|
Consider the following example:
#include <stdio.h> // DEMO this program
void f(int x)
{
x = x + 1;
}
int main(int argc, char *argv[])
{
int a = 4;
printf("Before calling f(a), a = %d\n", a);
f(a);
printf("After calling f(a), a = %d\n", a);
}
|
C will pass the value of the variable a to function f( )
We can pass the address of the variable a using &a :
#include <stdio.h> void f(int x) { x = x + 1; } int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); // Pass the value of the address of var a printf("After calling f(a), a = %d\n", a); } |
However: the data type of the parameter int x is now incorrect.
The correct type is int *x because x contains the address of an int typed variable:
#include <stdio.h> void f(int *x) { x = x + 1; // Meaning: increment the value in the variable x (wrong) } int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); printf("After calling f(a), a = %d\n", a); } |
Unfortunately: the statement x = x + 1 does not increment the correct variable...
x = x + 1 says: increment the (value) in the variable x
What we really want is: increment the (value) in the variable pointed to by x
The correct statement is *x = *x + 1 because *x is an alias of the int typed variable a:
#include <stdio.h> // DEMO this program void f(int *x) { *x = *x + 1; // Meaning: increment the value in the variable } // pointed to by x (≡ a !!) int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); printf("After calling f(a), a = %d\n", a); } |
And this is how C achieves the effect of the pass-by-reference mechanism by "Do It Yourself (DIY)" !!!
The effect of the following program:
#include <stdio.h> void f(int *x) // x will contain &a !! { *x = *x + 1; } int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); printf("After calling f(a), a = %d\n", a); } |
is equivalent to:
int a = 4; int *x; x = &a; *x = *x + 1; |
When we pass the (address) &a as parameter:
#include <stdio.h> void f(int *x) // x will contain &a !! { *x = *x + 1; } int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); printf("After calling f(a), a = %d\n", a); } |
the effect is equivalent to:
int a = 4; int *x; x = &a; *x = *x + 1; |
Therefore, the statement *x = *x + 1:
#include <stdio.h> void f(int *x) // x will contain &a !! { *x = *x + 1; } int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); printf("After calling f(a), a = %d\n", a); } |
will increment the variable a because *x ≡ a:
int a = 4; int *x; x = &a; *x = *x + 1; // Increments a |
|
Situation where you need to use function declaration:
#include <stdio.h> int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); // Call function before it's defined printf("After calling f(a), a = %d\n", a); } void f(int *x) { *x = *x + 1; } |
How to declare a function with a reference data type as parameter:
#include <stdio.h> void f(int *x); // Declare function with reference data type parameter int main(int argc, char *argv[]) { int a = 4; printf("Before calling f(a), a = %d\n", a); f(&a); // No error now printf("After calling f(a), a = %d\n", a); } void f(int *x) { *x = *x + 1; } |