Monday, 08/31/15 Here's a link for that book by Brad Cox that I mentioned, where he talks about "Software ICs": http://www.amazon.com/Object-oriented-Programming-Brad-Cox/dp/0201103931 His "OOPC" was predecessor of Objective-C Answers for UNIX slide 67 % who | cut -d" " -f1 | sort | uniq -c | sort -rn | head -1 | tr -s " " | cut -f3 -d\ % tr A-Z a-z < /usr/share/dict/words | fgrep e | fgrep i | grep a | grep o | grep u | wc -l % tr -dc a-z < lc.java | fold -1 | sort | uniq -c | sort -rn | head -5 Check point total in a2 write-up, assuming full text of a2 on clipboard: % cb | grep Problem | cut -d\( -f2 | grep point | cut -f1 -d" " | java sum Re "cb" see Clipboard meets Command Line in pzr (my Chrome "search engine" for the Piazza resources page). Friday, 09/11/15 The a3 write-up suggests line.split("\\s+") as a starting point but line.split("\\|") is a good alternative. Wednesday, 09/16/15 % echo "ls < x | a -x | b > d" | (javac clp.java && java clp) Friday, 09/18/15 Each tester run with diffs ends with "Files diffed:" Files diffed: a3/master/tester.out/clp.out.01 tester.out/clp.out.01 "Using the Tester" (tester.pdf) shows vimdiff a3/master/tester.out/clp.out.01 tester.out/clp.out.01 Here are some alternative views that diff provides: diff -y a3/master/tester.out/clp.out.01 tester.out/clp.out.01 diff -u a3/master/tester.out/clp.out.01 tester.out/clp.out.01 pr -m is handy, too: pr -m a3/master/tester.out/clp.out.01 tester.out/clp.out.01 Warning signs of a bad clp.java solution: 45+ lines with semicolons % grep ";" clp.java | wc -l More than one use each of "<" and ">". (And don't something like String LessThan = "<") a a | b a | b | c procCmd(String cmd, boolean first, boolean last) "a > x" if (!first && !last) { ...20 lines... } else if (!first && last) { ...20 lines... } iprint(3 + 4 * 5); // output: 3 + 4 * 5 = 23 System.out.println("3 + 4 * 5 = " + (3 + 4 * 5)); Friday, 10/16/15 Note: this file is fall15/lectures.notes Original Thought: "Whenever I have seen 'hackers' in movies, etc., I always thought it was ridiculous that they could do so much on the computer without ever touching a mouse. Now I understand that they are using a command line! Not so ridiculous anymore. Now I am the one typing hieroglyphics on the computer." --Ms. Woods Slide 246: Let's fix 'fill' by "capping off" the result in s with a zero: void fill(char s[], char c, int n) // luckystring3a.c { for (int i = 0; i < n; i++) s[i] = c; s[n] = 0; // Added } Q: Should we first check to be sure there's space for that zero? For a call to fill with c='a' and n=3, here are byte values starting at &s[0] BEFORE 's[n] = 0' is executed: 97 97 97 97 97 65 0 0 0 0 0 ... Is there room for the 0 at s[3]? Another: For a call to fill with c='A' and n=2, here are byte values starting at &s[0] BEFORE 's[n] = 0' is executed: 65 65 0 0 0 0 0 0 0 0 65 83 67 73 73 10 34 ... Is there room for the 0 at s[2]? One more: For a call to fill with c='$' and n=5, here are byte values starting at &s[0] BEFORE 's[n] = 0' is executed: 36 36 36 0 36 36 0 0 0 0 0 65 83 67 73 73 10 34 ... Is there room for the 0 at s[5]? void concat(char to[], char from[]) { int topos = 0, frompos = 0; while ((to[topos])) topos++; while ((to[topos++] = from[frompos++])) ; } j u s t 0 ? ? ? 0 1 2 3 4 5 6 7 void concat(char to[], char from[]) { strcpy(&to[strlen(to)], from); } Monday, 10/19/15 Two Original Thoughts: (1) "With this, for (int i = 0; i < strlen(s); i++) ... you've automatically got an n-squared (O(n^2)) loop." -- Mr. Forma (2) "Wildcard expressions are like nets you design to catch specific kinds of fish. Except the fish are files..." -- Mr. Grijalva Wednesday, 10/21/15 Discussion... 01234567 ab/cd.e/xy.z ab/cd.e xy.z z /x/y/z/a.c /x / x "" result[0] = '/'; result[1] = 0; XX result = "/"; strcpy(result, "/"); abcd0xy0z(&*#(!sdjflsk2082094 ^shiftleft abcd0xy0z(*#(!sdjflsk20082094 char s[] = "abcd"; shiftleft(s); puts(s); // output: "bcd" shiftright(s); puts(s); // output: "bbcd" void mkstr(char a, char b, char r[]); char res[5]; mkstr('x', 'y', res); puts(res); // output: xy void mkstr(char a, char b, char r[]) { r[0] = a; r[1] = b; r[2] = 0; r[0] = a && r[1] = b && r[2] = 0; (r[0] = a, r[1] = b, r[2] = 0); } void mkstr(char a, char b, char r[]) { char s[] = {b, a, b, a, b, 0}; strcpy(r, s); } int count_ints(int val, int a[]); int count_chars(char c, char s[]); void path_elem(char path[], char which, char result[]); char s[1]; path_elem("x", 'e', s); f("xyz"); void f(char path[]) { char dir[strlen(path)]; char s2[10] = "abc"; path_elem(path, 'n', dir); g(dir); Monday, 10/26/15 What's the following statement doing? result[strlen(result)] = 0; Put a zero wherever the first zero is. Tuesday, 10/27/15 Note: This file is cs.arizona.edu/classes/cs352/fall15/lectures.notes Q: If I increment a pointer using ++, what could cause a segmentation fault? A: Nothing! You'll never get a fault from simply incrementing or decrementing a pointer. A fault with a pointer can only arise from using the pointer to reference memory. *p++ might fault but p++ should never fault. Discussion, Wednesday, 10/28/15 void print_ints(int *first, int n); void from_to(int from, int to, int by, int *result); void reverse(int *first, int *last); void merge(int *a, int *b, int nelems, int *result); void split(int *vals, int nvals, int *a, int *b); void split_s(char *s, char *r1, char *r2); void blend(int *vals, char *s); void average(int *first, int *last, double *avg); char *merge_s(char *s1, char *s2, char *result); char *trim(char *s, char c) // trim("a bc ", ' ') --> "a bc" trim(trim("a bc ", ' '), 'c') trim(char *s, char *cs) // trim("a,b,.. ", ",. ") -> "a,b" int countvals(int *vals, int nelems, int low, int high) A proof that 2["testing"] is equivalent to "testing"[2]: x[y] is equivalent to *(x + y). By commutativity, *(x + y) is equivalent to *(y + x) *(y + x) is equivalent to x[y] Therefore, x[y] is equivalent to y[x] Friday, 10/30/15 alias tw="a8/tester warmup" alias twl="a8/tester warmup | less" "A-Z" ^ |before (*before)++ int *cset = ...the cset... cset['A'] = 1 int *first = cset + *before int *last = cset + *end Wednesday, 11/04/15 args1.c: int main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) printf("|%s|\n", argv[i]); } args2.c: int main(int argc, char *argv[]) // char **argv is equivalent { for (char **ap = argv+1; *ap; ap++) printf("|%s|\n", *ap); } Monday, 11/09/15 int *buf = malloc(n*sizeof(*buf)); ^^Don't do this^^ Instead, do this: char *int = malloc(n*sizeof(int)); Friday, 11/20/15 Bug in my free_block: If a block is underrun or overrun, I free it. You should do the same. mcycle: color=red,green,blue\n0 name^ ^ ^ ^ Wednesday, 11/25/15 struct pool_info pool_root = {}; Wednesday, 12/02/15 Slide 550 int first_bit_set(int w) { int intbits = sizeof(int) * CHAR_BIT; unsigned int checker = 1 << (intbits - 1); for (int pos = intbits; pos; pos--) if (w & checker) return pos; else checker >>= 1; return 0; } | | | | | int x = 0x0600 0025; 000001100000000000100101 int checker = 1 << 31 00000100000000000000000000000 ------- Discussion section ------- struct X { int value; } structure tag named X struct X x1; struct X *xp; typedef struct X { int value; struct X *next; } X; typedef int integer; typedef unsigned long int uli; typedef struct Vector { ... } *Vector_T; Vector_T x; sizeof(*x) struct Vector *x; x = Vector_new(sizeof(Vector_T)); Vector_put(x, x); X x1; x1.value = 10; X *xp = &x1; xp->value = 20; (*xp).value = 30; xp = xp->next; xp++; Friday, 12/04/15 (1) Think of Vector_new as a constructor! Vector_T Vector_new(int cell_size) { Vector_T this = malloc(sizeof(struct Vector)); this->cell_size = cell_size; ... } (2) When memory regions overlap, use memmove, not memcpy Monday, 12/07/15 (1) What wrong with this? Vector_T v = malloc(sizeof(Vector_T)); (2) % cat vector.c ... #ifdef MINE int main() { ...simple tests... } #endif % gcc -DMINE vector.c # "sees" your main % make vector # won't "see" main because MINE isn't defined Wednesday, 12/09/15 Ben Goldfarb Ass-u-me char *p; strcpy(p, "xyz");