
C言語基礎|引数を受け取らない関数
入力を“お願いする係”を部品にしよう
Cのプログラムって、入力チェックを入れはじめると、main 関数が一気にゴチャつきがちです。
そこで便利なのが 「引数を受け取らない関数」。
たとえば、
- 「条件を満たすまで入力を繰り返す」
- 「入力に失敗したら、もう一度うながす」
みたいな処理は、呼び出し側から見ると
「とにかく、条件OKの値を1つ返して!」ってお願いしたいだけですよね。
そういう“お願い”を引き受けるのが、引数なし関数です。

引数を受け取らない関数ってどういうもの?
引数を受け取らない関数は、呼び出し側から情報を受け取らずに動きます。
じゃあ何を頼りに動くの?というと、だいたいは次のどれかです。
引数なし関数が動ける理由
| 依存先 | 具体例 | 何ができる? |
|---|---|---|
| キーボード入力 | scanf | ユーザーに入力させる。 |
| 乱数・時刻 | rand, time | 実行のたびに変化する値を作る。 |
| グローバル変数 | 外部の状態 | 状態を共有して処理する。 |
| 固定の規則 | ルール化 | 一定の処理を毎回実行する。 |
今回の主役は「入力を読む」タイプです。
サンプルプログラム
ここでは、1〜12の月を読み込んで季節名を表示するプログラムに解説をします。
ポイントはここ:
- read_month は引数なし(void)で、入力チェック付きで月を返す。
- season_of は月から季節文字列を返す(引数ありの関数)
プロジェクト名:chap6-9-1 ソースファイル名:chap6-9-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
// 1〜12の月を読み込んで返す(引数なし)
int read_month(void)
{
int m;
do {
printf("月を入力してください(1〜12):");
scanf("%d", &m);
if (m < 1 || m > 12)
puts("範囲外です。1〜12で入力してください。");
} while (m < 1 || m > 12);
return m;
}
// 月から季節名を返す
const char *season_of(int month)
{
if (month == 12 || month == 1 || month == 2) return "冬";
if (month >= 3 && month <= 5) return "春";
if (month >= 6 && month <= 8) return "夏";
return "秋"; // 9〜11
}
int main(void)
{
int month = read_month();
printf("%d月は%sです。\n", month, season_of(month));
return 0;
}実行例
月を入力してください(1〜12):0
範囲外です。1〜12で入力してください。
月を入力してください(1〜12):13
範囲外です。1〜12で入力してください。
月を入力してください(1〜12):4
4月は春です。引数なし関数は「値を作って返す係」
引数なし関数は、呼び出し側から材料(引数)をもらわない代わりに、
自分で入力を読んで、条件を満たした値を“作って”返します。
read_month の流れ
| ステップ | 動き | 結果 |
|---|---|---|
| 1 | 表示して入力を促す | 例:月を入力してください |
| 2 | scanfで読む | m に入る |
| 3 | 範囲チェック | 1〜12ならOK |
| 4 | OKなら return | 呼び出し元へ月を返す |
| 5 | NGなら繰り返す | もう一度入力へ |
この表は「関数の中で何が起きているか」を段階的に見せるための図解です。
順番が見えると、do-while の役割もスッと入ってきます。
表の説明(この記事で使ったもの)
- 「引数なし関数が動ける理由」表
引数がなくても関数が処理できる理由(入力・乱数・外部状態など)を整理しました。
「引数がない=何もできない」ではなく、「材料の入手経路が違う」だけです。 - 「read_month の流れ」図(表)
入力→チェック→繰り返し→返却、という処理の流れを“手順の列”で表しました。
コードだけだと見落としやすい制御の順番がはっきりします。
登場する命令の書式と「何をする命令か」
ここでは、記事中で出てきた主要なものをまとめます。
(命令や引数は囲みません、という指定に合わせています)
関数定義(引数なし)の書式
- 返却値型 関数名(void) { 処理 }
例
- int read_month(void) { ... }
意味:引数を受け取らないことを明示している、という宣言です。
古いCだと 関数名() でも書けましたが、引数なしを明確にするなら void が安全です。
関数呼び出し(引数なし)の書式
- 関数名()
例
- month = read_month();
意味:実引数を渡さずに関数を実行し、返却値を受け取ります。
do-while の書式
- do { 文 } while (条件);
意味:必ず1回は処理してから条件判定し、真なら繰り返します。
入力チェックと相性がよく、「最低1回は入力してもらう」構造にピッタリです。
scanf の書式
- scanf(書式文字列, 変数のアドレス)
例
- scanf("%d", &m);
意味:キーボードから読んだ値を変数に入れる(入力)ための関数です。
& は「その変数の場所(アドレス)」を渡すために必要になります。
if の書式
- if (条件) 文
- if (条件) 文 else 文
意味:条件によって処理を分岐します。
今回だと「範囲外なら注意してループ継続」に使っています。
return の書式
- return 式;
- return;
意味:関数を終了し、呼び出し元へ戻ります。
read_month は int を返すので return m; の形になります。
(void関数なら return; だけでもOKです)
引数なし関数の“おいしい使い方”:返却値でそのまま初期化
main の先頭でこう書きました。
- int month = read_month();
この形が気持ちいい理由は、「読み込み+チェック」を1行に押し込めて、
main をスッキリさせられるからです。
表:よくある書き方の比較
| 書き方 | mainの見通し | 入力処理の場所 |
|---|---|---|
| month を宣言してから read_month を呼ぶ | ふつう | main と関数に分散 |
| int month = read_month(); | スッキリ | 入力の責務が関数側に集約 |
補足:main の int main(void) の意味
int main(void) は、「main は引数を受け取らない」という意味でもあります。
(コマンドライン引数を扱うなら main の形は変わりますが、今はまず void でOKです)
まとめ:引数なし関数は“入力と検証を肩代わりする部品”
- 呼び出し側は「値を1つ返して」とお願いするだけ
- 関数側で入力チェックや繰り返しを全部引き受ける。
- main が読みやすくなる(これ大事)
