The parameters are local variables that are assigned an initial value before the execution of the function body. Their scope of validity, therefore is the function body itself. The way parameters are passed to a function is essential to understand the behavior of C programs.
Consider the following program:
1 2 3 4 5 6 7 8 9 10 11 12 | int addition(int a, int b) { return (a + b); } int main() { int x = 10; int y = 20; int z; z = addition(x, y); } |
The parameters a
and b
declared in
line 1 are valid only in the expression in line 3. Variables x
,
y
and z
, on the other hand, are valid in the body
of function main
(lines 7 to 11).
The scope of variables x
, y
and
z
(invoking scope), and that of variables a
and
b
(invoked scope) are totally different. The invoking scope
disappears temporarily when the function is invoked in line 11. During this
execution, the invoked scope is visible. Upon function termination, the
invoked scope disappears and the invoking scope is recovered.
The communication between these two scopes is done in line 11. Before the start of the function execution the values of the variables in the invoking scope are copied over the variables in the invoked scope. When the function terminates execution, the expression in line 11 is replaced by the returned value. The following figure illustrates this procedure for the previous example.
Passing the parameters and returning the result in C functions is done by value, that is, copying the values between the two scopes.
The function local variables (including the parameters) disappear when the function terminates, therefore, any value that needs to be save, needs to be returned as result (see Exercise 1).
Copying parameters from the invoking to the invoked scope has an exception. When a function receives as parameter an array, instead of performing a duplicate of the table, only its memory address is copied. As a consequence, if a function modifies a table received as parameter, those changes are visible in the invoking scope. The following example illustrates this situation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #define NUMBER 100
void fill(int table[NUMBER], int size)
{
int i;
for (i = 0; i < size; i++)
{
table[i] = 0;
}
}
int main()
{
int i, data[NUMBER];
for (i = 0; i < size; i++)
{
data[i] = 10;
}
fill(data, NUMBER);
/* Data is all set to zero */
} |
To explain this behavior the C pointers need to be studied first.