C言語基礎|配列とポインタの相違点

似ているからこそ危ない!配列は“動かない箱の列”、ポインタは“動く住所メモ”。

ここまでで、配列名が先頭要素へのポインタっぽく振る舞ったり、p[i] が使えたりと、配列とポインタが仲良しに見える理由を学びました。
でも実は、ここで混同すると事故ります。

配列は「要素が連続して並ぶ実体(領域)」で、ポインタは「どこかの領域を指すための値(住所)」です。
似た書き方ができるのは“表記上の都合”が大きくて、正体はかなり違います。

この記事では、特に重要な違いとして

  • ポインタは代入で指す先を変えられる。
  • 配列は代入の左側になれない(配列そのものは動かせない)

を、表と図でしっかり押さえていきます。

まず結論:ポインタは代入できる、配列は代入できない

ポイントはこれです。

代入できるかどうか

対象代入できる?何が変わる?
ポインタ変数p = aできるp の値(住所)が変わる
配列x = aできない配列は“実体”なので動かせない

OKな例:p = a が通る理由(p は住所メモだから)

OK例

int a[5];
int *p;

p = a;    // OK

この a は多くの式で &a[0] と同じ意味になりやすいので、結果として p は a[0] を指します。

図:p = a のイメージ

NGな例:x = a がエラーになる理由(配列は“動かない箱の列”)

NG例

int a[5];
int x[5];

x = a;    // エラー

これが許されると、配列 x の“置き場所”が丸ごと別の場所へ移動できることになります。
でも配列は「決まった領域に並ぶ実体」なので、代入で移動はできません。

重要ポイント

代入演算子の左オペランドを配列にすることはできない。

「配列の全要素コピー」ができない理由を、もう一段正確に言う

第5章の「代入演算子では配列全体をコピーできない」は有名ですが、ここではより本質的にこう言えます。

  • 配列は代入の左側になれない
  • つまり「配列全体を代入でコピーする」という操作自体が成立しない

よくある誤解と正しい捉え方

言い方ニュアンスより正確には
配列は代入でコピーできないコピーだけがNGに見える配列は代入の左側になれない

サンプルプログラム

「ポインタは指す先を変えられる」ことが体感できるプログラム例です。

プロジェクト名:chap10-12-1 ソースファイル名:chap10-12-1.c

#include <stdio.h>

int main(void)
{
    int a[3] = {10, 20, 30};
    int b[3] = {100, 200, 300};

    int *p = a;   // まず a を指す

    puts("ポインタは指す先を切り替えられます。");

    printf("最初: *p = %d(a[0]を見ている)\n", *p);

    p = b;        // 次に b を指す(代入OK)
    printf("切替後: *p = %d(b[0]を見ている)\n", *p);

    return 0;
}

このプログラムで言いたいことはシンプルです。

  • p は「住所の入れ物」だから、代入で a を指したり b を指したりできる
  • でも配列 a や b 自体は “動かせない”

もし配列をコピーしたいなら?(代入ではなく要素ごと)

配列を別の配列へ“内容だけ”コピーしたいなら、代入ではなくループで要素ごとに行います。

例:要素ごとのコピー

for (int i = 0; i < 5; i++) {
    x[i] = a[i];
}

コピー手段の整理

やりたいことできる?方法
x = a のように一発コピーできない代入の左に配列を置けない
要素の内容をコピーできるループで x[i] = a[i]
先頭要素を指すようにするできるp = a(ポインタならOK)

ついでに押さえる:ポインタと配列の正体の違い

見た目が似てても、存在の仕方が違います。

配列とポインタの正体(超重要)

観点配列ポインタ
正体連続した要素の領域そのもの住所を保持する変数
“値”要素の集合(実体)アドレスという値
変更できるもの各要素の値は変更できる指す先(アドレス)を変更できる
代入配列自体へはできないできる

登場する命令(関数)と書式・何をする命令なのか

今回のサンプルで出てきたのはこの2つです。

puts

  • 書式:puts(文字列);
  • 何をする?:文字列を表示して改行も付ける(ログを出すのに便利)

printf

  • 書式:printf(書式文字列, 引数1, 引数2, ...);
  • 何をする?:書式に従って表示する(%d で整数表示など)

使った表や図の説明(まとめ)

  • 代入可否の表は「配列とポインタの最大の違い」を一瞬で整理するためのものです。
  • p=a の図は「ポインタが先頭要素を指す」状態を矢印で視覚化したものです。
  • 誤解と正しい捉え方の表は「コピーできない」の本質が“配列が代入できない”点にあることを示しています。
  • コピー手段の表は「配列の内容コピー」と「ポインタの付け替え」を混同しないためのものです。