Shao Miller said:
On 2/5/2013 04:09, Esash wrote:
The two are _separate_. The called function can modify its parameters
and those modifications _do_not_ modify the caller's arguments.
... As another example:
void bar(void) {
int i = 21;
int j = 21;
int x = add(i, j);
}
Your 'add' function above cannot modify the arguments 'i' and 'j'. It
can only modify its parameters 'a' and 'b'.
It gets a bit more confusing when arrays are involved:
void iadd(int a[],int b) {
a[0]+=b;
}
I think you meant "It gets a bit more confusing when parameter
declarations appear to declare arrays". For a beginner, one of the
hurdles in C is that array declarators for function parameters actually
declare pointers. For this reason, I recommend avoiding array
declarators in function parameters altogether, unless one requires the
= C99 conveniences (like 'static'), in which case one is probably not
a beginner to C.
int main (void) {
int x[]={10,20,30};
iadd (x,1);
}
Here, the caller's 'x' argument *is* apparently modified. In fact, an
array can *only* be passed by reference.
Well that might add to the confusion. In 'main', the 'x' array object
isn't an argument, and 'iadd' doesn't modify its arguments (nor does any
C function access its caller's arguments). One thing that can be said
is that the 'x' lvalue is not the same as the value of the expression
'x'. Lvalue conversion and "array decay" are side-by-side concepts that
can be challenging for a beginner to grasp, but the sooner done, the better.
I like to imagine an "evaluation pass". Given (in a function):
int x[] = { 10, 20, 30 };
int y = 13;
int z = 42;
foo(x, y, z, bar());
I imagine an "evaluation pass" resulting in:
foo(pointer to first element of x, 13, 42, result of call to bar);
These more accurately describe the arguments to 'foo'. We can see that
all of the originals are, after some evaluation has happened, _not_
arguments to 'foo'. In normal discussion, we might say that they are,
but this can contribute to beginners' confusion.
There is another confusing case that's similar to "array decay", and
that's "function decay", which explains the difference between these two
lines:
int sz = sizeof main;
int sz = sizeof (0, main);
In the latter, 'main' "decays" to a function pointer, just as array
expressions decay to object pointers. And, just like array expressions,
this same decay happens when 'main' appears to be an argument in a
function call. There is again a similar relationship to arrays for
function parameters: A function parameter declarator that itself appears
to declare a function actually declares a function pointer parameter.
I seem to recall another comp.lang.c post referencing "Haddocks' Eyes":
http://en.wikipedia.org/wiki/Haddocks'_Eyes#Naming
The argument is called 'x', but the argument is a pointer to the first
element of 'x'.