如何在C中使用指针?

时间:2013-11-04 05:13:48

标签: c pointers initialization unions

我想初始化这个结构:

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 */
};

3 个答案:

答案 0 :(得分:3)

在文件范围初始化的变量(无论是否static)和在static持续时间的块范围内初始化的变量只能使用常量初始化。自动变量(必须在块范围内)可以用表达式初始化。

此外,初始化union时,初始化程序必须与第一个成员匹配,除非使用指定的初始化程序。使用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成员的联合是毫无意义的。联合的不同元素通常应该是不同的类型。

答案 1 :(得分: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

我希望这能澄清事情。

答案 2 :(得分:0)

问题在于,除非使用显式指示符,否则只能初始化并集的FIRST元素。以下是有效的:

tMyStruct myStruct[2] =
{
    {0,{gpStrList},{3}},
    {1,{.pStr = "str"},{4}}
};