🧩 関数とスコープ
🎯 関数の役割と基本の書き方が分かり、自分で作った関数を呼び出せる
朝の支度を人に説明するとき、「歯ブラシを取って、水を出して、みがいて、口をすすいで……」と毎回すべてを言う人はいません。ふつうは「歯をみがく」の一言で済ませます。手順のかたまりに名前を付けたからです。
プログラムでも同じことをします。処理のかたまりに名前を付けて、いつでも呼び出せる部品にしたもの。それが関数です。ここまで毎回書いてきた main も、実は関数のひとつでした。
基本の形
戻り値の型 関数名(引数リスト)
{
処理;
}いちばん簡単なのは、値を受け取らず、値も返さない関数です。
#include <stdio.h>
// 区切り線を表示するだけの関数
void print_line(void)
{
printf("--------------------\n");
}
int main(void)
{
print_line();
printf(" 本日の売上\n");
print_line();
return 0;
}実行すると、区切り線・見出し・区切り線の3行が表示されます。print_line(); と書いた場所でいったん関数の中身に飛び、終わったら元の場所に戻ってくる。これが呼び出しです。
実行の順番に注意
「ソースコードは上から下へ実行される」という思い込みは、ここで一度捨ててください。print_line の中身はファイルの上のほうに書かれていますが、それが動くのは main の中で呼ばれた瞬間です。定義は「置いてあるだけ」で、呼ばれるまで一度も実行されません。プログラムの実行はいつも main から始まり、呼び出しのたびに行ったり来たりします。
なぜ部品にするのか
理由は3つあります。ひとつめ、同じ処理を何度も書かずに済むこと。ふたつめ、print_line という名前そのものが説明になり、main を上から読むだけで流れが分かること。みっつめ、直すときに1か所だけ直せばよいこと。区切り線を - から = に変えたくなっても、関数の中の1行を書き換えるだけで、呼び出しているすべての場所に反映されます。
名前の付け方にもコツがあります。関数は「何かをする」ものなので、print_line count_words のように動詞から始めると、読んだ瞬間に役割が伝わります。
罠・注意
void が2か所に出てきますが、意味は別々です。前の void は「返す値はない」、カッコの中の void は「受け取る値はない」。C23では print_line() と空カッコにしても「引数なし」の意味になりますが、意図がはっきりする (void) を書いておくのが無難です。
} の後ろにセミコロンは要りません。}; は構造体と混同しやすい癖です。() を忘れると実行されません。print_line; は「その関数を指し示すだけ」で、何も起きないまま素通りします。printf のような名前は避けます。まとめ: 関数は「名前の付いた処理のかたまり」。作って、呼ぶ。たったこれだけで、長いプログラムが読める大きさに分かれていきます。
一連の処理に名前を付けてひとまとめにしたもののこと。同じ処理を何度も書かずに、名前を呼ぶだけで再利用できる部品にあたる。printfやscanfも、標準ライブラリがあらかじめ用意してくれている関数の一種。
もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。