f(char *x), f(int *x)
関数にアドレスを渡すことができます。すなわち,アドレスを受け取る関数を作成することができます。
/* Example 10.14 */ #include <stdio.h> void f(int *); int main(void) { int x = 2, y = 3; f(&x); f(&y); printf("x = %d\n", x); printf("y = %d\n", y); return 0; } void f(int *p) // int *型変数(intへのポインタ) { *p = 10; // * は間接演算子 }
これは Example 10.10
において,各変数を 10
に変更する部分を関数 f
にまとめたものです。実行すると,
x = 10 y = 10
という出力結果を得ます。関数 f
に渡すのはアドレス &x
や &y
,そして受け取る側の仮引数はポインタ p
ということで,「アドレス → ポインタ」という連繋になっています。
アドレスを渡すと関数 f
内でも x
や y
の値を変更することができます。アドレスを渡さない場合は変更できません。次の例でそれが確認できます。
/* Example 10.15 */ #include <stdio.h> void f(int); int main(void) { int x = 2; f(x); printf("(3) x = %d\n", x); return 0; } void f(int s) { printf("(1) s = %d\n", s); s = 10; printf("(2) s = %d\n", s); }
実行結果です。
(1) s = 2 (2) s = 10 (3) x = 2
関数 f
に x
を渡したので,最初 s
は 2
です。その後 10
に変わっています。しかし,x
の値は 2
のままです。x
の値を変更するには,それが記憶されているメモリ領域にアクセスできなければならない訳です。
/* Example 10.16 */ #include <stdio.h> void f(char *); int main(void) { char str[] = "ABCDEFG"; f(str); return 0; } void f(char *str) { char *p; for(p = str; *p != '\0'; p++) printf("[%p] '%c' %s\n", p, *p, p); }
Example 10.8
のプリント部分を少し変更したものを関数 f
にしたものです。また,変換指定子 %s
はこれまでも使用してきましたが,その意味は指定されたアドレスのメモリ箇所に記憶されている値からナル文字の直前までを出力するというものです。実行結果です。
[0xbffffa98] 'A' ABCDEFG [0xbffffa99] 'B' BCDEFG [0xbffffa9a] 'C' CDEFG [0xbffffa9b] 'D' DEFG [0xbffffa9c] 'E' EFG [0xbffffa9d] 'F' FG [0xbffffa9e] 'G' G
値を変更したりプリントしたりと,様々な作業や役割を関数に持たせることが可能になります。