void関数
返す値がない関数
最初に書いた show_line を思い出してください。線を1本出すだけなのに、戻り値の型を int と書いたせいで、意味のない return 0; を付ける羽目になっていました。呼び出し側もその 0 を毎回捨てています。
こういう「やることはやるが、返す値はない」関数のために、C には void という型が用意されています。
void show_line(void) {
printf("------------------------------\n");
}戻り値の型を void にすると、return を書く必要がなくなります。本体の最後まで実行したら、そのまま呼び出し元に戻ります。
void は「空」という意味の型で、値がひとつも入らない型だと思ってください。引数リストの (void) も同じ単語ですが、こちらは「受け取る値がない」ことを表しています。同じ関数の1行目に2回出てくるので混乱しやすいのですが、左の void は返さない、カッコの中の void は受け取らない と場所で区別できます。
値は返さないが引数は受け取れる
引数と戻り値は別の話なので、値を受け取って表示だけする関数も書けます。
void show_result(int no, int score) {
printf("%d人目 %d点 ", no, score);
if (score >= 60) {
printf("合格\n");
} else {
printf("不合格\n");
}
}受け取った点数から合否まで判定して、画面に出して終わりです。返す値はありません。main 側は次のように呼びます。
show_result(1, 80);void 関数でやってはいけないこと
返す値がないので、呼び出しを値として使えません。
int x = show_line(); /* エラー。void は値を持たない */また、return 80; のように値を付けた return も書けません。ただし 値なしの return; は書けます。分岐で途中打ち切りをしたいときに使います。
void show_result(int no, int score) {
if (score < 0) {
printf("%d人目 データなし\n", no);
return;
}
printf("%d人目 %d点\n", no, score);
}return; に来たらそこで関数が終わるので、下の行は実行されません。
使い分けの目安
計算した結果を呼び出し元が使うなら戻り値のある関数、画面に出して終わりなら void 関数、という分け方が素直です。表示と計算を1つの関数に混ぜると、あとで「画面には出さずに値だけ欲しい」となったときに困ります。この章の最後のつくる回では、まさにこの分け方でプログラムを組み直します。
では、区切り線と1人分の表示を、どちらも void 関数にしてみましょう。
要件
- show_line は引数も戻り値もない void 関数にする。ハイフン30個の行を表示する
- show_result は番号と点数を受け取る void 関数にする。戻り値はない
- show_result は 1人目 80点 合格 の形で1行表示する。60点以上を合格、それ未満を不合格とする
- for 文で3人分の点数を scanf で読み込み、読むたびに show_result を呼ぶ
- 一覧の前後に show_line を1回ずつ呼ぶ
入出力例
main("80 55 90") → "------------------------------
1人目 80点 合格
2人目 55点 不合格
3人目 90点 合格
------------------------------"
main(60, 59, 100) → "------------------------------
1人目 60点 合格
2人目 59点 不合格
3人目 100点 合格
------------------------------"