2012/05/02

C言語 配列 arrays

配列の宣言

配列は同じ型の集まり。データを一括して扱う場合に使用する。ひとつひとつを要素(element)という。要素数の添え字は0から始まる。例として10個のint型の配列を宣言。
int a[10];
配列にアクセスするときの添え字は0から9となる。
a[0]~a[9]
この配列の中にint型の数値を入れるには、いくつかの方法がある。
要素ひとつひとつに入れる場合は以下のようにする。
a[0]=255;
a[1]=256;
配列を宣言するときに初期値として入れてしまうことも可能。
int a[10] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55};
また、初期値をこのように入れている場合は、要素数は省くこともできる。
int a[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55};


int型の配列

#include <stdio.h>
int main(void){
  int a[] = {1,1,2,3,5,8,13,21,34,55,89,144};
  int i;
  for(i=0;i<15;i++){
    printf("%d array= %d アドレス=%x\n"
                       ,i,a[i],&a[i]);
  }
  return 0;
}
配列を用意して、初期値となる数列を入れる。それをfor文で出力。実行結果は以下の通り。注目点はアドレスがint型の4byteずつ増加しているところ。要素は4byteをひとつとして数えているのが分かる。また配列の要素以上に繰り返し表示させているが、最後の要素である144以降は無関係な数値が入っている。Javaではコンパイルエラーになるようなところも、C言語では容赦なく実行してしまうので注意が必要。
0 array= 1 アドレス=23ff0c
1 array= 1 アドレス=23ff10
2 array= 2 アドレス=23ff14
3 array= 3 アドレス=23ff18
4 array= 5 アドレス=23ff1c
5 array= 8 アドレス=23ff20
6 array= 13 アドレス=23ff24
7 array= 21 アドレス=23ff28
8 array= 34 アドレス=23ff2c
9 array= 55 アドレス=23ff30
10 array= 89 アドレス=23ff34
11 array= 144 アドレス=23ff38
12 array= 12 アドレス=23ff3c
13 array= 4200620 アドレス=23ff40
14 array= -2092586108 アドレス=23ff44



char型の配列

C言語では文字列を扱う場合はchar型の配列として扱われる。
char s[] = "0123 ABC";
配列の中身をプログラムで確かめてみる。
#include <stdio.h>
int main(void){
  char s[] = "0123 ABC";
  /* 上記は下と同じ意味になる */
  /* char s[] ={'0','1','2','3',' ','A','B','C','\0'}; */
  int i;
  for(i=0;i<11;i++){
    printf("%d char= %c 16進数= 0x%x アドレス=%x\n"
                               ,i,s[i],s[i],&s[i]);
  }
  return 0;
}
実行結果は下のようになる。各要素には1byte分の文字が入っている。アドレスはきれいに並んでいるのが確認できる。アドレスは1byte単位で、char型の1byteと一致しているからそのようになる。型に応じてアドレスの間隔は違う。文字列の最後には必ず\0(16進数の0)が入っている。これは文字列が終了したことを示すものでコンパイラが入れてくる。自分で "0123 ABC\0"; と入れてもいい。それ以降の要素にはs[]とは無関係な値が入っている。ちなみにchar型の数字0は16進では0x00ではなく、0x30になっている。ASCIIコードを見れば、どういう仕組みになっているかわかる。
http://ja.wikipedia.org/wiki/ASCII
0 char= 0 16進数= 0x30 アドレス=23ff33
1 char= 1 16進数= 0x31 アドレス=23ff34
2 char= 2 16進数= 0x32 アドレス=23ff35
3 char= 3 16進数= 0x33 アドレス=23ff36
4 char=   16進数= 0x20 アドレス=23ff37
5 char= A 16進数= 0x41 アドレス=23ff38
6 char= B 16進数= 0x42 アドレス=23ff39
7 char= C 16進数= 0x43 アドレス=23ff3a
8 char= ^@ 16進数= 0x0 アドレス=23ff3b
9 char=   16進数= 0x9 アドレス=23ff3c
10 char= ^@ 16進数= 0x0 アドレス=23ff3d


配列の要素数を調べて利用する sizeof

上記は表示するときに回数指定の記述をしている。要素数が分かるときならよいが、そうでない場合困ってしまう。そこで配列の要素数を調べて利用する。
#include <stdio.h>
int main(void){
  int a[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55,89,144};
  int i;
  for(i=0;i<sizeof(a)/4;i++){
    printf("%2d array= %3d アドレス= %x\n"
         ,i,a[i],&a[i]);
  }
  char s[] = "0123 ABC";
  for(i=0;i<sizeof(s);i++){
    printf("%2d char= %c 16進数= 0x%x アドレス= %x\n"
                               ,i,s[i],s[i],&s[i]);
  }
  return 0;
}
sizeofを利用することで要素数分だけ繰り返しを実行できる。sizeofは1byte分なので、char型ではそのまま利用できるが、int型は4byteなので4で割っている。
 0 array=   1 アドレス= 23ff0c
 1 array=   1 アドレス= 23ff10
 2 array=   2 アドレス= 23ff14
 3 array=   3 アドレス= 23ff18
 4 array=   5 アドレス= 23ff1c
 5 array=   8 アドレス= 23ff20
 6 array=  13 アドレス= 23ff24
 7 array=  21 アドレス= 23ff28
 8 array=  34 アドレス= 23ff2c
 9 array=  55 アドレス= 23ff30
10 array=  89 アドレス= 23ff34
11 array= 144 アドレス= 23ff38
 0 char= 0 16進数= 0x30 アドレス= 23ff03
 1 char= 1 16進数= 0x31 アドレス= 23ff04
 2 char= 2 16進数= 0x32 アドレス= 23ff05
 3 char= 3 16進数= 0x33 アドレス= 23ff06
 4 char=   16進数= 0x20 アドレス= 23ff07
 5 char= A 16進数= 0x41 アドレス= 23ff08
 6 char= B 16進数= 0x42 アドレス= 23ff09
 7 char= C 16進数= 0x43 アドレス= 23ff0a
 8 char= ^@ 16進数= 0x0 アドレス= 23ff0b


C言語 ANSI C89 Meadow & MinGW GCC 目次はこちら