ポインタと配列
C 言語で、配列はメモリ上で連続して配置されます。以下のプログラムを実行して、配列の要素のアドレスを表示してみましょう。
#include <stdio.h>
int main(){
int arr[] = {10, 11, 12};
printf("%d, %d, %d\n", arr[0], arr[1], arr[2]);
printf("%p, %p, %p\n", &arr[0], &arr[1], &arr[2]);
printf("%p\n", arr);
printf("%p\n", &arr);
}
実行結果は以下のようになります。配列型の変数は、 &arr[0]
(先頭の要素のアドレス) と arr
(arr
に格納されているアドレス) と &arr
(arr
のアドレス) が同じ値であることがわかります。(配列の各要素のアドレスは、4byteずつ連続しています。これは、メモリのアドレスが 1 byte ずつに割り当てられており、 int 型の変数の大きさは 4 byte であるためです。)
10, 11, 12
0x7ffff6cf7b48, 0x7ffff6cf7b4c, 0x7ffff6cf7b50
0x7ffff6cf7b48
0x7ffff6cf7b48
以下にイメージ図を示します。
このイメージ図では、以下のように表示されます。(わかりやすく 10 進数で表示しています。 int 型の変数の大きさは 4 byte ですが、わかりやすくするために、アドレスは 1 byte ずつに割り当てています。)
10, 11, 12
102, 103, 104
102
102
アドレスに数値を足す
ポインタを使って、配列の要素にアクセスすることができます。以下のプログラムを実行して、ポインタを使って配列の要素にアクセスする方法を確認してみましょう。
#include <stdio.h>
int main(){
int arr[] = {10, 11, 12};
int *p = arr;
printf("%d, %d, %d\n", arr[0], arr[1], arr[2]);
printf("%p, %p, %p\n", &arr[0], &arr[1], &arr[2]);
printf("%p\n", arr);
printf("%p\n", &arr);
printf("%d, %d, %d\n", *p, *(p + 1), *(p + 2));
printf("%p, %p, %p\n", p, p + 1, p + 2);
printf("%d, %d, %d\n", p[0], p[1], p[2]);
}
実行結果は以下のようになります。p
は arr
の先頭要素のアドレスを指しています。p + 1
は p
のアドレスに 1 を足したアドレスを指します。*(p + 1)
は p + 1
のアドレスに格納されている値を取得します。
10, 11, 12
0x7ffe73b706d8, 0x7ffe73b706dc, 0x7ffe73b706e0
0x7ffe73b706d8
0x7ffe73b706d8
10, 11, 12
0x7ffe73b706d8, 0x7ffe73b706dc, 0x7ffe73b706e0
10, 11, 12
以下にイメージ図を示します。
イメージ図では、以下のように表示されます。(わかりやすく 10 進数で表示しています。 int 型の変数の大きさは 4 byte ですが、わかりやすくするために、アドレスは 1 byte ずつに割り当てています。)
10, 11, 12
102, 103, 104
102
102
10, 11, 12
102, 103, 104
10, 11, 12