配列

C言語勉強会 第六回

E3
May 29, 2013
引用 : Programming Place Plus

配列

これまで使ってきた変数は
a b c i j x y z

など、変数名のみで扱った。たとえばこいつらに0~7までの数字を代入しようとすると a=0; b=1; c=2; ・・・ z=7;

非常に扱いにくい。

ではここでおもむろに配列を使ってみる。
_人人人人人人人_
> 配列って何 <
 ̄Y^Y^Y^Y^Y^Y ̄

配列とは 同じ型の連続したメモリ領域 を確保するものである。

配列の宣言

コレまでの変数と「基本」は同じ。今までのは
int a;
これでint型でaという変数が宣言された。

配列の宣言は
型 変数名[サイズ];
といった風に宣言される。
int arr[ 7 ];
これでarrという配列変数がint型 7 つぶんの大きさで宣言された。

前のスライドのaという変数は
a
という1つだけの変数を宣言している。 先ほどのarrという配列の宣言は実質的には
arr[ 0 ] arr[ 1 ] arr[ 2 ] arr[ 3 ] arr[ 4 ] arr[ 5 ] arr[ 6 ]
という整数型の7つの変数の宣言(のよう)になる

arrは配列の変数名、[ ]の中の数字は 添字 という。
添字は必ず0から始まることに注意しよう!

イメージ図

配列はこんなイメージ。きれいに並んでいる 配列のイメージ

普通の変数は変数名のみで扱うが、配列は変数名と添字の組み合わせで扱う。
配列の4番目の要素に123という整数を代入したいなら、

arr[3] = 123;

と書く。

添字には整数の数字を指定してarr[6]のように書いても(つまり添字に定数を指定する書き方でも)いいが

変数名と括弧内の添字の組み合わせで書くということ以外は普通の変数と同じに取り扱える。
添字に変数を指定しても構わない。

添字に変数を指定してもいいということは繰り返し構文とかと組み合わせるとHappyかもしれない

先の例と同じ様にarrが大きさ7で宣言されているint型の配列なら(さらにint型の変数iが宣言されているとする)

for( i = 0; i < 7 ; ++i )
    printf( "%d\n" , arr[i] );

などと書くと、配列の全ての要素を出力できる。

配列と繰り返し構文を使うと配列のすべての要素に同じ処理を一気にしたりできる。

注意

arrのサイズを7と宣言したということは、arr[0]からarr[6]までの7つの要素にアクセス/変更しても良いということである。
しかしarr[7]やarr[-1]にはアクセス/変更してはいけない。

配列のエラー

配列のエラー

最初はよくやってしまいがちなので本当に気をつけよう。

for文でも同様に添字に気を付けなければならない。先ほどのfor文

for( i = 0; i < 7 ; ++i )
    printf( "%d\n" , arr[i] );

ここでは繰り返しの条件を i < 7 としているが、これは配列のサイズが7と定義されているという理由でこの条件にしている。
iは0から6まで増えていき、iが7のときには既にループから抜けているので、誤ってarray[7]にアクセスすることはない。
このような繰り返し構文では配列のアクセスに注意して書く必要がある。

配列の宣言と初期化その1

配列の宣言時には括弧内に配列の大きさを指定するが、この大きさ指定部分には定数を書かなければならない。

呼び出し時には添字に変数を指定してもいいのだが、紛らわしいことに宣言時の括弧内に書くことと呼び出し時に括弧内に書くことはまったく別の意味を持つ。注意。

動的確保ってやりかたもあるけどそれはまた別な話

配列の宣言と初期化その2

配列は初期化もできる。

int x = 5;  //普通の変数の初期化  
int a[5] = {0,2,4,6,8}; //配列の変数の初期化  

上は変数xに5が入ってる。これは普通。

下はa[0]に0、a[1]に2、a[2]に4、a[3]に6、a[4]に8
が入っている。

配列の初期化は、順番に要素を代入していくと考えるとよい。ちなみに初期化するときは

int a[] = {0,2,4,6,8};

これでも配列の大きさ5と勝手に解釈され、
上と同じ意味になる。

多次元配列

さっきの配列は「1次元配列」とも呼ばれる。当然「2次元配列」や「3次元配列」もある。

int a[3];   //1次元配列  
↓  
a[0] a[1] a[2]  


int  a[3][4];   //2次元配列  
↓  
a[0][0]  a[0][1]  a[0][2]  a[0][3]  
a[1][0]  a[1][1]  a[1][2]  a[1][3]  
a[2][0]  a[2][1]  a[2][2]  a[2][3]  

1次元配列ではサイズ数の変数を、2次元配列ではサイズ数×サイズ数、
3次元配列では・・・と続く。2次元以上の配列を 多次元配列 という。

配列の宣言と初期化その3

多次元配列の初期化はどうなるか。

int a[3][3] = { {2,4,6},  
                {3,6,9},  
                {4,8,12} };  

これは
変数a[0][0]に2 変数a[0][1]に4 変数a[0][2]に6
変数a[1][0]に3 変数a[1][1]に6 変数a[1][2]に9
変数a[2][0]に4 変数a[2][1]に8 変数a[2][2]に12
が入ってる。ちなみに上の初期化は

int a[3][3] = { {2,4,6}, {3,6,9}, {4,8,12} };  

このような1行でも表せる。

1次元配列では繰り返し文ですべての要素に対して操作できたりしたが、多次元配列でも繰り返し文で同様のことができる

場合にもよると思うが、素直に考えるなら、2次元配列なら2重の繰り返し文、3次元配列なら3重の繰り返し文を使うことになるだろうたぶん

確認問題

  1. int a[10] と宣言された配列aがある。 aa[0] の違いは何か。
  2. int aint a[1] の違いは何か。
  3. int a[2][3][4] と宣言された配列aがある。これはどのようにメモリが確保されるか。