広告スペース

第24回 配列を引数に

C言語で関数に配列を渡す方法。ポインタとの関係も解説。

配列を引数に渡す

配列を関数に渡すときは、引数の書き方が少し特殊です。
// 2通りの書き方。どちらも同じ意味
int sumArray(int a[], int n) { ... }
int sumArray(int *a, int n) { ... }

int main(void) {
  int scores[5] = {80,65,92,78,88};
  int total = sumArray(scores, 5); // 配列名だけで渡す(&不要)
  printf("%d\n", total);
}

int sumArray(int a[], int n) {
  int s = 0;
  for(int i=0; i<n; i++) s += a[i];
  return s;
}
配列のサイズ: 関数側で配列のサイズを知る手段がないため、サイズも引数で渡すのが定石です。

値渡し vs 参照渡し

通常のint/doubleは「値のコピー」が渡りますが、配列は「先頭のアドレス」が渡ります。
普通の値渡し(int, double)
関数内で変更しても呼び出し元に影響なし(コピーされた値を変更するだけ)
配列の渡し方
実体のアドレスが渡るため、関数内でa[i] = 0 すれば呼び出し元の配列も変わる
void reset(int a[], int n) {
  for(int i=0; i<n; i++) a[i] = 0; // 呼び出し元の配列も0になる
}

int main(void) {
  int x[3] = {1,2,3};
  reset(x, 3);
  printf("%d %d %d\n", x[0], x[1], x[2]); // → 0 0 0
}

sizeof の落とし穴

関数内で sizeof(a) は使えない! 関数内では配列は「アドレス」として渡されているため、sizeofはポインタのサイズ(8バイトなど)しか返しません。
int main(void) {
  int a[5];
  printf("%ld\n", sizeof(a));       // 20 (5要素×4バイト)
  test(a);
}
void test(int a[]) {
  printf("%ld\n", sizeof(a));       // 8 (ポインタのサイズ)!
}
対処法: サイズは必ず別の引数で渡すか、マクロ・#defineで定数として共有。

自分で書いてみよう ― 配列を引数に

arr_param.c
出力
「実行」を押してください...
広告スペース

関連する講座

繰り返し・配列・文字列
第18回 配列
C言語の配列の宣言・初期化・アクセス方法。メモリ配置も図解。
発展編
第25回 ポインタの基礎
C言語のポインタをメモリ可視化で理解。アドレスと間接参照を図解。
関数編
第20回 関数(基本)
C言語の関数の定義と呼び出し。引数・戻り値の仕組みを図解。
← 前の講座
第23回 グローバル変数
次の講座 →
第25回 ポインタの基礎

確認クイズ

この講座の理解度をチェックしましょう!

Q1. 配列を関数に渡すと何が渡される?

配列の全要素のコピー
配列の先頭要素へのポインタ
配列のサイズ

C言語では配列名は先頭要素のポインタとして解釈されるため、関数にはアドレスが渡されます。

Q2. 関数内で引数の配列を変更すると?

元の配列も変更される
元の配列は変更されない
コンパイルエラー

ポインタ渡しなので、関数内で配列の要素を変更すると呼び出し元の配列も変更されます。

Q3. 配列の要素数を関数に渡す方法として正しいのは?

sizeof で自動的にわかる
別の引数として要素数を渡す
渡す必要はない

関数に渡されるのはポインタだけなので、sizeof では元の配列サイズがわかりません。要素数は別の引数で渡す必要があります。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。丁寧な解説で基礎を固められます。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で、演習問題も充実。大学の教科書としても採用多数。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。基礎を終えた後のステップアップに最適。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。