前回は、「変数(オブジェクト)のアドレスを表示するプログラム」をご紹介した。
このプログラムは、ただアドレスを表示するだけなので何かの役に立つわけではないが、変数=オブジェクトの概念はご理解いただけたのではないだろうか。
今回は、いよいよメインテーマであるポインタを扱う。これで、アドレスを有効活用できるようになる。
なお、本プログラムは、Windows 11 Home(23H2)上で、 Visual Studio Code(1.89.1)を使用して作成し、gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0でコンパイルしている。
ポインタ(アドレス演算子&と間接演算子*)
//ポインタ(アドレス演算子&と間接演算子*)
#include <stdio.h>
int main(void)
{
int n = 19;
printf("n = %d\n",n);
printf("&n = %p\n",&n);
int *p = &n;
printf("p = %p\n",p);
printf("*p = %d\n",*p);
return 0;
}
実行結果
n = 19
&n = 0x7ffcbbf313dc
p = 0x7ffcbbf313dc
*p = 19
「int *p = &n;」では、型名と変数名の間に*が置かれている。
これで「intへのポインタ型」あるいは、「int *型」と一般的に呼ばれる型になる。
初期化子が&nなので、pは変数nのアドレスで初期化される。このときのpとnの関係は、次の通り表現する。
ポインタpの値がnのアドレスであるとき。「pはnを指す」という。
・矢印の始点・・ポインタ
・矢印の終点・・そのポインタによってさされているオブジェクト
式&nは、nを指すポインタであり、その評価で得られるのがnのアドレスである。
Type型のオブジェクトnに対してアドレス演算子&を適用したアドレス式&nは、Type*型のポインタであり、その値はnのアドレスである。
ポインタの値は、指しているオブジェクトのアドレスなので、
printf(“p = %p\n”,p); で表示されるpの値は、pが指しているnのアドレスとなる。
次に、printf(“p = %d\n”,*p); では、間接演算子が使われている。
単項*演算子 *a aが指すオブジェクトそのもの
このように、「式*pが、nそのものを表す」ことを「*pはnのエイリアス(別名)である。」と表現する。
Type*型のポインタpがType型のオブジェクトnを指すとき、間接演算子*を適用した間接式*pは、nのエイリアス(別名)となる。
なお、ポインタに間接演算子を適用することで、ポインタが指すオブジェクトを間接的にアクセスすることは、参照外しと呼ばれる。
(参考)新・明解C言語 入門編 第2版 柴田 望洋 (著)SBクリエイティブ
コメント