見出し画像

C言語教室 第3回 - 配列という入れ物

同じような処理を繰り返す場合、その数だけ対応する変数を用意するのは大変です。

#include <stdio.h>

void main() {
  int a1;
  int a2;
  int a3;

  a1 = 3;
  a2 = 5;
  a3 = 7;

  printf("%d\n", a1);
  printf("%d\n", a2);
  printf("%d\n", a3);
}

この結果は当然のように

3
5
7

となります。このような時には配列変数というものを使うことで、わかりやすく(コードも簡単に)することができます。

#include <stdio.h>

void main() {
  int a[3];
  int i;

  a[0] = 3;
  a[1] = 5;
  a[2] = 7;

  for( i = 0; i < 3; i++) {
    printf("%d\n", a[i]);
  }
}

ちゃんと結果は同じですね。

3
5
7

配列変数を使う時には、まず宣言で配列であることを指定します。変数名の後ろに続く’[]’の中に「何個」使うのかを指定します。例では3個を指定していますので、配列変数を使う時には’[]’の中が0,1,2の3個が使えるようになります(他の言語を知っている方は、ここが微妙に違うことがあるので注意)。この個数の指定を配列の大きさであるとか、要素数と呼ぶこともあります。また配列変数を使うときの’[]’の中の数字を添え字とかインデックスということがあります。

さて配列変数は、このように添え字がひとつだけの1次元配列だけではなく、2つまたはそれ以上の多次元配列にすることもできます。

#include <stdio.h>

void main() {
  int a[2][2];
  int i, j;

  a[0][0] = 0;
  a[0][1] = 1;
  a[1][0] = 2;
  a[1][1] = 3;

  for ( i = 0; i < 2; i++) {
    for ( j = 0; j < 2; j++) {
      printf("Value[%d][%d]=%d\n", i, j, a[i][j]);
    }
  }
}

iとjの宣言ですが、同じ型の変数はこのように’,’で区切って同じ行で複数の変数を宣言することもできます。さて結果は

Value[0][0]=0
Value[0][1]=1
Value[1][0]=2
Value[1][1]=3

C言語の多次元配列は、多次元配列という構文があるのではなく、int a[2][2]という宣言は「int a[2]という型の変数を大きさ2の配列」としてを宣言するよという意味です。ですから後ろに[]を続ければ何次元であっても同様です(他の言語にあるように’[]’の中を’,’で区切るような書き方ではない)。

ところで第2回で説明した参照を、配列変数に対して取ってみましょう。

#include <stdio.h>

void main() {
  int a[3];
  int *pa;
  int i;

  a[0] = 0;
  a[1] = 1;
  a[2] = 2;

  for ( i = 0; i < 3; i++) {
    pa = &a[i];
    printf("Value[%d]=%d\n", i, *pa);
  }
}

参照をとってから、その値をprintfで使っています。

Value[0]=0
Value[1]=1
Value[2]=2

これは簡単ですね。同じように2次元配列に対しても参照をとってみます。

#include <stdio.h>

void main() {

  int a[2][2];
  int *pa;
  int i, j;

  a[0][0] = 0;
  a[0][1] = 1;
  a[1][0] = 2;
  a[1][1] = 3;

  for ( i = 0; i < 2; i++) {
    for ( j = 0; j < 2; j++) {
      pa = &a[i][j];
      printf("Value[%d][%d]=%d\n", i, j, *pa);
    }
  }
}

結果は

Value[0][0]=0
Value[0][1]=1
Value[1][0]=2
Value[1][1]=3

参照がとれるようになったので、これを使って配列をアクセスする別の方法があります。

#include <stdio.h>

void main() {
  int a[3];
  int *pa;
  int i;

  a[0] = 0;
  a[1] = 1;
  a[2] = 2;

  pa = &a;
  for (i = 0; i < 3; i++) {
    printf("Value[%d]=%d\n", i, *pa);
    pa++;
  }
}

&aは配列aの先頭、つまりa[0]を指しています。このように参照をインクリメントすること(+1すること)で、最初から順に次の配列の中身を指すように書くことが出来ます。

Value[0]=0
Value[1]=1
Value[2]=2

配列のそれぞれの中身すべてを使う時に、この方法が効率が良いこともあり、よく使われる書き方です。

配列は、中身がすべて同じ型でなければならないこと、大きさを宣言時に決めておかなければならないことがポイントです。

お約束

これだけわかれば、もう大丈夫です。参照を使うと配列でも普通の変数と同じように使えるということも覚えておいてください。


課題

  • 大きさで指定した範囲を超えた値を使ってみて、何が起こるか確認してください。

  • 2つの配列の中身をそれぞれ入れ替える処理を、以前に使ったswap関数を使って書いてください。


第2回の回答例

C言語教室 第2回 - 参照渡し

前回の課題は引き数の値を2倍にする関数でしたね。

#include <stdio.h>

void doubler(int *p) {
  *p = *p * 2;
}

void main() {
  int a;

  a = 2;
  printf("a=%d\n", a);

  doubler(&a);
  printf("a=%d\n", a);
}

ちゃんと2倍になっているかな。

a=2
a=4

なおdoubleは予約語なので関数名として使うことが出来ません。


この記事が気に入ったらサポートをしてみませんか?