home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

C言語系/memos/構造体の初期化, enumリストの末尾カンマ関連 (v1)

C言語系/memos/構造体の初期化, enumリストの末尾カンマ関連 (v1)

C言語系 / memos / 構造体の初期化, enumリストの末尾カンマ関連 (v1)
id: 880 所有者: msakamoto-sf    作成日: 2010-12-23 16:35:17
カテゴリ: C言語 

構造体の初期化, enumリストの末尾カンマ関連のメモ集。
C99で追加された機能が含まれているため、GCCでは使えるがVC++で使えなかったりする。(VC++2010時点でC99未対応)

参考:

構造体の初期化その1

VC++2008, GCC4 の両方で使用可能。

struct01.c:

#include <stdio.h>
 
typedef struct {
    int foo;
    int bar;
    struct {
        int f1;
        int f2;
    } baz;
    int abc;
} st01;
 
int main(int argc, char *argv[])
{
    st01 v = {
        100,
        200,
        {
            300,
            400,
        },
        500,      /* GCC4/VC++2008の両方で末尾カンマに対応している */
    };
 
    printf("foo = %d\n", v.foo);
    printf("bar = %d\n", v.bar);
    printf("baz.f1 = %d\n", v.baz.f1);
    printf("baz.f2 = %d\n", v.baz.f2);
    printf("abc = %d\n", v.abc);
 
    return 0;
}

実行結果:

foo = 100
bar = 200
baz.f1 = 300
baz.f2 = 400
abc = 500

構造体の初期化その2 : 複合リテラル (Compound Literal)

C99に対応しているGCC4で使用可能。VC++2008ではC99未対応につき使用不可

見た目はキャスト演算子に似ている。関数呼び出し時にも使えるので便利。

ex:
foo( (struct bar) { 100, 200, ... } );

struct02.c:

#include <stdio.h>
 
typedef struct {
    int foo;
    int bar;
    struct {
        int f1;
        int f2;
    } baz;
    int abc;
} st01;
 
int main(int argc, char *argv[])
{
    st01 v = (st01){
        100,
        200,
        {
            300,
            400,
        },
        500,
    };
 
    printf("foo = %d\n", v.foo);
    printf("bar = %d\n", v.bar);
    printf("baz.f1 = %d\n", v.baz.f1);
    printf("baz.f2 = %d\n", v.baz.f2);
    printf("abc = %d\n", v.abc);
 
    return 0;
}

実行結果:struct01と同じ。

構造体の初期化その3 : 指示付きの初期化子 (Designated Initializer)

C99に対応しているGCC4で使用可能。VC++2008ではC99未対応につき使用不可

可読性向上に加え、一部のフィールドだけ特定の値で初期化したい場合にも使える。

struct03.c:

#include <stdio.h>
 
typedef struct {
    int foo;
    int bar;
    struct {
        int f1;
        int f2;
    } baz;
    int abc;
} st01;
 
int main(int argc, char *argv[])
{
    st01 v = {
        .foo = 100,
/*      .bar = 200, */
        .baz = {
            .f1 = 300,
            .f2 = 400,
        },
/*      .abc = 500, */
    };
 
    printf("foo = %d\n", v.foo);
    printf("bar = %d\n", v.bar);
    printf("baz.f1 = %d\n", v.baz.f1);
    printf("baz.f2 = %d\n", v.baz.f2);
    printf("abc = %d\n", v.abc);
 
    return 0;
}

実行結果:

foo = 100
bar = 0        # 未指定フィールド
baz.f1 = 300
baz.f2 = 400
abc = 0        # 未指定フィールド

enumリストの末尾カンマ(trailing comma)

C99に対応しているGCC4で使用可能。VC++2008ではC99未対応だが使用可能。

enum01.c:

#include <stdio.h>
 
enum t01 {
    DEF01_1,
    DEF01_2,
    DEF01_3,
};
 
enum t02 {
    DEF02_1 = 0,
    DEF02_2,
    DEF02_3,
} v2;
 
typedef enum {
    DEF03_1 = 0,
    DEF03_2,
    DEF03_3 = 5,
    DEF03_4,
    DEF03_5 = 0,
    DEF03_6
} t03;
 
int main(int argc, char *argv[])
{
    enum t01 v1;
    t03 v3;
 
    printf("t01 : DEF01_1 = %d\n", v1 = DEF01_1);
    printf("t01 : DEF01_2 = %d\n", v1 = DEF01_2);
    printf("t01 : DEF01_3 = %d\n", v1 = DEF01_3);
 
    printf("t02 : DEF02_1 = %d\n", v2 = DEF02_1);
    printf("t02 : DEF02_2 = %d\n", v2 = DEF02_2);
    printf("t02 : DEF02_3 = %d\n", v2 = DEF02_3);
 
    printf("t03 : DEF03_1 = %d\n", v3 = DEF03_1);
    printf("t03 : DEF03_2 = %d\n", v3 = DEF03_2);
    printf("t03 : DEF03_3 = %d\n", v3 = DEF03_3);
    printf("t03 : DEF03_4 = %d\n", v3 = DEF03_4);
    printf("t03 : DEF03_5 = %d\n", v3 = DEF03_5);
    printf("t03 : DEF03_6 = %d\n", v3 = DEF03_6);
 
    return 0;
}

実行結果:

t01 : DEF01_1 = 0
t01 : DEF01_2 = 1
t01 : DEF01_3 = 2
t02 : DEF02_1 = 0
t02 : DEF02_2 = 1
t02 : DEF02_3 = 2
t03 : DEF03_1 = 0
t03 : DEF03_2 = 1
t03 : DEF03_3 = 5
t03 : DEF03_4 = 6
t03 : DEF03_5 = 0
t03 : DEF03_6 = 1


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2010-12-23 16:36:38
md5:bd6552283ea38490251af4d47ececdc3
sha1:f696dcd025e4fafdbcef531d2d8b8192c271dd63
コメント
コメントを投稿するにはログインして下さい。