C言語基礎|関数の再利用

部品を“使い回す”と、強くて読みやすいコードになる

ここまでで、自分で関数を作って呼び出せるようになりました。次のステップは 関数の中から、別の自作関数を呼ぶ ことです。

これができると何が嬉しいかというと、

  • 同じ処理を何回も書かなくて済む(重複が減る)
  • バグが減る(直す場所が1か所)
  • 意味が見えやすい(名前で意図が伝わる)

つまり、関数を“部品”として組み立てられるようになります。

関数の再利用って何?

関数の再利用とは、すでに作った便利な関数を、別の関数や別の場面でそのまま使うことです。
「もう作った部品があるなら、それを使って新しい部品を作ろう」という感じですね。

再利用で得られるメリット

うれしいこと具体的にどうなる?
重複が減る同じ計算をあちこちに書かない。
修正がラク直すのは関数1か所だけで済む。
読みやすい処理の意味が関数名で伝わる。
テストしやすい小さな関数を個別に確認できる。

サンプルプログラム

2つの整数の差(絶対値)を作る関数を部品として、
3つの整数の“幅”(最大値−最小値)を求める関数を作ってみます。

  • min2:2つの小さいほうを返す(部品)
  • max2:2つの大きいほうを返す(部品)
  • range3:3つの値の範囲(最大−最小)を返す(再利用の完成品)

プログラム例

プロジェクト名:chap6-5-1 ソースファイル名:chap6-5-1.c

Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。

#include <stdio.h>

// 2つの整数の大きいほうを返す
int max2(int a, int b)
{
    return a > b ? a : b;
}

// 2つの整数の小さいほうを返す
int min2(int a, int b)
{
    return a < b ? a : b;
}

// 3つの整数の範囲(最大値−最小値)を返す
int range3(int a, int b, int c)
{
    int mx = max2(max2(a, b), c);
    int mn = min2(min2(a, b), c);
    return mx - mn;
}

int main(void)
{
    int x, y, z;

    puts("3つの整数を入力してください。最大と最小の差を求めます。");
    printf("1つ目:");
    scanf("%d", &x);
    printf("2つ目:");
    scanf("%d", &y);
    printf("3つ目:");
    scanf("%d", &z);

    printf("最大と最小の差は %d です。\n", range3(x, y, z));

    return 0;
}

実行例

3つの整数を入力してください。最大と最小の差を求めます。
1つ目:12
2つ目:-3
3つ目:7
最大と最小の差は 15 です。

どう再利用しているか

range3 の中身は、「最大値を求める」「最小値を求める」を部品で作っています。

部品の組み立て(イメージ)

関数役割中で呼び出す関数
max22つの大きいほうなし
min22つの小さいほうなし
range33つの最大−最小max2 と min2 を再利用

この構造ができると、例えば「4つの範囲」「5つの範囲」も、同じ発想で広げられます。

登場する命令・書式と役割(ちゃんと整理)

関数定義の書式

関数は次の形で定義します。

  • 返却値型 関数名(仮引数並び) { 処理 }

例:

  • int max2(int a, int b) { ... }

今回出てくる命令・演算子

名前書式何をする?
関数呼出し関数名(実引数...)関数を実行して返却値を得る
return文return 式;関数を終了し、値を呼び出し元へ返す
条件演算子条件 ? 式1 : 式2条件で値を選ぶ(短く書ける)
scanfscanf(書式, アドレス...)入力を変数に読み込む
printfprintf(書式, 値...)値を表示する
putsputs(文字列)文字列を表示して改行する

表の説明(この記事で使った意味)

  • メリット表:再利用すると何が得かを、最初に迷わず掴むため
  • 部品の組み立て表:range3 が「max2 と min2 の合成」でできているのを見える化するため
  • 命令・演算子表:関数呼出し、return、条件演算子の役割を整理して読み戻しやすくするため

演習問題

演習6-4:4乗値を返す関数 pow4 を作ろう(関数を再利用すること)

int 型整数の 4 乗値を返す関数 pow4 を作成せよ。
関数の内部で、2乗を返す関数 sqr を呼び出すこと。

関数プロトタイプ:
int pow4(int x);

解答例

プロジェクト名:chap6-5-2 ソースファイル名:chap6-5-2.c

Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。

#include <stdio.h>

int sqr(int n)
{
    return n * n;
}

int pow4(int x)
{
    return sqr(sqr(x));
}

int main(void)
{
    int n;

    puts("整数を入力してください。4乗を表示します。");
    printf("整数:");
    scanf("%d", &n);

    printf("4乗は %d です。\n", pow4(n));

    return 0;
}

解説

  • sqr(x) で 2乗が作れる。
  • それをもう一回 sqr に渡せば (x²)² なので x⁴ になる。
  • pow4 の中で sqr を再利用しているので、計算式が短く、意味も読み取りやすいです。