C言語 | ポインタ | ポインタ演算
ポインタ演算を使うと、ポインタが参照する対象を変更できます。特に配列の要素を順番に参照するときに便利です。
アドレスを計算する
ポインタはメモリアドレスを保持し、データ型を持ちます。演算が意味を持つのは、配列のような連続した有効なメモリ領域の範囲内です。無関係なアドレスを間接参照すると、クラッシュや未定義動作の原因になります。
コード1
#include <stdio.h>
int main() {
char chStr[] = "Kitty on your lap";
int iCount;
for (iCount = 0; chStr[iCount]; ++iCount)
printf("&chStr[%d] = %p\n", iCount, (void *)&chStr[iCount]);
return 0;
}
配列は連続したメモリ領域を使うため、各要素のアドレスは順番に増加します。char は1バイトなので、chStr[0] のアドレスに5を加えると chStr[5] のアドレスになります。
コード2
#include <stdio.h>
int main() {
int iArray[] = { 10, 100, 1000 };
int *iPo = &iArray[0] + 1;
printf("*iPo = %d\n", *iPo);
return 0;
}
ここで iPo は iArray[1] を指します。ポインタ演算は常に1バイト単位ではなく、参照先の型を単位として進みます。
コード3
#include <stdio.h>
int main() {
int iArray[] = { 2, 4 };
printf("&iArray[0] = %p\n", (void *)&iArray[0]);
printf("&iArray[1] = %p\n", (void *)&iArray[1]);
return 0;
}
int が4バイトの環境では、表示される2つのアドレスの差は4バイトです。この調整はコンパイラが自動的に行います。
コード4
#include <stdio.h>
int main() {
int iArray[] = { 2, 4 };
int *iPo = &iArray[0];
printf("*iPo = %d : iPo = %p\n", *iPo, (void *)iPo);
iPo += 1;
printf("*iPo = %d : iPo = %p\n", *iPo, (void *)iPo);
return 0;
}
iPo += 1 の後、iPo は2番目の要素を指します。int * に1を加えると、アドレスは sizeof(int) バイト進みます。