1

この構造を初期化したい:

typedef struct
{
    int num;
    union 
    {
        const char** ppStrList;
        const char* pStr;
    };
    union
    {
        int num1;
        int num2;
    };
} tMyStruct;

変数を宣言するときにこの構造を初期化しようとすると、エラーが発生します。

const char *gpStr = "str";

const char *gpStrList[2] =
{
    {"str1"},
    {"str2"}
};

tMyStruct myStruct[2] = 
{
    {0,{gpStrList},{3}},
    {1,{gpStr},{4}}
};

変数gpStrを使用して構造体を初期化することはできません

ただし、関数内で問題なく初期化できます。

int main(int argc, char *argv[])
{
    myStruct[0].num = 0;
    myStruct[0].ppStrList = gpStrList;
    myStruct[0].num1 = 3;

    myStruct[1].num = 0;
    myStruct[1].pStr = gpStr;
    myStruct[1].num2 = 3;
}

宣言時に構造体を初期化できないのはなぜですか?

ユニオンを使用しなければ問題は存在しないため、ユニオンには特別な動作があると思います。例えば:

typedef struct
{
    int num;
    union /* Union to contain ppStrList and pStr pointers */
    {
        const char** ppStrList;
        const char* pStr;
    };
    union
    {
        int num1;
        int num2;
    };
} tMyStruct1;


typedef struct
{
    int num;
    /* I don´t use an union */
    const char** ppStrList;
    const char* pStr;

    union
    {
        int num1;
        int num2;
    };
} tMyStruct2;

const char gStr[] = "str";

const char *gpStrList[2] = 
{
    {"str1"},
    {"str2"}
};

tMyStruct1 myStruct1[2] = /* Structure with union inside */
{

    {0,{gpStrList},{3}},
    {1,{gStr},{4}}  /* <--- Error here if I use gStr address with union */
};

tMyStruct2 myStruct2[2] = /* Structure without union inside */
{
    {0,gpStrList,NULL,{3}},
    {1,NULL,gStr,{4}} /* <--- No poblem here if I use gStr address */
};
4

3 に答える 3

4

ファイル スコープで初期化された変数 (かどうstaticかに関係なく) およびブロック スコープでstatic期間を指定して初期化された変数は、定数でのみ初期化できます。自動変数 (必ずブロック スコープで) は、式で初期化できます。

また、共用体が初期化されるとき、指定された初期化子が使用されない限り、初期化子は最初のメンバーと一致する必要があります。C99 以降では、次のように記述できます。

typedef struct
{
    int num;
    union 
    {
        const char** ppStrList;
        const char* pStr;
    };
    union
    {
        int num1;
        int num2;
    };
} tMyStruct;

const char gpStr[] = "str";

const char *gpStrList[2] =
{
    "str1",
    "str2"
};

tMyStruct myStruct[2] = 
{
    { .num = 0, { .ppStrList = gpStrList }, { .num1 = 3 } },
    { .num = 1, { .pStr      = gpStr     }, { .num2 = 4 } },
};

の微調整された型に注意してくださいgpStr。すべての要素に指定されたイニシャライザを使用する必要はありませんが、一貫性から、おそらくそうすべきであることが示唆されています。intまた、2 つの異なる名前のメンバーの和集合はあまり意味がないことに注意してください。共用体のさまざまな要素は、通常、さまざまな型である必要があります。

于 2013-11-04T06:34:45.830 に答える
0

非科学的な答え:

定数でしか初期化できないと思います。最初のインスタンスでは、変数を使用して初期化しています (つまり、プログラムの実行前に値を割り当てています)。定義により、変数はプログラムが実行されるまで「アクセス可能な」値を持ちません。2番目の例では、「初期化」は実際には変数を使用した「割り当て」であり、それで問題ありません。あなたが労働組合を持っているという事実とは何の関係もないと思います。

最も簡単な例:

#include <stdio.h>
int one = 1;
int two = one;
int main(void) {
  printf("one is %d; two is %d\n", one, two);
}

コンパイルしようとすると、

consts.c:3: error: initializer element is not constant

これで問題が解決することを願っています。

于 2013-11-04T05:18:57.507 に答える
0

問題は、明示的な指定子を使用しない限り、共用体の FIRST 要素しか初期化できないことです。したがって、次のように動作します。

tMyStruct myStruct[2] =
{
    {0,{gpStrList},{3}},
    {1,{.pStr = "str"},{4}}
};
于 2013-11-04T06:38:51.203 に答える