コンテンツにスキップ

C言語/return

出典: フリー教科書『ウィキブックス(Wikibooks)』

return 文の理解と活用

[編集]

return 文の基本概念

[編集]

C言語における return 文は、関数の実行を終了し、呼び出し元に値を返すための制御構文です。return 文は以下の形式で使用されます。

return [];

なお、void 型の関数では式を省略することができます。

return;  // void 型関数での使用例

シンプルな return 文の例を見てみましょう。

#include <stdio.h>
int add(int a, int b) {
    int sum = a + b;
    return sum;  // 計算結果を呼び出し元に返す
}

int main() {
    int result = add(5, 3);
    printf("5 + 3 = %d\n", result);  // "5 + 3 = 8" と表示
    return 0;  // プログラムの正常終了を意味する
}

この例では、add 関数が計算結果を return 文で返し、main 関数がその値を受け取って表示しています。main 関数の最後の return 0 は、プログラムが正常に終了したことをオペレーティングシステムに伝えます。

return 文の役割と重要性

[編集]

return 文は関数プログラミングの中核要素であり、以下のような重要な役割を担っています。

役割 説明
値の返却 関数の計算結果や状態を呼び出し元に返す
関数の終了 関数の実行を即座に終了させる
条件付き終了 特定条件を満たした場合に関数を早期終了させる
エラー処理 エラー状態を検出した際に関数を終了し、エラーコードを返す
プログラム終了 main 関数での return は、プログラム全体の終了ステータスを指定する

return 文の実践的な使用例

[編集]

条件による早期リターン

[編集]

早期リターンパターンは、条件チェックをネストさせずに関数の始めに行うことで、コードの可読性を高める手法です。

#include <stdio.h>
int divide(int a, int b) {
    // エラーチェックを最初に行い、早期リターン
    if (b == 0) {
        printf("エラー: ゼロ除算\n");
        return -1;  // エラーコードを返す
    }
    
    // 正常処理
    return a / b;
}

int main() {
    printf("10 / 2 = %d\n", divide(10, 2));  // "10 / 2 = 5" と表示
    printf("10 / 0 = %d\n", divide(10, 0));  // "エラー: ゼロ除算" と表示後、"-1" を表示
    return 0;
}

この例では、ゼロ除算を防ぐためのチェックを最初に行い、問題があれば即座に関数を終了しています。

再帰関数での基底条件

[編集]

再帰関数では、return 文が再帰の終了条件(基底条件)を定義する重要な役割を担います。

#include <stdio.h>
// 階乗を計算する再帰関数
int factorial(int n) {
    // 基底条件: 0! = 1
    if (n == 0) {
        return 1;
    }
    
    // 再帰的な計算
    return n * factorial(n - 1);
}

int main() {
    printf("5! = %d\n", factorial(5));  // "5! = 120" と表示
    return 0;
}

この例では、n が 0 に達したときに再帰が終了するよう return 1 を使用しています。

複数の値を返す工夫

[編集]

C言語では関数は基本的に一つの値しか返せませんが、ポインタを使用して複数の値を間接的に返すことができます。

#include <stdio.h>
// 整数の割り算を行い、商と余りを返す
void divide_with_remainder(int dividend, int divisor, int *quotient, int *remainder) {
    if (divisor == 0) {
        return;  // エラー時は何も変更せずに返る
    }
    
    *quotient = dividend / divisor;
    *remainder = dividend % divisor;
    return;  // void 関数での return
}

int main() {
    int a = 17, b = 5;
    int quot, rem;
    
    divide_with_remainder(a, b, &quot, &rem);
    printf("%d ÷ %d = %d 余り %d\n", a, b, quot, rem);  // "17 ÷ 5 = 3 余り 2" と表示
    
    return 0;
}

この例では、商と余りの結果をポインタを通じて外部変数に格納することで、実質的に複数の値を返しています。

関数ポインタの返却

[編集]

C言語では、関数ポインタを返すことも可能です。これはコールバック関数や動的な関数選択に役立ちます。

#include <stdio.h>
// 演算関数のプロトタイプ
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);

// 関数ポインタの型定義
typedef int (*Operation)(int, int);

// 演算子に基づいて適切な関数ポインタを返す
Operation get_operation(char op) {
    switch(op) {
        case '+': return add;
        case '-': return subtract;
        case '*': return multiply;
        case '/': return divide;
        default:  return NULL;
    }
}

// 演算関数の実装
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }

int main() {
    int a = 10, b = 5;
    char operators[] = {'+', '-', '*', '/'};
    
    for (int i = 0; i < 4; i++) {
        Operation op = get_operation(operators[i]);
        if (op != NULL) {
            printf("%d %c %d = %d\n", a, operators[i], b, op(a, b));
        }
    }
    
    return 0;
}

この例では、get_operation 関数が演算子に基づいて適切な関数ポインタを返し、main 関数がそれを使用して計算を行っています。

return 文と main 関数

[編集]

main 関数は特別な関数であり、その return 値はプログラムの終了ステータスとしてオペレーティングシステムに渡されます。

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("使用法: %s <引数>\n", argv[0]);
        return EXIT_FAILURE;  // プログラムの異常終了を意味する
    }
    
    printf("引数: %s\n", argv[1]);
    return EXIT_SUCCESS;  // プログラムの正常終了を意味する
}

この例では、コマンドライン引数が不足している場合に EXIT_FAILURE を返してプログラムを終了します。これにより、シェルスクリプトなどでプログラムの実行結果を確認することができます。

return 文と制御フロー

[編集]

return 文は関数内のどこからでも使用でき、即座に関数の実行を終了させます。

#include <stdio.h>
void process_value(int value) {
    if (value < 0) {
        printf("負の値: %d\n", value);
        return;  // 負の値の場合は処理を終了
    }
    
    printf("値を処理します: %d\n", value);
    
    if (value > 100) {
        printf("値が大きすぎます\n");
        return;  // 大きすぎる値の場合も処理を終了
    }
    
    printf("処理が完了しました\n");
    return;  // 明示的な終了(省略可能)
}

int main() {
    process_value(-5);  // "負の値: -5" のみ表示
    process_value(50);  // 全ての処理を実行
    process_value(150); // "値を処理します: 150" と "値が大きすぎます" を表示
    
    return 0;
}

この例では、条件に応じて関数の実行を早期に終了させる方法を示しています。

結論

[編集]

return 文は C 言語において関数からの値の返却と実行フローの制御の両方に重要な役割を果たします。関数の結果を呼び出し元に伝えるだけでなく、条件に応じた早期終了、エラー処理、再帰関数の基底条件など、多くの場面で活用されます。適切に return 文を使用することで、効率的で読みやすいコードを書くことができます。特に早期リターンパターンは、複雑な条件分岐を平坦化し、コードの可読性を高める重要なテクニックです。また、main 関数の return 値は、プログラム全体の終了ステータスを表現する重要な役割も担っています。