今回は、配列内の要素を指すポインタp + iに間接演算子*を適用すると、どうなるかをご紹介しよう。
ポインタpが配列中の要素eを指すとき、
要素eのi個だけ後方の要素を指す*(p + i)は、p[ i ]と表記でき、
要素eのi個だけ前方の要素を指す*(p – i)は、p[ -i ]と表記できる。
例えば、2番目の要素a[ 1 ]に着目しよう。
・ p + 1 は、a[ 1 ]を指すため、*(p + 1)は、a[ 1 ]のエイリアスである。
・*(p + 1)は、p[ 1 ]と表記できるため、p[ 1 ]もa[ 1 ]のエイリアスである。
・配列名aは、先頭要素a[ 0 ]を指すポインタである。
したがって、そのポインタに1を加えた、a + 1 は、2番目の要素a[ 1 ]を指すポインタである。
・ポインタa + 1が要素a[ 1 ]を指しているので、そのポインタに間接演算子を適用した*(a + 1)は、
a[ 1 ]のエイリアスである。
次の4個の式は、いずれも各要素をアクセスする式である。
① a[ i ] *(a + i) p[ i ] *(p + i)
次の4個の式は、いずれも各要素を指すポインタである。
② &a[ i ] a + i &p[ i ] p + i
このことをプログラムを作って確認してみよう。
「配列の要素の値とアドレスを表示するプログラム」である。
なお、本プログラムは、Windows 11 Home(23H2)上で、Visual Studio Code(1.90.0)を使用して作成し、gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0でコンパイルしている。
配列の要素の値とアドレスを表示するプログラム
//配列の要素の値とアドレスを表示するプログラム
#include <stdio.h>
int main(void)
{
int a[5] = {1,2,3,4,5};
int *p = a;
for (int i = 0; i < 5; i++)
printf("a[%d] = %d *(a + %d) = %d p[%d] = %d *(p + %d) = %d\n",
i,a[i],i,*(a + i),i,p[i],i,*(p + i));
for (int i = 0; i < 5; i++)
printf("&a[%d] = %p a + %d = %p &p[%d] = %p p + %d = %p\n",
i,&a[i],i,(a + i),i,&p[i],i,(p + i));
return 0;
}
実行結果
a[0] = 1 *(a + 0) = 1 p[0] = 1 *(p + 0) = 1
a[1] = 2 *(a + 1) = 2 p[1] = 2 *(p + 1) = 2
a[2] = 3 *(a + 2) = 3 p[2] = 3 *(p + 2) = 3
a[3] = 4 *(a + 3) = 4 p[3] = 4 *(p + 3) = 4
a[4] = 5 *(a + 4) = 5 p[4] = 5 *(p + 4) = 5
&a[0] = 0x7ffe73c45be0 a + 0 = 0x7ffe73c45be0 &p[0] = 0x7ffe73c45be0 p + 0 = 0x7ffe73c45be0
&a[1] = 0x7ffe73c45be4 a + 1 = 0x7ffe73c45be4 &p[1] = 0x7ffe73c45be4 p + 1 = 0x7ffe73c45be4
&a[2] = 0x7ffe73c45be8 a + 2 = 0x7ffe73c45be8 &p[2] = 0x7ffe73c45be8 p + 2 = 0x7ffe73c45be8
&a[3] = 0x7ffe73c45bec a + 3 = 0x7ffe73c45bec &p[3] = 0x7ffe73c45bec p + 3 = 0x7ffe73c45bec
このプログラムは、int[ 5 ]型配列aの全要素の値と要素へのポインタを表示する。
①の4個の式と、②の4個の式は、それぞれ同じ値として表示される。
(参考) 新・明解C言語 入門編 第2版 柴田 望洋 (著)SBクリエイティブ
コメント