a = ( (b * c) == 2 ) a = ( ( b && ( a > z ) ) ? ( x = y ) : z ) a = ( ( s . f ) + ( x . y ) ) a = ( b >> ( 2 + 4 ) ) c = ( getchar() == EOF )
baa meep sproing
meep sproing
/* Count the number of a's */ /* in a line given as input */ #include <stdio.h> #include <ctype.h> void main(void) { int num_a = 0; int c; while((c = getchar()) != '\n') { while(isdigit(c)) ; if (c == 'a') num_a++; } printf("%d\n", num_a); exit(0); }
Incidentally, there is a bug in this program if c is a digit; the program enters an infinite loop. Note that in my solution I have preserved the bug (the question didn't say to debug the program ...)
The first printf increments cpp and dereferences it twice; so, after the ++, the variable cpp is cp+1, and *cpp is c + 2 or &c[2], giving **cpp as c[2], or "POINT". The picture now looks like:
The second printf 's second argument is (*(--(*(++cpp))))+3; so, cpp now becomes cp+2, *++cpp is c+1 or &c[1], --(*(++cpp)) stores (c+1)-1 or c in cp[2], and (*(--(*(++cpp)))) is c. Hence, (*(--(*(++cpp))))+3 is &c[0]+3, or "ER". Again, the picture has changed slightly:
In the third printf, *cpp[-2]+3 is (*(cpp[-2]))+3, or (*(*(cpp-2)))+3; the value stored in the variable cpp is cp+2, so *(cpp-2) is *(cp+2-2) or *cp, or c+3 or &c[3], or "FIRST"; hence (*(*(cpp-2)))+3 is &c[3]+3 or "ST".
In the fourth printf, cpp[-1][-1] is (*(*cpp-1)-1), or (*(cp+2-1)-1), or (*(cp+1)-1), or (c+2-1), or c+1, or &c[1]; so, cpp[-1][-1]+1 is &c[1]+1, or "EW".
Putting this into the formats, the code fragment prints:
POINTER STEWfollowed by a newline.
variable | value if min is macro | value if min is function |
---|---|---|
a | 4 | 3 |
b | 3 | 3 |
c | 5 | 5 |
d | 4 | 3 |
e | 3 | 3 |
For min a macro, the fourth line becomes:
d = ((++a) > b) ? (b) : (++a)Now, as a is 2 and b is 3, the conditional is false (as 3 == 3), so ++a is evaluated, setting a to 4 and returning 4 as the expression value. For the fifth line, we have
e = ((c++) > b) ? (b) : (c++)giving a true conditional (as 4 > 3; note c is incremented after its value is used), whence the value of b, or 3, is assigned to e.
variable | final value |
---|---|
a | 2 |
arr[0] | 3 |
arr[1] | 5 |
arr[2] | 5 |
b | &arr[0] |
c | &arr[1] |
d | 2 |
e | 3 |
f | 4 |
All parameters are passed by value, not reference.
As testandinc treats its parameter as an integer, and not an integer pointer, a's value cannot change. As testandinc returns the value of its parameter (because the ++ follows the x, x is incremented after its value is used), it also returns the value of its parameter. The ++ is effectively a do-nothing operator.
The second function, p1testandinc, takes a pointer as its parameter:
The third function is a bit different. The return value is evaluated differently; the pointer is dereferenced first, then the value x points to is incremented. (Note the parentheses change the meaning from the second function's return value.) So, not, the value of the argument on return is unchanged; but the value stored in arr[1], to which the argument points, is incremented from 4 to 5.
sed 's/:.*//' /etc/passwd | sort | uniq -u > usernames
ls *rc .*rcNote that ls -a *rc does not work, because the shell, not ls, expands *rc; and the result of that expansion does not include any files with names beginning with a period. The ls command lists information about them, and no others.