C 言語で関数から構造体を返す

胡金庫 2023年10月12日
  1. 標準記法を使って関数から struct を返す
  2. ポインタ記法を用いて関数から struct を返す
C 言語で関数から構造体を返す

この記事では、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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C Struct