C 言語でのポインタアンパサンド表記の使用
この記事では、C 言語でのポインタアンパサンド記法の使い方について複数の方法を紹介します。
与えられた変数のアドレスを取得するために &var
記法を使用する
ポインタは単にメモリアドレスを保持する変数です。ポインタは type *var
記法で宣言されています。ポインタには同じ型の任意のアドレスを割り当てることができ、どのようなポインタ型でも void*
ポインタを格納することができ、これを汎用ポインタと呼ぶ。オブジェクトのアドレスを格納する型があるのだから、それへのアクセスを提供する演算子があるはずです。
アンパサンド記号 &
は単項演算子として用いられ、しばしばアドレス演算子と呼ばれる。これは、オブジェクトが格納されているアドレスを取得するためにデータオブジェクトや関数で利用できます。
以下の例に示すように、整数 x
が宣言されて初期化されているとしよう。この場合、アンパサンド演算子 &
でそのアドレスを取得し、変数 int *xptr
に代入することができます。その結果、xptr
は 10233 の値を指しており、以後のコードでは演算子 *
を使ってその値にアクセスすることができます。
アスタリスク *
はここでは二つの異なるコンテキストで使われていることに注意してください。一つはポインタ型の変数を宣言するためのものです。もう一つは変数へのポインタから変数の値にアクセスするためのもので、後者は間接参照と呼ばれています。
#include <stdio.h>
#include <stdlib.h>
int main() {
int x = 10233;
int *xptr = &x; // xptr now points to x
printf("x: %d\n", x);
printf("*xptr: %d\n", *xptr);
exit(EXIT_SUCCESS);
}
出力:
x: 10233
*xptr: 10233
ポインタから変数の値にアクセスするには *ptr
記法を用いる
間接参照演算子は、ポインタから値を取得して同じ型の変数に代入するために利用できます。なお、*
演算子は null
ポインタや無効なポインタには使えないことに注意してください。ほとんどのシナリオでは、null
ポインタを試すとプログラムがクラッシュする可能性が高い。しかし、無効なポインタがアクセスされた場合、それは気づかれないかもしれません。無効なポインタはメモリ内の任意のオブジェクトを指している可能性があり、そのポインタに対する操作は続行されるが、プログラムの状態の正しさを損なう可能性があります。
#include <stdio.h>
#include <stdlib.h>
int main() {
int x = 10233;
int *xptr = &x; // xptr now points to x
int y = *xptr; // y now holds the value 10233
printf("x: %d\n", x);
printf("y: %d\n", y);
exit(EXIT_SUCCESS);
}
出力:
x: 10233
y: 10233
アンパサンド記法 &
を使ってオブジェクトのアドレスを関数に渡す
address-of 演算子を利用する最も一般的な例は、関数の引数としてオブジェクトへのポインタを渡すことです。次の例は、2つの整数ポインタを引数にとる関数 swap
を示しています。関数 main
から swap
が呼び出されたとき、アンパサンド演算子を使って x
と y
の変数のアドレスを渡していることに注意してください。ただし、swap
関数の本体にある *
演算子はポインタの逆参照を示します。
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
}
int main() {
int x = 10233;
int y = 10133;
printf("x:%d, y:%d\n", x, y);
swap(&x, &y);
printf("x:%d, y:%d\n", x, y);
exit(EXIT_SUCCESS);
}
出力:
x:10233, y:10133
x:10133, y:10233