C言語入門|関数を呼び出して使う

前の記事では、
「関数を作るには、まず定義が必要」
という話をしました。

でも、ここでひとつ大事なことがあります。

関数は、作っただけでは動きません。

関数は、
呼び出されてはじめて実行される
ものです。

ここでは、
作った関数をどうやって使うのか、
つまり 関数の呼び出し について見ていきましょう。

関数を使う=関数を呼び出す

関数を利用することを、
関数の呼び出し と呼びます。

引数も戻り値も使わない
シンプルな関数であれば、
呼び出し方はとても簡単です。

関数の呼び出しの基本形

関数名();

これだけです。

カッコの中が空なのは、
「この関数は引数を受け取らない」
という意味でしたね。

シンプルな関数を呼び出してみよう

では、実際のコードで確認してみましょう。
次のプログラムでは、
挨拶を表示する関数を呼び出しています。

プロジェクト名:8-3-1 ソースファイル名: sample8-3-1.c

#include <stdio.h>

void greet(void)
{
    printf("おはようございます\n");
}

int main(void)
{
    printf("関数を呼び出します\n");
    greet();   // greet関数を呼び出す
    printf("関数の呼び出しが終わりました\n");

    return 0;
}

このプログラムには、

  • greet 関数
  • main 関数

の2つの関数が定義されています。

プログラムは必ず main 関数から始まる

ここで、C言語の重要なルールを思い出しましょう。

C言語のプログラムは、必ず main 関数から実行が始まります。

たとえ他にどんな関数が定義されていても、

  • 最初に動くのは main 関数
  • その中で必要な関数を呼び出す

という流れになります。

そのため、先ほどのコードも、

  1. main 関数が実行される
  2. greet(); に到達する
  3. greet 関数の処理が実行される
  4. greet が終わったら main に戻る

という順番で動きます。

関数の実行結果を追ってみよう

先ほどのプログラムを実行すると、
画面には次のように表示されます。

関数を呼び出します
おはようございます
関数の呼び出しが終わりました

この結果からも分かるように、

  • greet 関数は
    呼び出されたその場で実行され
  • 処理が終わると
    元の場所に戻ってくる

という動きをしています。

関数は定義しただけでは動かない

とても大事なポイントを、
もう一度確認しておきましょう。

関数は、定義しただけでは実行されません。

もし、

greet();

この1行を削除したら、
「おはようございます」は表示されなくなります。

関数は、

  • 定義する
  • 呼び出す

この2つがそろって、
はじめて意味を持つのです。

関数呼び出しの流れ

関数の呼び出しは、
次のような流れで実行されます。

  1. main 関数の処理が進む
  2. 関数呼び出しに出会う
  3. 呼び出された関数に処理が移る
  4. 関数の処理が終わる
  5. 呼び出した元の場所に戻る

この「行って、戻ってくる」
という動きを、
頭の中でイメージできるようになると、
関数の理解が一気に進みます。

関数には2つの立場がある

ここで、とても大切な考え方を紹介します。

関数には、
2つの立場 があります。

立場何をする人?
定義する立場関数を作る人
呼び出す立場関数を使う人

今回の例では、
どちらも自分ひとりで書いていますが、
考え方としては別人 として捉えるのがポイントです。

大規模開発では役割が完全に分かれる

実際の業務システムやゲーム開発では、

  • 関数を定義する人
  • 関数を呼び出して使う人

が、まったく別の人であることも珍しくありません。

だからこそ、

  • 関数を定義する人は
    呼び出す人のことを考えて作る
  • 呼び出す人は
    中身を知らなくても使える

という関係が、とても重要になります。

関数名は「呼び出す人」へのメッセージ

ここで、次のコードを見てみてください。

int main(void)
{
    greet();
    saveResult();
    aaa();
}

greet や saveResult は、
「何をしている関数か」
なんとなく想像できますね。

でも、aaa はどうでしょう?

「これ、何をする関数?」
と、首をかしげてしまいます。

関数名はチーム全体に影響する

関数名は、

  • 定義する人だけのもの
    ではありません。

呼び出す人全員が読むもの です。

分かりにくい関数名は、

  • 読みにくいコード
  • 修正しにくいコード
  • ミスを生みやすいコード

へと、少しずつ悪影響を広げていきます。

関数定義の1行目はとても重要

関数定義は、必ず次の2つの部分から成り立っています。

void greet(void)    // ① 重要事項の表明
{
    printf("おはようございます\n");  // ② 処理内容
}

このうち、
特に重要なのが1行目 です。

関数定義の1行目は「接点」

関数定義の1行目には、

  • 関数名
  • 引数の形
  • 戻り値の有無

といった、
呼び出す人にとって必要な情報 がすべて書かれています。

つまりここは、

  • 定義する人
  • 呼び出す人

2つの立場の接点 なのです。

中身は定義する人だけが気にすればいい

一方で、
関数ブロックの中身は、

  • 定義する人だけが理解していればOK

です。

呼び出す人は、

  • 正しい名前で
  • 正しい形で

呼び出しさえすれば、
「きちんと仕事をしてくれる」
と信頼して関数を使います。

まとめ:関数呼び出しは人との約束

この節のポイントをまとめます。

  • 関数は呼び出されてはじめて動く。
  • プログラムは必ず main 関数から始まる。
  • 関数には定義する立場と呼び出す立場がある。
  • 関数定義の1行目は、人と人との接点

関数呼び出しは、
単なる文法ではありません。

「この名前で呼んでくれたら、この処理をするよ」
という、人との約束なのです。

この感覚を大切にしながら、
次は 引数や戻り値を持つ関数 に進んでいきましょう 😊