ポインタ演算: メモリの散歩

ポインタに1を足すと、1バイトではなく「1つ隣」に進む。

ポインタ演算
ポインタに対する加減算。アドレスが「型のサイズ分」増減する。
歩幅 (Step Size)
型によって1回に進むバイト数が違うこと(intなら4, charなら1)。
巨人の一歩 (Giant Steps)

ポインタの足し算(`p + 1`)は、単純に数字の1を足すのではありません。「その人が歩く一歩分」だけ進みます。 ・`char`(赤ちゃん)の1歩 = 1バイト ・`int`(大人)の1歩 = 4バイト ・`struct`(巨人)の1歩 = 100バイトかも? コンパイラは、ポインタの型を見ることで「誰が歩いているか(型のサイズ)」を判断し、適切な距離だけアドレスを進めます。

型を知っているから歩ける

ポインタに対する計算(p + 1 )は、普通の数字の足し算とは違います。「今の場所から、要素1つ分進む」という意味になります。

コンパイラはポインタの型(int* など)を知っているので、自動的にその型のサイズ(intなら4バイト)だけアドレスを進めてくれます。まるで番地を飛び越えて、隣の家に移動するような感覚です。

型による歩幅の違い

Scaling by Type
int arr[] = {10, 20, 30};
int *p = arr; // 先頭を指す
// +1 すると「次の要素」へ進む
printf("%d\n", *p); // 10
printf("%d\n", *(p + 1)); // 20 (intなら4バイト進む)
printf("%d\n", *(p + 2)); // 30
// char型なら1バイト進む
char str[] = "ABC";
char *cp = str;
printf("%c\n", *(cp + 1)); // 'B'

実践テクニック

イディオム: ポインタでループ

配列の要素を順番に処理するとき、添字(<code>i</code>)を使わずにポインタを進めていく書き方もよく使われます。

Pointer Iteration
// ポインタを使った配列ループ
int nums[] = {1, 2, 3, 4, 5};
int *ptr = nums;
// ptr が指す先が配列内にある限り進む
// (ここでは回数を決めてループ)
for (int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++; // 次の住所へ歩く
}
Warning: 範囲外アクセスに注意!配列の終わりを超えて進むと、プログラムはクラッシュします。

演習課題

課題1: 逆順表示
配列の最後の要素へのポインタを作成し、ポインタをデクリメント(引く)しながら逆順に表示してください。

合格ライン

ポインタに+1するとアドレスがいくつ増えるか答えられる
ポインタを使って配列を走査できる