Notes on CP Tutorial Sheet for week 7 ------------------------------------- "Arrays" Rev is the standard array reversal function. So the first call Rev(a,b,4) makes b = { 3, 2, 1, 0 } Then the second call reverses b[0..2] into a[0..2], making a = { 1, 2, 3, 3} "Another function" The point here is that they need to use a pointer to return two answers. Nowadays it would be cleaner to return a struct, but we haven't taught them that yet, and there's still a huge amount of code out there that uses pointer returns, so it's still worthwhile. If they get beyond the general point to actually implementing it, then the specification is also completely vague about what exactly the type of this function is supposed to be - remind them that in lecture 10 I remarked on how tying down the specification is something that should be done before implementing! The obvious choice is to do it for doubles (because there's no good reason to use floats except in some particular circumstances). It seems somehow natural to have the function return the mean as its value, and pass back the s.d. by a pointer, but there's nothing about that in the spec. double square(double a) { return a*a; } double stats(double *sdpointer, double a1, double a2, double a3) { double mu,sd; mu = (a1 + a2 + a3)/3; sd = (square(a1-mu) + square(a2-mu) + square(a3-mu))/3; *sdpointer = sd; return mu; } The use of the separate sd variable, rather than storing the computation directly into sdpointer, is a stylistic principle of having the function do its side-effects in one place right at the end, so that in debugging (for example), we can deal with that separately from the actual computation. "Programming" The programming exercise is extending the program we developed in the lectures. The challenge is dealing with non-denary representations of fractional numbers. The point is that printing the fractional part is easier, as we can just go one digit at a time, and don't need to pre-calculate the largest column we need. Solution is in fbase.c