int 型や float 型の引数を普通に渡すのが値渡し。このとき引数の値はコピーされて関数に渡されるので、関数の中で変更しても元の(つまり関数の外の)変数の値は変化しない。
これに対して、ポインタで渡すのが参照渡し。引数のポインタの持っているアドレスがコピーされて関数に渡されるけど、このアドレスは関数の呼び出し元のポインタと同じデータを指している。結果として、関数内で引数(ポインタ)の指すデータを変更すると、呼びさし側でもデータが変化することになる。
参照渡しの場合は、関数の仮引数をポインタとして定義する。次のプログラム中の関数 swap は2つの引数(ポインタ)をとって、相互に値を交換する。
#include
void swap(int *i, int *j);
int main(void)
{
int num1, num2;
num1 = 100;
num2 = 800;
printf("num1= %d, num2= %d\n", num1, num2);
swap(&num1, &num2);
printf("num1= %d, num2= %d\n", num1, num2);
return 0;
}
void swap(int *i, int *j)
{
int temp;
temp = *i;
*i = *j;
*j = temp;
}
「void swap(int *i, int *j)」というのが、ポインタ引数の書き方だ。ここでは2つ使っている。
実行結果:
takatoh@nightschool $ ./sample_7_3 num1= 100, num2= 800 num1= 800, num2= 100
ちゃんと num1 と num2 の値が入れ替わった。
ところで、引数に配列(文字列を含む)を渡す場合、配列のアドレスが渡されるだけで配列そのものがコピーされるわけじゃない。これは参照渡しだ。だから、関数の仮引数はポインタ型として定義する必要がある。
#include
void f(int *num);
int main(void)
{
int count[5] = {1, 2, 3, 4, 5};
f(count);
return 0;
}
void f(int *num)
{
int i;
for (i = 0; i < 5; i++) {
printf("%d\n", num[i]);
}
}
takatoh@nightschool $ ./sample_7_3a 1 2 3 4 5