C言語で関数から複数の戻り値を返す【ポインタ、構造体】

543, 2022-08-29

目次

C言語で関数の戻り値を複数にする

C言語で関数の戻り値を複数にしたい
C言語を学んでると自然と起きる発想です。

しかし! C言語では複数の戻り値を返すことはできません。
return文が返す戻り値は常に1つだけです。

ですがポインタや構造体を使うと複数の戻り値を得ることもできます。
この記事ではそれらを使った方法を解説します。

関連記事

ポインタを使った方法

複数の戻り値をreturn文で返せないのならポインタを使って処理結果を取得しよう。
というのがC言語的な発想です。

具体的には↓のようなコードを見てください。

#include <stdio.h>

void calc(int n, int *result1, int *result2) {
    *result1 = n * 2;
    *result2 = n * 4;
}

int main(void) {
    int result1 = 0;
    int result2 = 0;

    calc(2, &result1, &result2);

    printf("result1: %d\n", result1);  // result1: 4
    printf("result2: %d\n", result2);  // result2: 8
    return 0;
}

↑のcalc()という関数が問題の関数です。
この関数は第1引数のnを2倍、4倍にします。
そしてそのそれぞれの結果を関数の呼び出し側で取得したいわけです。

こういう時は関数の引数にポインタを渡します。
そしてそのポインタに対して処理結果を保存します。
こうすると複数の処理結果を複数のポインタに保存できます。

calc()を呼び出した後のresult14になり、result28になります。

このポインタを使った複数の結果の取得方法はC言語では一番お手軽な方法です。
構造体を定義する必要もなくポインタを使うだけで実現できます。
ですのでこの方法は記憶しておくと捗るでしょう。

構造体を使った方法

他には構造体を使った方法もあります。
関数の処理結果用の構造体を定義しておいて、関数ではその構造体を返すようにします。

#include <stdio.h>

struct Result {
    int nibai;
    int yonbai;
};

struct Result calc(int n) {
    return (struct Result) {
        n * 2,
        n * 4,
    };
}

int main(void) {
    struct Result result = calc(2);

    printf("nibai: %d\n", result.nibai);  // nibai: 4
    printf("yonbai: %d\n", result.yonbai);  // yonbai: 8

    return 0;
}

↑のコードでは問題の関数はcalc()です。
この関数はResult構造体を結果として返します。
Result構造体はcalc()用の構造体で、結果を格納するのに使います。
calc()内ではResult構造体のメンバにそれぞれ計算結果を保存しています。

calc()を呼び出すとResultが返ってきますのでこれを受け取ります。
そしてあとは構造体のメンバであるnibaiyonbaiを参照します。

この方法は美しいですが、汎用性はポインタほどは高くありません。
まず構造体の定義が関数ごとに必要になってしまう、というのがあげられます。
関数ごとに専用の構造体を定義するというのも大変な話です。
しかし一回定義してしまえばあとはその構造体を使えばいいだけなので、ある意味楽かもしれません。

他には汎用性のある構造体をいくつか定義しておいてそれを使いまわすという方法も考えられます。
たとえばTupleIIという構造体を作っておけばcalc()のような関数には対応できます。
double型の結果が欲しい場合はTupleDDという構造体を作っておきます。

typedef struct {
    int first;
    int second;
} TupleII;

typedef struct {
    double first;
    double second;
} TupleDD;

TupleII calc(int n) {
    TupleII result = { n * 2, n * 4 };
    return result;
}

C++などの言語ではこのようなケースではstd::tuple()などが使えます。

おわりに

今回はC言語の関数で複数の戻り値を返す方法を解説しました。
C言語では工夫をすれば複数の結果を取得することも可能です。

(^ _ ^)

C言語は工夫しがいのある言語

(・ v ・)

魔改造して使おう



この記事のアンケートを送信する