トラック7・🧩関数とスコープ

関数とは——処理に名前を付ける

読む目安 約10分・ゴール:関数の役割と基本の書き方が分かり、自分で作った関数を呼び出せる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

朝の支度を人に説明するとき、「歯ブラシを取って、水を出して、みがいて、口をすすいで……」と毎回すべてを言う人はいません。ふつうは「歯をみがく」の一言で済ませます。手順のかたまりに名前を付けたからです。

プログラムでも同じことをします。処理のかたまりに名前を付けて、いつでも呼び出せる部品にしたもの。それが関数です。ここまで毎回書いてきた 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) を書いておくのが無難です。

ビット同じ処理を2回以上書きそうになったら、関数にするサインだよ

まとめ: 関数は「名前の付いた処理のかたまり」。作って、呼ぶ。たったこれだけで、長いプログラムが読める大きさに分かれていきます。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

void print_line(void) のうち、カッコの中に書かれた void の意味はどれですか。

  1. この関数は引数を受け取らない
  2. この関数は値を返さない
  3. この関数は何も表示しない
  4. この関数は1回しか呼べない
答えを見る

正解:A(この関数は引数を受け取らない)

前の void は「戻り値なし」、カッコの中の void は「引数なし」を表します。位置によって意味が変わるので、2つの void を混同しないようにしましょう。C23では空カッコでも引数なしの意味になりますが、(void) と書くほうが意図が明確です。

確認問題 2

Cの関数について、正しい説明はどれですか。

  1. 関数の中に別の関数を定義できる
  2. main も関数のひとつである
  3. 関数定義の閉じカッコの後ろにはセミコロンが必要
  4. 関数は1つのプログラムに1つしか作れない
答えを見る

正解:B(main も関数のひとつである)

main も戻り値 int の関数です。Cでは関数の入れ子定義はできず、定義の閉じ } の後ろにセミコロンは要りません。関数はいくつでも作れます。

「関数とスコープ」の目次

  1. 関数とは——処理に名前を付ける
  2. 引数と戻り値
  3. プロトタイプ宣言
  4. 変数のスコープ——見える範囲
  5. 変数の寿命とstatic
  6. コールスタック——関数呼び出しの舞台裏
  7. 値渡しの本質
  8. グローバル変数との付き合い方
  9. 関数分割の設計センス
  10. 再帰の入口——自分を呼ぶ関数

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版