ポインタ
スポンサーリンク
次のプログラムは,ポインタを扱ったプログラムの例です。
#include <stdio.h>
int main(void)
{
int num = 123;
int *ptr; /* ポインタ変数 */
printf("%d\n", num); /* 出力: 123 */
printf("%d\n", &num); /* 出力: 460832 (例) */
ptr = # /* num のアドレスを ptr に代入 */
ptinrf("%d\n", ptr); /* 出力: 460832 (例) */
printf("%d\n", *ptr); /* 出力: 123 */
return 0;
}
ポインタとは
ポインタ (pointer) とは,ある変数のメモリアドレスを保持する変数のことです。
今回の例では,ポインタ変数 ptr に,変数 num のメモリアドレスが代入されています。
int 型変数用のポインタは int * ,char 型変数用のポインタは char * というように,ポインタ型は 型 * という型名を持ちます。
アドレス演算子/間接参照演算子
ポインタ関連の演算子として,次のようなものがあります。
演算子 | 説明 |
---|---|
& (アドレス演算子) | 変数のデータが置かれた場所のアドレスを取得 |
* (間接参照演算子) | アドレスの場所に格納されているデータを取得 |
先のプログラムにおける num, &num, ptr, *ptr は,次のように説明できます。
式 | 説明 |
---|---|
num | 変数 num のデータ |
&num | 変数 num のデータが置かれた場所のメモリアドレス |
ptr | 変数 num のデータが置かれた場所のメモリアドレス |
*ptr | ptr の指す場所に格納されたデータ (= 変数 num のデータ) |
ポインタの宣言
ポインタの宣言は,次のように書きます。初期化子は省略できます。
int *ptr = #
次のような宣言を書くときは注意が必要です。
int *a, b; /* a は int * 型,b は int 型 */
int *a, *b; /* a と b は int * 型 */
NULL
ポインタがどの変数も指していない状態は,NULL という定数で表されます。
NULL の値は 0 と定義されています。
ptr = NULL; /* ptr はどの変数も指していない */
引数のポインタ渡し
C の関数呼び出しは,基本的に値渡しです。
関数の呼び出し元の変数を操作するには,関数の引数に変数へのポインタを受け取り,間接的にアクセスします。
/* a と b の値を交換する */
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int m = 1, n = 2;
swap(&m, &n); /* アドレスを渡す */
return 0;
}
scanf 関数で & を付ける必要があったのは,この理由からです。
関数ポインタ
関数への参照を保持する,関数ポインタを宣言することもできます。
int add(int a, int b)
{
return a + b;
}
int main(void)
{
int m = 2, n = 5, sum;
int (*fp)(int, int); /* 関数ポインタ */
fp = add; /* fp は add 関数を参照する */
sum = (*fp)(m, n); /* 間接的に add 関数を呼び出し */
return 0;
}
スポンサーリンク