ANSWERS TO EXERCISES ON C FUNCTIONS 1. Extra semicolon on the first line. Only function prototypes have semicolons after the parenthesis, not function definitions. 2. It returns 16 and prints. 4 16 The function stops as soon as the first return statement is reached. 3. It takes 3 integer arguments and returns 1 (true) if all three are equal, and 0 otherwise. Veteran C program might write this more succinctly as the following since the result of the && operation is always 0 or 1. int eq3(int a, int b, int c) { return (a == b) && (a == c); } 4. int max(int a, int b) { if (a >= b) return a; else return b; } The keyword "else" is not essential since once a return statement is reached, no further statements are executed. int max(int a, int b) { if (a >= b) return a; return b; } 5. int max3(int a, int b, int c) { if (a >= b && a >= c) return a; else if (b >= c) return b; else return c; } 6. double absolute_value(double x) { if (x > 0) return x; else return -x; } Alternatively, use the fabs() function from the math library. Be sure to #include <math.h>. 7. int f(int n) { int i = 1; while (i < n) i += i; return i; } 8. We take a brute force approach, and check integers less than N to see if they divide evenly into N. int isPrime(int N) { int divisor; if (N <= 1) return 0; for (divisor = 2; divisor < N; divisor++) if (N % divisor == 0) /* N is a multiple of divisor */ return 0; return 1; } 9. One solution is to copy the above code and exchange 0 and 1 in the three return statements. A better solution is to call the above function. Recall ! means logical NOT in C. int isNotPrime(int N) { return !isPrime(N); } 10. To remove the least significant digit, we divide by 10 and throw away the remainder. int leadingdigit(int x) { while (x >= 10) x = x / 10; return x; } 11. Prints out "9 11". 12. Different compilers have different ways of trying to tell you about the problems. % cc bad.c "bad.c", line 3: syntax error before or at: { "bad.c", line 3: undefined or not a type: x "bad.c", line 3: warning: old-style declaration or incorrect type for: x "bad.c", line 3: identifier redeclared: x current : pointer to int previous: function() returning int : "bad.c", line 3 "bad.c", line 3: syntax error before or at: } "bad.c", line 8: syntax error before or at: b "bad.c", line 11: syntax error before or at: else cc: acomp failed for bad.c % lcc bad.c bad.c:3: unrecognized declaration bad.c:3: unrecognized declaration bad.c:3: syntax error; found `*' expecting `;' bad.c:3: redeclaration of `x' previously declared at bad.c:3 bad.c:3: unrecognized declaration bad.c:8: syntax error; found `b' expecting `;' bad.c:11: syntax error; found `else' expecting `;' % gcc126 bad.c bad.c:3: parse error before `{' bad.c: In function `main': bad.c:8: parse error before `b' bad.c:11: parse error before `else' % gcc126 bad.c bad.c:3: parse error before `{' bad.c: In function `main': bad.c:8: parse error before `b' bad.c:11: parse error before `else' bad.c:6: warning: `a' might be used uninitialized in this function bad.c:6: warning: `b' might be used uninitialized in this function Compilers do the best they can to try to understand what we give them to be legal C programs. When we make errors, their interpretation may diverge from our intention, to the point that the error messages may not make sense to us. Lesson: fix the *first* error, then try again.