C 言語で関数から構造体を返す
胡金庫
2023年10月12日
この記事では、C 言語の関数から struct
を返す方法について複数のメソッドを示します。
標準記法を使って関数から struct
を返す
C 言語の struct
キーワードは、ユーザ定義のデータ構造を実装するために使われます。この例では struct
型を定義しているので、MyStruct
構造体を typedef
した方が、関数宣言の際の記法がすっきりします。これにより、与えられた構造体の新しい型のエイリアスが関連付けられるので、関数プロトタイプでは新しいエイリアス名だけを指定する必要があります。これで、C 言語の関数は組み込みのデータ型と同様に struct
を返すことができるようになりました。
以下の例では、MyStruct
オブジェクトへのポインタを受け取り、同じオブジェクトを値で返す clearMyStruct
関数を実装しています。ハンドルが struct
へのポインタである場合、struct
のメンバに ->
演算子を使ってアクセスする必要があることに注意してください。
#include <stdio.h>
#include <stdlib.h>
enum { DAY = 9, MONTH = 2 };
typedef struct {
int day;
int month;
} MyStruct;
MyStruct clearMyStruct(MyStruct *st) {
st->day = 0;
st->month = 0;
return *st;
}
int setMyStruct(MyStruct *st, int d, int m) {
if (!st) return -1;
st->day = d;
st->month = m;
return 0;
}
int main() {
MyStruct tmp;
if (setMyStruct(&tmp, DAY, MONTH) == -1) exit(EXIT_FAILURE);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
clearMyStruct(&tmp);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
exit(EXIT_SUCCESS);
}
出力:
day: 9
month: 2
day: 0
month: 0
ポインタ記法を用いて関数から struct
を返す
一般的に、struct
で定義されたデータ構造体は複数のデータメンバを含む傾向があり、結果として大きなメモリフットプリントが発生します。さて、関数間で比較的大きな構造体を渡す場合は、ポインタを使うのがベストです。ポインタはオブジェクトのハンドルとして機能し、そのサイズはそこに格納されている構造体に関係なく固定されます。ポインタを使って struct
を返すことで、メモリトラフィックを削減し、コードのパフォーマンスを向上させることができます。プログラムは最適化フラグでコンパイルされていますが、データを渡す命令を暗黙的に変更することがあります。名前付き定数整数値を宣言するために enum
型を利用していることに注意してください。
#include <stdio.h>
#include <stdlib.h>
enum { DAY = 9, MONTH = 2 };
typedef struct {
int day;
int month;
} MyStruct;
MyStruct *clearMyStruct2(MyStruct *st) {
st->day = 0;
st->month = 0;
return st;
}
int setMyStruct(MyStruct *st, int d, int m) {
if (!st) return -1;
st->day = d;
st->month = m;
return 0;
}
int main() {
MyStruct tmp;
if (setMyStruct(&tmp, DAY, MONTH) == -1) exit(EXIT_FAILURE);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
clearMyStruct2(&tmp);
printf("day: %d\nmonth: %d\n", tmp.day, tmp.month);
exit(EXIT_SUCCESS);
}
出力:
day: 9
month: 2
day: 0
month: 0
著者: 胡金庫