Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

構造体の初期化に於いて、暗黙の初期値を指定する方法

More than 3 years have passed since last update.

C言語において構造体の初期化を行うときには、定数式を並べる方法と、要素指示子を用いて初期値を指定する方法があります。要素指示子を用いた場合、メンバの識別子順とは順不同に初期値を記述することが出来、これはC++には存在しないC言語特有の構文となります。

struct st_id {
    int a, b, c;
};

struct st_id v = { 1, 2, 3 };
    // v.a = 1, v.b = 2, v.c = 3
struct st_id w = { .c=1, .b=2, .a=3 };
    // w.a = 3, w.b = 2, w.c = 1

これら2つの初期化方法は組み合わせて用いることが出来、要素指示子での初期化は、以前の初期化子を書き換えることができます。

struct st_id x = { 1, 1, 1, .a = 2 };
    // x.a = 2, x.b = 1, x.c = 1

この初期化方法はC言語の仕様として定義されており、C99のJIS規格「JISX3010-2003 プログラム言語C」1にて下記の通り記載されています。

6.7.8 初期化
<中略>
初期化は,初期化子並びの順に行う。特定の部分オブジェクトに対する初期化子が,同じ部分オブジェクトに対する以前の初期化子を書き換えることもある。

この初期化方法を使えば、構造体の初期化において、初期化指定されないメンバは通常ゼロ初期化されるところを、任意の初期値を指示することが出来ます。
例えば、関数マクロの可変長引数を使って下記の様に定義すれば、デフォルト初期値を持つ構造体宣言を行うマクロを定義できます。

#define MAKE_ST_ID(name, ...)   \
    struct st_id name = { -1, -1, -1, __VA_ARGS__ }

MAKE_ST_ID(y, .c = 0, .a = 3);
    // y.a = 3, y.b = -1, y.c = 0

  1. JISCのサイトより"JISX3010"と検索することで閲覧が可能。 

rai_suta
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away