8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C言語 配列とポインタのややこしいところ

Last updated at Posted at 2020-03-03

##変数と配列の違い
###変数
char a = 123;

a は 変数aの値(ここでは123)
&a は 変数aのアドレス
を指します。

「&」はメンバアクセス演算子の中のアドレス取得演算子といってアドレスを表示してくれる演算子です。

参考: メンバアクセス演算子 - cppreference.com

配列

char a[4] = "ABC";

a は 配列aの先頭要素のアドレス
a[0] は a[0]の値('A')
a[1] は a[1]の値('B')
a[2] は a[2]の値('C')
a[3] は a[3]の値('\0')
を指します。

ここでややこしいのが、aとした場合、アドレスを指していること。

[]」は演算子です。後で説明します。

###配列のaはあくまでアドレスを示すだけ。ポインタ変数になっているわけではない。
char a[4] = "ABC";と書いたとき、
aは先頭アドレスを示すが、ポインタ変数になっているわけではない。つまりaは&a[0]と同じ意味というだけである。
その証拠に下記のような書き方をするとエラーが出る。

#include <stdio.h>

int main(void)
{
    char a[4] = "ABC";
    char *p = a;
    printf("%p\n", a);
    printf("%p\n", p);

    // ポインタをインクリメントさせる
    p++;
    printf("%p\n", p);

    // この書き方ではエラーになる。
    a++;
    printf("%p\n", a);
}

##[]の正体
[]は配列の要素番号を指定する演算子。
仕組みとしては、配列名というアドレスに足し算を行っているだけ。

int a[4];

と宣言した場合、
aの先頭アドレスが1000とすると
&a[0]は1000
&a[1]は1001
&a[2]は1002
&a[3]は1003
のように先頭のアドレスに番号の値だけ足し算を行う仕組みです。

※注意点
a[0]は通常編集モードなのでポインタとして扱うことは出来ないです。
また、&a[0]もアドレス演算子&によって、アドレスを表示させているだけなので、ポインタ変数モードになっていないという点に注意です。

##配列における宣言時と数式の違い。
配列を宣言するときの[]は要素数を指定するための記号です。
配列の各要素を使うときに[]で番号指定するときの[]は先頭アドレスに足し算するための演算子です。

##まとめ
###配列とポインタは全くの別物

  • 配列
    • 多数の変数を順番つけでまとめて扱う方法
  • ポインタ
    • 変数のショートカットを作る方法

です。混同されがちなので気をつけてください。

###参考
配列とポインタ
http://www9.plala.or.jp/sgwr-t/c/sec10-2.html

配列とポインタの奇妙な関係 - 苦しんで覚えるC言語
https://9cguide.appspot.com/15-07.html

8
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?