
C言語基礎|配列の受渡し
ここまでで「関数は部品」「依存しすぎる関数は再利用しにくい」という話をしてきましたよね。
その流れで次に出てくるのが 配列を関数に渡す(受け渡す) というテーマです。
C言語では、配列を関数に渡すときにちょっと独特なルールがあります。
- 配列そのものを丸ごとコピーして渡す、というより
配列の先頭を指す情報(先頭アドレス)が渡る という振る舞いになります(※理由は後でしっかり説明します) - だからこそ、関数側は 要素数を別に受け取る のが基本です
この「配列+要素数をセットで渡す」型を身につけると、どんな配列にも使える 汎用関数 が作れるようになります。

サンプルプログラム
ここでは「1週間(7日)の歩数」と「1週間(7日)の睡眠時間」を入力して、それぞれの最大値を求めるプログラムを例に解説をします。
サンプル:2種類の配列を同じ関数で処理する
プロジェクト名:chap6-14-1 ソースファイル名:chap6-14-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
// 2つの配列(歩数・睡眠時間)の最大値を求める
#include <stdio.h>
#define DAYS 7 // 1週間
//--- 要素数nの配列vの最大値を返す ---//
int max_of(const int v[], int n)
{
int max = v[0];
for (int i = 1; i < n; i++) {
if (v[i] > max)
max = v[i];
}
return max;
}
int main(void)
{
int steps[DAYS]; // 歩数
int sleep[DAYS]; // 睡眠時間(分)
puts("1週間のデータを入力してください。");
for (int i = 0; i < DAYS; i++) {
printf("%d日目 歩数:", i + 1);
scanf("%d", &steps[i]);
printf(" 睡眠(分):");
scanf("%d", &sleep[i]);
}
int max_steps = max_of(steps, DAYS);
int max_sleep = max_of(sleep, DAYS);
printf("歩数の最大=%d\n", max_steps);
printf("睡眠(分)の最大=%d\n", max_sleep);
return 0;
}実行例
1週間のデータを入力してください。
1日目 歩数:6500
睡眠(分):420
2日目 歩数:7200
睡眠(分):360
3日目 歩数:5000
睡眠(分):480
4日目 歩数:9100
睡眠(分):390
5日目 歩数:8300
睡眠(分):450
6日目 歩数:10000
睡眠(分):300
7日目 歩数:7600
睡眠(分):510
歩数の最大=10000
睡眠(分)の最大=510配列を渡すときの「見た目」と「実際」
ここがいちばん大事な感覚です。
コード上は「配列を渡している」ように見えるのに、実際は「先頭を指す情報を渡している」挙動になります。
配列の受渡しで起きていること
| 観点 | 呼び出し側 | 呼び出され側 | どういう意味? |
|---|---|---|---|
| 書き方 | max_of(steps, DAYS) | int max_of(const int v[], int n) | 配列名だけ渡す/関数側は [] で受け取る。 |
| 実体 | steps は int の配列 | v は配列に見えるが… | 実際には先頭要素を指す情報として扱われる。」 |
| 要素数 | DAYS を別引数で渡す | n として受け取る | 配列の長さは自動で分からないので必須 |
図:呼び出し側と関数側の対応
下の図は、関数 max_of を呼び出した瞬間のイメージです。

- v[0] は steps[0] と同じ
- v[5] は steps[5] と同じ
つまり 関数内の v は、渡された配列そのものを指している ように振る舞います。
なぜ要素数を別で渡す必要があるの?
C言語の関数は、受け取った配列 v から「何個あるか」を自動では知れません。
なので、必ず自分で n を渡してあげるのが基本になります。
要素数を渡さないと困ること
| 困りごと | 具体的に何が起きる? |
|---|---|
| どこまで読めばいいか分からない | ループの上限が決められない |
| 間違って範囲外へアクセスしやすい | 未定義動作の原因になりやすい |
| 汎用関数にならない | 使うたびに固定長前提になる |
関数頭部の読み方(書式と意味)
今回のキモはここです。
max_of の書式
- 返却値型:int
- 関数名:max_of
- 仮引数:const int v[] と int n
int max_of(const int v[], int n)関数頭部のパーツ分解
| パーツ | 例 | 意味 |
|---|---|---|
| 返却値型 | int | 最大値を int で返す |
| 関数名 | max_of | 「最大値を求める」役割の名前 |
| 配列仮引数 | const int v[] | int の配列を受け取る(読み取り専用にする) |
| 要素数 | int n | 配列の要素数を別で受け取る |
const を付ける理由
max_of は「調べるだけ」で、配列の中身を変更しません。
なので const を付けておくと、「うっかり書き換え」をコンパイラが防いでくれて安全です。
この関数が「汎用的」になる理由(依存しない設計)
今回の max_of は、
- 特定の配列名に依存しない(stepsでもsleepでもOK)
- 固定の人数や日数に依存しない(7でも30でもOK)
- 外のマクロやグローバル変数に頼らない
つまり「部品」として完成度が高いです。
依存していないポイント
| 依存対象 | 依存していると… | 今回はどう? |
|---|---|---|
| グローバル配列 | 別データで使いにくい | 引数で受け取るのでOK |
| 固定要素数 | サイズ変更に弱い | n を引数で受け取るのでOK |
| 入出力 | テストしにくい | max_of は計算だけでOK |
演習:配列の最小値を求めよう
「1週間の気温(7個)を入力して、最小値を表示する」プログラムを作成せよ。
最小値を求める関数 min_of を作って、main から呼び出すこと。
- 関数:int min_of(const int v[], int n);
解答例
プロジェクト名:chap6-14-2 ソースファイル名:chap6-14-2.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
#define DAYS 7
int min_of(const int v[], int n)
{
int min = v[0];
for (int i = 1; i < n; i++) {
if (v[i] < min)
min = v[i];
}
return min;
}
int main(void)
{
int temp[DAYS];
puts("1週間の気温を入力してください。");
for (int i = 0; i < DAYS; i++) {
printf("%d日目:", i + 1);
scanf("%d", &temp[i]);
}
printf("最小の気温=%d\n", min_of(temp, DAYS));
return 0;
}解説(ポイントだけ)
- min_of は配列 temp を直接知らない。引数 v と n だけで動く。
- だから別の配列(湿度、売上、点数)でも同じ関数を使える。
- const を付けて「読むだけ」を明確化している。
重要ポイント(ここだけは覚えておく)
- 配列を関数に渡すときは、配列名だけ を渡す。
- 関数側は 型 引数名[] の形で受け取る。
- 要素数は別引数で渡す(超重要)
- 読むだけなら const を付けると安全
