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成员的联合是毫无意义的。联合的不同元素通常应该是不同的类型。

于 2013-11-04T06:34:45.830 回答
0

不科学的答案:

我认为你只能用常量初始化。在第一个实例中,您正在使用变量进行初始化(即在程序运行之前分配一个值);根据定义,在程序运行之前,变量没有“可访问”值。在您的第二个示例中,“初始化”实际上是一个带有变量的“赋值”,这没关系。我认为这与你有工会这一事实无关。

最简单的例子:

#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

问题是您只能初始化联合的第一个元素,除非您使用显式指示符。所以以下工作:

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