
C言語のきほん|引数を受け取る関数
引数を渡せるようになると、関数はもっと便利な部品になる
C言語の関数を学び始めると、まずは決まった処理をそのまま行う関数を作ることが多いです。
でも、実際のプログラムでは「毎回少しずつ違う処理をしたい」という場面がたくさんあります。
そんなときに役立つのが、引数を受け取る関数です。
引数を使うと、関数の外から値を渡して、その値に応じて処理の内容を変えられるようになります。
たとえば、
- 回数を渡して、その回数だけ表示する
- 点数を渡して、評価メッセージを表示する
- 温度を渡して、コメントを変える
といったように、1つの関数をいろいろな場面で使い回せるようになります。
つまり、引数を受け取る関数は、固定の動きしかしない関数を、より柔軟に使える関数へ進化させる仕組みです。
ここでは、引数だけを持つ関数の書き方と考え方を、サンプルプログラムとともにやさしく整理していきます。
引数だけ持つ関数とは
引数だけ持つ関数とは、呼び出し元から値を受け取って処理を行うが、結果は返さない関数のことです。
宣言の形は次のようになります。
void 関数名(型 仮引数名);たとえば、整数を1つ受け取る関数なら次のように書きます。
void show_message(int level);この形には、大事な意味が2つあります。
| 要素 | 例 | 意味 |
|---|---|---|
| 返却値の型 | void | 値を返さない |
| 引数 | int level | 整数値を1つ受け取る |
ここでのポイントは、値は受け取るけれど、呼び出し元へ結果は返さないことです。
そのため、表示処理や案内処理などに向いています。
なぜ引数が必要なのか
引数がない関数は、呼び出しても毎回同じ動きをします。
それはそれで便利ですが、もう少し柔軟にしたいことがあります。
たとえば、次のような場面を考えてみてください。
- 1回だけではなく、指定した回数だけ表示したい
- 数字によってメッセージを変えたい
- 状況に応じて違う内容を表示したい
こうしたとき、関数の中に値を固定してしまうと使い回しがしにくくなります。
そこで、必要な値を引数として外から渡すようにすると、同じ関数をさまざまな場面で使えるようになります。
つまり引数は、関数に外から材料を渡すための仕組みです。
サンプルプログラム
点数に応じてメッセージを表示する関数を考えてみます。
この例では、score という引数を受け取り、その値に応じて異なるコメントを表示します。
ファイル名:13_7_1.c
// 引数だけ持つ関数の例
#include <stdio.h>
void show_comment(int score);
int main(void)
{
show_comment(85); // 関数を呼び出す(85点を渡す)
return 0;
}
// 点数に応じたコメントを表示する関数
void show_comment(int score)
{
if (score >= 80) {
printf("とてもよくできました!\n");
}
else if (score >= 60) {
printf("よくがんばりました!\n");
}
else {
printf("次もいっしょにがんばろう!\n");
}
}実行結果例
とてもよくできました!このプログラムの流れ
このプログラムでは、main 関数から次のように関数を呼び出しています。
show_comment(85);この 85 が、関数へ渡される実引数です。
そして、関数定義側では次のように受け取っています。
void show_comment(int score)この score が仮引数です。
つまり、呼び出し側で渡した 85 が、関数の中では score という名前で使われています。
流れを表にすると次のようになります。
| 順番 | 内容 |
|---|---|
| 1 | main 関数で show_comment(85); を実行する |
| 2 | 85 が関数へ渡される |
| 3 | 仮引数 score が 85 を受け取る |
| 4 | if 文で score の値を判定する |
| 5 | 条件に合ったメッセージを表示する |
| 6 | 関数が終了し、main 関数へ戻る |
このように、引数を使うことで、関数の動きが渡された値によって変わります。
実引数と仮引数の違い
引数を学ぶときに、とても大事なのが実引数と仮引数の違いです。
| 用語 | 書かれる場所 | 例 | 意味 |
|---|---|---|---|
| 実引数 | 関数呼び出し側 | show_comment(85); | 実際に渡す値 |
| 仮引数 | 関数定義側 | void show_comment(int score) | 受け取るための変数 |
今回の例なら、
- 実引数 → 85
- 仮引数 → score
です。
この区別があいまいだと、関数の流れが分かりにくくなります。
まずは、呼び出す側が実引数、受け取る側が仮引数と覚えておくとよいです。
返却値がないので受け取らない
この関数は引数を受け取りますが、返却値はありません。
そのため、呼び出すときに結果を変数へ代入することはしません。
たとえば、今回の呼び出しはこうです。
show_comment(85);返却値がないので、次のような書き方はしません。
int result = show_comment(85);なぜなら、show_comment は void 型、つまり何も返さない関数だからです。
この点はとても大切です。
引数があることと、返却値があることは別です。
値を受け取る関数でも、結果を返すとは限りません。
return 文は必要か
返却値がない関数では、最後に return 文を書かなくても大丈夫です。
関数の終わりの } まで処理が進めば、その時点で自動的に呼び出し元へ戻ります。
今回の関数も、最後は return を書いていません。
void show_comment(int score)
{
if (score >= 80) {
printf("とてもよくできました!\n");
}
else if (score >= 60) {
printf("よくがんばりました!\n");
}
else {
printf("次もいっしょにがんばろう!\n");
}
}ただし、途中で関数を終わらせたい場合には、
return;と書くことがあります。
たとえば次のような例です。
void show_comment(int score)
{
if (score < 0) {
return;
}
if (score >= 80) {
printf("とてもよくできました!\n");
}
else if (score >= 60) {
printf("よくがんばりました!\n");
}
else {
printf("次もいっしょにがんばろう!\n");
}
}このように書くと、score が 0 未満ならそこで関数を終了できます。
引数を受け取る関数のよさ
引数を受け取る関数には、いくつもよい点があります。
| よさ | 内容 |
|---|---|
| 再利用しやすい | 渡す値を変えるだけで何度も使える |
| 柔軟に動く | 状況ごとに違う処理ができる |
| コードを減らせる | 同じような処理を何度も書かなくてよい |
| 役割がはっきりする | 何を受け取って何をする関数か分かりやすい |
たとえば、show_comment 関数は 85 だけでなく、60 や 40 を渡しても使えます。
show_comment(85);
show_comment(60);
show_comment(40);こうすると、同じ関数なのに、渡した値に応じて表示内容が変わります。
これが引数の大きな強みです。
引数がない関数との違い
引数を受け取る関数の特徴をはっきりさせるために、引数がない関数と比べてみましょう。
| 比較項目 | 引数がない関数 | 引数がある関数 |
|---|---|---|
| 呼び出すたびに動きが変わるか | 基本的に変わらない | 渡す値によって変わる |
| 外から情報を渡せるか | 渡せない | 渡せる |
| 柔軟性 | 低め | 高い |
| 向いている処理 | 定型的な表示や固定処理 | 条件に応じて変わる処理 |
たとえば、
void show_title(void);なら毎回同じタイトルを表示するだけかもしれません。
一方で、
void show_comment(int score);なら score の値によってメッセージが変わります。
図で見ると流れがつかみやすい
引数の流れは、図で見るとかなり理解しやすくなります。
特に、「呼び出し側から値が渡される」というイメージがつかみやすくなります。

この図では、main 関数から show_comment 関数へ 85 という値が渡される様子 を表しています。
main 側で書いた 85 は実引数です。
それが show_comment 関数に渡されると、関数定義側では仮引数 score として受け取られます。
そのあと、score の値を使って if 文で分岐し、適切なメッセージを表示します。
この関数は返却値を持たないので、結果をどこかへ返す矢印はありません。
この点が、返却値ありの関数との違いです。
関数宣言・呼び出し・定義を対応させて見る
引数を受け取る関数では、宣言・呼び出し・定義の対応を見ることが大切です。
今回の例を対応づけると、次のようになります。
| 役割 | コード | 意味 |
|---|---|---|
| 関数プロトタイプ宣言 | void show_comment(int score); | この関数は int 型を1つ受け取る |
| 関数呼び出し | show_comment(85); | 実引数として 85 を渡す |
| 関数定義 | void show_comment(int score) | 仮引数 score で受け取る |
この3つがつながっていることを意識すると、関数の全体像がかなり見やすくなります。
引数の型は一致させることが大切
引数を使うときは、渡す値の型と受け取る側の型が合っていることが大切です。
今回の例では、
- 実引数 85 は整数
- 仮引数 score は int 型
なので一致しています。
もし関数宣言や関数定義の型がずれていると、正しく動かなかったり、警告の原因になったりします。
たとえば、宣言が
void show_comment(int score);なのに、定義が
void show_comment(double score)のようになっていると不一致です。
そのため、引数を使うときは次の点をそろえることが大事です。
| 確認したい点 | 内容 |
|---|---|
| 宣言の型 | int か double か |
| 呼び出し時の値 | 渡している値の種類は何か |
| 定義の型 | 宣言と一致しているか |
複数の値を受け取ることもできる
今回は引数を1つだけ受け取る例でしたが、関数は複数の引数を受け取ることもできます。
たとえば次のような形です。
void show_result(int score, int max_score);このように、カンマで区切って複数の引数を書けます。
ただし、今の段階ではまず引数を1つ受け取る基本形をしっかり押さえることが大切です。
1つの引数の流れが分かれば、複数引数も考えやすくなります。
実践問題
pr13_2_2.c
次の仕様に従って関数を作成し、main 関数から呼び出して結果を確認してください。
関数宣言
void show_temperature_message(int temperature);機能
温度 temperature の値に応じてメッセージを表示する。
表示ルール
- 30以上なら 暑いですね! と表示
- 15以上30未満なら 過ごしやすいですね! と表示
- 15未満なら 少し寒いですね! と表示
実行結果例
気温を入力してください > 18
過ごしやすいですね!解答例
ファイル名:13_7_2.c
// 気温に応じたメッセージを表示するプログラム
#include <stdio.h>
void show_temperature_message(int temperature);
int main(void)
{
int temperature;
printf("気温を入力してください > ");
scanf("%d", &temperature);
printf("\n");
show_temperature_message(temperature);
return 0;
}
// 気温に応じたメッセージを表示する関数
void show_temperature_message(int temperature)
{
if (temperature >= 30) {
printf("暑いですね!\n");
}
else if (temperature >= 15) {
printf("過ごしやすいですね!\n");
}
else {
printf("少し寒いですね!\n");
}
}解答例の解説
この問題では、main 関数で入力した temperature の値を、show_temperature_message 関数へ渡しています。
show_temperature_message(temperature);この temperature が実引数です。
そして関数定義側では、
void show_temperature_message(int temperature)のように、仮引数 temperature で受け取っています。
受け取った値を if 文で判定し、条件に応じたメッセージを表示しているので、まさに引数だけ持つ関数の基本形になっています。
この関数は表示することが役割なので、返却値は必要ありません。
そのため返却値の型は void になっています。
学習のコツ
引数を受け取る関数を学ぶときは、次の2つを意識すると理解しやすいです。
外から値を渡していることを意識する
関数の中に値が突然現れるのではなく、呼び出し元から渡されていると考えることが大切です。
受け取った値で処理が変わることを意識する
引数があることで、同じ関数でも渡す値に応じて違う動作ができます。
ここが、引数なしの関数との大きな違いです。
この2つを意識しながらコードを読むと、引数の意味がぐっとつかみやすくなります。
