62
44

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 5 years have passed since last update.

C言語の引数に多次元配列を渡す

Posted at

C言語では、関数の引数で「配列そのもの」を受け取ることができない。配列の先頭のアドレスを受け渡すことになる。

だから、配列の要素数は別途引数を用意して受け渡さなければならない。そうでないと関数内で配列の要素数を知るすべがなく、困ってしまう。

int sum_all(int length, int arr[]) {
/* int sum_all(int length, int *arr) でも同じ意味になる */
  int i, result = 0;
  for (i = 0, i < length; ++i) {
    result += arr[i];
  }
  return result;
}

ところで、二次元配列の事を考えてみる。多次元配列の場合、要素数の省略は最初の[]にしかできないから、普通にやるとこんな感じになってしまう。

/* 2次元のint配列を受け取って、全部足して返す */
int sum_all2(int xlength, int arr[][3]) {
  int i, j, result = 0;
  for (i = 0; i < xlength; ++i) {
    for (j = 0; j < 3; ++j) {
      result += arr[i][j];
    }
  }
  return result;
}

\突然現れるマジックナンバー3!/

これだと、要素数が片側固定になってしまうので関数の使い心地が悪い。一次元配列のintポインタにキャストしてarrを渡すという技もあるけど、素直じゃないし、書き方がポインタ演算になってしまうのでわかりにくくなっちゃう。

とか悩んでたら、C99だとこんな書き方ができるんだそうな。

int sum_all2(int size1, int size2, int arr[size1][size2]) {
  int i, j, result = 0;
  for (i = 0; i < size1, ++i) {
    for (j = 0; j < size2, ++j) {
      result += arr[i][j];
    }
  }
  return result;
}

int main(void) {
  int arr[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
  printf("%d", sum_all2(3, 3, arr));
  return EXIT_SUCCESS;
}

仮引数って引数宣言の中で使えるようになるんですね。。
これなら、配列サイズに依存せずに使えるし、書き方もそんなに気持ち悪くないし、便利。

62
44
2

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
62
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?