#navi_header|C言語系| 構造体の初期化, enumリストの末尾カンマ関連のメモ集。 C99で追加された機能が含まれているため、GCCでは使えるがVC++で使えなかったりする。(VC++2010時点でC99未対応) #more|| 参考: - C言語で構造体を初期化する方法 - 揮発性のメモ -- http://d.hatena.ne.jp/iww/20090424/struct - How to initialize a struct in ANSI C? - Stack Overflow -- http://stackoverflow.com/questions/330793/how-to-initialize-a-struct-in-ansi-c - プログラミング言語 C の新機能 -- http://seclan.dll.jp/c99d/c99d00.htm - c++ - Compound literals in MSVC - Stack Overflow -- http://stackoverflow.com/questions/3869963/compound-literals-in-msvc - Compound Literals - Using the GNU Compiler Collection (GCC) -- http://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html - Dr Dobbs - The New C: X Macros -- http://www.drdobbs.com/184401387 * 構造体の初期化その1 VC++2008, GCC4 の両方で使用可能。 struct01.c: #code|c|> #include 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: #code|c|> #include 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: #code|c|> #include 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: #code|c|> #include 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 #navi_footer|C言語系|