简体   繁体   English

如何在C中的联合中使用指针?

[英]How to use pointers in an union in C?

I want to initialize this structure: 我想初始化这个结构:

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

If I try to initialize this structure when I declare the variable I get an error: For example; 如果在声明变量时尝试初始化此结构,则会出现错误:

const char *gpStr = "str";

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

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

The variable gpStr can´t be used to initialize the structure 变量gpStr不能用于初始化结构

But it can be initialized inside of a function without problem: 但是它可以在函数内部初始化而没有问题:

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

Why the structure can't be initialized when it is declared? 为什么在声明结构时无法对其进行初始化?

I think the union has a special behavior because if I don't use an union the problem doesn't exist. 我认为工会有一种特殊的行为,因为如果我不使用工会,这个问题就不存在。 For example: 例如:

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

Variables initialized at file scope (whether static or not) and variables initialized at block scope with static duration can only be initialized with constants. 在文件范围内初始化的变量(无论是否为static )和在块范围内以static持续时间初始化的变量只能使用常量进行初始化。 Automatic variables (necessarily at block scope) can be initialized with expressions. 自动变量(必要时在块范围内)可以用表达式初始化。

Also, when a union is initialized, the initializer must match the first member unless a designated initializer is used. 同样,在初始化联合时,除非使用指定的初始化程序,否则初始化程序必须与第一个成员匹配。 With C99 or later, you could write: 使用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 } },
};

Note the tweaked type for gpStr . 注意gpStr的调整类型。 You don't have to use the designated initializers for all the elements, but consistency suggests you probably should. 您不必对所有元素都使用指定的初始化程序,但是一致性建议您可能应该使用。 Also note that a union of two differently named int members is modestly pointless. 还要注意,两个不同名称的int成员的并集是毫无意义的。 The different elements of a union should normally be of different types. 联合的不同元素通常应具有不同的类型。

The unscientific answer: 不科学的答案:

I think you can only initialize with constants. 我认为您只能使用常量进行初始化。 In the first instance you are initializing (ie allocating a value before the program runs) with a variable; 在第一个实例中,您正在使用变量进行初始化(即在程序运行之前分配一个值); by definition variables don't have a "accessible" value until the program runs. 根据定义,在程序运行之前,变量没有“可访问”的值。 In your second example the "initialization" is really an "assignment" with a variable, and that's OK. 在第二个示例中,“初始化”实际上是带有变量的“赋值”,没关系。 I don't think it has anything to do with the fact that you have a union. 我认为您拥有工会这一事实与之无关。

Simplest example: 最简单的例子:

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

When I try to compile, I get 当我尝试编译时,我得到

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

I hope this clarifies things. 我希望这可以使事情澄清。

The problem is that you can only initialize the FIRST element of a union, unless you use an explicit designator. 问题是,除非使用显式指示符,否则您只能初始化联合的FIRST元素。 So the following works: 因此,以下工作原理:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM