31

これが、他の誰かの質問で見つけた初期化です。

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

私はこれまでにこのようなものを見たことがなく、どのように .name が正しい可能性があるかについての説明を見つけることができません。
私が探しているのは、このプロセスが段階的に進む方法です。

次のようになります。

  1. data;
  2. *data;
  3. (*data).name;
  4. (*data).name="Peter";

それとも私は完全に間違っていますか?

4

6 に答える 6

35

my_datanameフィールドとしての構造data[]体であり、構造体の配列です。各インデックスを初期化しています。以下を読んでください:

5.20 指定された初期化子:

.fieldname ='構造体初期化子では、要素値の前に初期化するフィールドの名前を指定します。たとえば、次の構造があるとします。

struct point { int x, y; };

次の初期化

struct point p = { .y = yvalue, .x = xvalue };

と同等です

struct point p = { xvalue, yvalue };

GCC 2.5 以降廃止された、同じ意味を持つ別の構文は、次のとおりfieldname:'です。

struct point p = { y: yvalue, x: xvalue };

次のように書くこともできます。

my_data data[] = {
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

なので:

my_data data[] = {
    [0] = { .name = "Peter" },
    [1] = { .name = "James" },
    [2] = { .name = "John" },
    [3] = { .name = "Mike" }
}; 

また:

my_data data[] = {
    [0].name = "Peter",
    [1].name = "James",
    [2].name = "John",
    [3].name = "Mike"
}; 

2 番目と 3 番目の形式は、順番に記述する必要がないため便利です。たとえば、上記の例はすべて次と同等です。

my_data data[] = {
    [3].name = "Mike",
    [1].name = "James",
    [0].name = "Peter",
    [2].name = "John"
}; 

構造体に複数のフィールドがある場合 (たとえば、 an int age)、以下を使用して一度にすべてを初期化できます。

my_data data[] = {
    [3].name = "Mike",
    [2].age = 40,
    [1].name = "James",
    [3].age = 23,
    [0].name = "Peter",
    [2].name = "John"
}; 

配列の初期化を理解するには、奇妙な初期化式をお読みください。

さらに、スイッチ ケースに対する @ Shafik Yaghmourの回答もお読みください: What is “…” in switch-case in C code

于 2013-09-20T16:36:31.943 に答える
30

ここで使用できる構文は 2 つだけです。

  1. 普通の古い配列の初期化:

    int x[] = {0, 0}; // x[0] = 0, x[1] = 0
    
  2. 指定された初期化子。この質問に対する受け入れられた回答を参照してください: C プログラミング言語標準に従って構造体を初期化する方法

    ただし、構文は一目瞭然です。次のように初期化できます。

    struct X {
        int a;
        int b;
    }
    struct X foo = { 0, 1 }; // a = 0, b = 1
    

    または任意の順序を使用するには、

    struct X foo = { .b = 0, .a = 1 }; // a = 1, b = 0
    
于 2013-09-20T16:35:31.673 に答える
22

ここには「ステップバイステップ」はありません。初期化が定数式で実行される場合、プロセスは基本的にコンパイル時に実行されます。もちろん、配列がローカル オブジェクトとして宣言されている場合、配列はローカルに割り当てられ、実行時に初期化されますが、それでも意味のある細分化ができない 1 ステップのプロセスと考えることができます。

指定された初期化子を使用すると、構造体オブジェクトの特定のメンバー (または配列の特定の要素) の初期化子を指定できます。他のすべてのメンバーはゼロで初期化されます。したがって、次のようmy_dataに宣言されている場合

typedef struct my_data {
  int a;
  const char *name;
  double x;
} my_data;

それからあなたの

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

の単純なよりコンパクトな形式です。

my_data data[4]={
    { 0, "Peter", 0 },
    { 0, "James", 0 },
    { 0, "John", 0 },
    { 0, "Mike", 0 }
};

後者が何をするか知っていることを願っています。

于 2013-09-20T16:46:13.633 に答える
2

これは、C99 で導入された指定初期化子と呼ばれます。structこの例では、初期化または配列に使用されますstruct

与えられた

struct point { 
    int x, y;
};

次の初期化

struct point p = { .y = 2, .x = 1 };

C89 スタイルと同等

struct point p = { 1, 2 };
于 2013-09-20T16:34:27.647 に答える
1

これは非常に単純です my_data。定義済みの構造型です。したがってmy_data、いくつかの要素の -arrayを宣言する必要があります。

char a[] = { 'a', 'b', 'c', 'd' };

したがって、配列には4つの要素があり、それらを次のように初期化します

a[0] = 'a', a[1] = 'b', a[1] = 'c', a[1] ='d';

これは、指定された初期化子と呼ばれます (私が正しく覚えているように)。

これは、data が型my_datでなければならず、非常に多くの my_data 構造体を格納する必要がある配列でなければならないことを示しているだけなので、各型メンバー名が Peter、James、John、Mike の構造体が存在します。

于 2013-09-20T16:33:06.827 に答える
1

これは、C99 標準で導入された指定された初期化子です。構造体または共用体オブジェクトの特定のメンバーを名前で初期化できます。 は明らかに、型orのメンバーを持つ型my_dataの typedef です。 structnamechar *char [N]

于 2013-09-20T16:34:47.103 に答える