2012/05/03

C言語 多次元配列

2次元以上の配列を多次元配列という。これは1次元配列の各要素に、さらに1次元配列をするようなもの。2次元配列の場合は升目をイメージになり、3次元配列の場合は、さらに奥行きが加わって立体になるようなイメージ。4次元では、さらに各要素に1次元配列がされていく。イメージとしては個人差が出るところだが、個人的には2次元&入れ子でイメージしている。こうすれば何次元だろうが容易いので。

まずは2次元配列。使うシーンとしては、縦横柔軟な計算が必要なとき。サンプルは、よくある成績の例で、いくつかの方法で計算してみた。
#include <stdio.h>
/* マクロ定義 配列の要素のサイズを調べる */
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
/* 2次元配列 A,B,C,Dさんの国語、算数、理科の点数 */
int main(void) {
  float a[][3]={ /* 最初の配列の要素数は省略可 */
     {50,50,50} /* 0=Aさん 国語、算数、理科の点数 */
    ,{90,60,50} /* 1=Bさん 国語、算数、理科の点数 */
    ,{30,90,40} /* 2=Cさん 国語、算数、理科の点数 */
    ,{40,70,60} /* 3=Dさん 国語、算数、理科の点数 */
  };
  /* 各人の3教科平均点 */
  int i;
  int j;
  float sum;
  for(i=0;i<SIZE(a);i++){
    for(j=0;j<SIZE(a[0]);j++){
        sum += a[i][j];
    }
    printf("各人平均点 %d= %f\n",i,sum/SIZE(a[0]));
        sum = 0;
  }
  /* 各教科の平均点 国語=0、算数=1、理科=2 */
  for(i=0;i<SIZE(a[0]);i++){
    for(j=0;j<SIZE(a);j++){
        sum += a[j][i];
    }
    printf("教科平均点 %d= %f\n",i,sum/SIZE(a));
        sum = 0;
  }
  /* 全体の平均点 */
  for(i=0;i<SIZE(a);i++){
    for(j=0;j<SIZE(a[0]);j++){
        sum += a[i][j];
    }
  }
  printf("全体の平均点= %f",sum/(sizeof(a)/4));
  return 0;
}
A,B,C,Dさんの国語、算数、理科の点数を2次元配列で用意し、あれこれ計算してみる。縦横計算する必要がある場合には2次元配列は便利。行列の計算などにも使える。さらに3次元、4次元と多次元配列は可能だが、使うのは普通3次元配列まで。4次元以上になると、直感的にイメージしにくくなるし、必要なシーンも極端に少ないはず。一般的には配列は次元が増えるほど使用頻度が減る。また、低い次元で実現できるなら、なるべく低い次元の配列を使うべきだと思う。
各人平均点 0= 50.000000
各人平均点 1= 66.666667
各人平均点 2= 53.333333
各人平均点 3= 56.666667
教科平均点 0= 52.500000
教科平均点 1= 67.500000
教科平均点 2= 50.000000
全体の平均点= 56.666667


2次元配列を使った文字列の表示

#include <stdio.h>
void array(int n) {
  int i;
  char str[][8] = {
   "abc",
   "defg",
   "hijkl",
   "mnopqr"
  };
  printf("str[%d] s: %s\n", n, str[n]);
  for(i=0; i < sizeof(str[0]); i++){
     printf("str[%d] [%d]: %c\n", n, i, str[n][i]);
  }
}

int main(void) {
  array(0);
  array(3);
  return 0;
}
あらかじめ文字列の配列を用意し、そこにアクセスして任意の文字列を表示させている。%s であれば文字列が表示され、%cで各文字を表示することができる。
配列を宣言するときの要素数については、一つ目の[]は4つ入れることが分かっているので省略している。数字をstr[4][8]と入れても問題ない。2つ目の[]は数値を入れている。これを変数にしてしまうと、GCCではコンパイルエラーが起きてしまう。
str[0] s: abc
str[0] [0]: a
str[0] [1]: b
str[0] [2]: c
str[0] [3]: 
str[0] [4]: 
str[0] [5]: 
str[0] [6]: 
str[0] [7]: 
str[3] s: mnopqr
str[3] [0]: m
str[3] [1]: n
str[3] [2]: o
str[3] [3]: p
str[3] [4]: q
str[3] [5]: r
str[3] [6]: 
str[3] [7]: 


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