C言語の配列とポインタの違いとは?メモリの視点でわかりやすく解説

目次

メモリ領域解説シリーズ

本記事は「メモリ領域解説」シリーズの1つです。

メモリ領域解説シリーズの全体像はこちら

C言語を学んでいると、よく出てくる疑問があります。

初心者さん

配列とポインタって何が違うの?

例えば次のコードです。

int arr[3] = {1,2,3};
int *p = arr;

このように書けるため、
「配列とポインタは同じものでは?」と感じる人も多いでしょう。

しかし実際には、配列とポインタは別のものです。

ただし、C言語では配列がポインタのように振る舞う場面があるため、
理解が難しくなっています。

この記事では、メモリの視点から配列とポインタの違いを整理します。


初心者さん

先輩、配列ってポインタなんですか?

エンジニアくん

それ、C言語あるあるの疑問だね。

初心者さん

だって配列名をそのままポインタに代入できますよね?

エンジニアくん

そう。そこがややこしいところなんだ。
配列はポインタ“ではない”けど、ポインタに変換されることがあるんだ。


配列とは

配列は、同じ型のデータを連続して格納するメモリ領域です。

int arr[3] = {1,2,3};

メモリのイメージ

arr
↓
+----+----+----+
| 1  | 2  | 3  |
+----+----+----+

3つの int が連続して配置されます。


ポインタとは

ポインタは、メモリアドレスを格納する変数です。

int *p;

ポインタ変数 p は、
どこかのメモリアドレスを保存するための変数です。

例えば

p = arr;

とすると、p には arr の先頭アドレスが入ります。


配列名がポインタのように使える理由

C言語では、多くの場面で配列名が先頭要素のアドレスに変換されます。

int *p = arr;

これは実質的に

p = &arr[0]

と同じ意味です。

そのため、配列とポインタが同じように見えるのです。


しかし配列とポインタは別物

sizeof の違い

int arr[3];
int *p = arr;
sizeof(arr) → 12 (int ×3)
sizeof(p) → 8 (ポインタサイズ)

配列はデータ全体のサイズですが、
ポインタはアドレスを保存する変数です。


代入できるか

ポインタ

p = arr;

は可能ですが、

配列

arr = p;

はできません。

配列は固定されたメモリ領域だからです。


関数引数では配列はポインタになる

関数引数では、配列はポインタとして扱われます。

void func(int arr[])

これは実質

void func(int *arr)

と同じです。

そのため、関数内では

sizeof(arr)

は配列サイズではなく
ポインタサイズになります。


まとめ

配列とポインタの違いを整理すると次のようになります。

項目配列ポインタ
意味連続したメモリ領域アドレスを保存する変数
サイズ配列全体ポインタサイズ
代入不可可能

配列はポインタではありませんが、
配列名がアドレスに変換される場面があるため、
同じように見えることがあります。

メモリの仕組みを理解すると、
この違いがより明確になります。

この記事が参考になった方へ

メモリ領域については他の記事でも解説しています。

メモリ領域解説シリーズの全体像はこちら

スタック領域の基本はこちらの記事で解説しています。

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

お問い合わせはこちら

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする


目次