C言語における配列とポインタの関係を理解する
配列とポインタの関係
このチュートリアルでは、Cプログラミングにおける配列とポインタの関係について学びます。また、ポインタを使って配列要素にアクセスする方法も解説します。
配列とポインタの関係を学ぶ前に、以下の2トピックを確認しておいてください:
- C言語の配列
- C言語のポインタ
配列とポインタの関係
配列は連続したデータのブロックです。配列要素のアドレスを表示するプログラムを書いてみましょう。
#include <stdio.h>
int main() {
int x[4];
int i;
for(i = 0; i < 4; ++i) {
printf("&x[%d] = %p\n", i, &x[i]);
}
printf("Address of array x: %p", x);
return 0;
}
出力
&x[0] = 1450734448 &x[1] = 1450734452 &x[2] = 1450734456 &x[3] = 1450734460 Address of array x: 1450734448
配列xの連続する2要素間には4バイトの差があります。これはintのサイズが4バイトだからです(当環境のコンパイラでは)。
&x[0]とxのアドレスが同じであることに注目してください。変数名xが配列の最初の要素を指しているためです。

上記の例から、&x[0]はxと等価であり、x[0]は*xと等価であることがわかります。
同様に、
&x[1]はx+1と等価で、x[1]は*(x+1)と等価。&x[2]はx+2と等価で、x[2]は*(x+2)と等価。- …
- 一般に、
&x[i]はx+iと等価で、x[i]は*(x+i)と等価。
例1: ポインタと配列
#include <stdio.h>
int main() {
int i, x[6], sum = 0;
printf("Enter 6 numbers: ");
for(i = 0; i < 6; ++i) {
// scanf("%d", &x[i]); と等価
scanf("%d", x+i);
// sum += x[i] と等価
sum += *(x+i);
}
printf("Sum = %d", sum);
return 0;
}
プログラムを実行すると、以下のように出力されます:
Enter 6 numbers: 2 3 4 4 12 4 Sum = 29
ここでは6要素の配列xを宣言し、ポインタを使って要素にアクセスしています。
ほとんどの文脈では、配列名はポインタに退化します。簡単に言えば、配列名はポインタに変換されます。それがポインタで配列要素にアクセスできる理由です。しかし、ポインタと配列は同一ではないことを覚えておいてください。
配列名がポインタに退化しないケースもいくつかあります。詳細は「配列名がポインタに退化しない場合」を参照してください。
例2: 配列とポインタ
#include <stdio.h>
int main() {
int x[5] = {1, 2, 3, 4, 5};
int* ptr;
// ptrに3番目の要素のアドレスを代入
ptr = &x[2];
printf("*ptr = %d \n", *ptr); // 3
printf("*(ptr+1) = %d \n", *(ptr+1)); // 4
printf("*(ptr-1) = %d", *(ptr-1)); // 2
return 0;
}
実行結果:
*ptr = 3 *(ptr+1) = 4 *(ptr-1) = 2
この例では、&x[2](3番目の要素のアドレス)がポインタptrに代入されます。したがって、*ptrを出力すると3が表示されます。
*(ptr+1)は4番目の要素、*(ptr-1)は2番目の要素を与えます。
C言語
- 電動モータの電圧・電流不平衡:原因とトラブルシューティングの理解
- 運転・メンテナンス協働の強化で製造成果を最大化
- ブレージング vs 半田付け:温度・強度・冶金学的違いを完全解説
- 2ストローク vs 4ストロークエンジン:主な違いを徹底解説
- SCADAとHMI:主な違いとインダストリー4.0での役割
- DCモーターとACモーターの違い:主要な差異と購入ガイド
- ビッグデータとクラウドコンピューティング:相互補完的な関係性
- IoTとエッジ・コンピューティングが相互補完する仕組み
- C++ポインタと配列:関係性をマスターする
- C言語: アドレスとポインタを関数に渡す – 実践ガイド
- C言語 構造体とポインタ: 実践ガイド