c - 为结构体的 union 字段赋值时出现问题

标签 c struct unions

我是新来的,希望能得到一些帮助。 在完成有关structsunion 的教程后,我练习了所学内容,并希望将两种想法结合起来。但我遇到了一个错误,我花了几个小时试图解决这个错误,但没有成功。

代码是:

void main(){

    typedef enum {INDIV, OUNCE, POUND } quantity;

    typedef union{

        short individual;
        float pound;
        float ounce;

    } amount;

    typedef struct{

        char *brand;
        amount theAmount;

    } orangeProduct;

    orangeProduct productOrdered;

    quantity quantityType = OUNCE;

    switch(quantityType)
    {
        case INDIV:
            productOrdered = {"Chiquita", .theAmount.individual = 13 };
            printf("You bought %d oranges\n\n", productOrdered.theAmount.individual)
            break;

    }
}

我还有其他情况,但这并不重要:如果我解决了第一个问题,我就会解决所有问题。 目标是拥有可以容纳品牌橙子的结构,并为每个品牌容纳购买的数量、正确的重量类型。

问题在于行:

productOrdered = {"Chiquita", productOrdered.theAmount.individual = 13 };

我的gcc编译器(使用codeBlocks)对我大喊大叫:

error: expected expression before '{' token|

而且,无论我尝试什么,都没有帮助。

请帮忙。

最佳答案

分配给结构

只有在定义结构时才能使用大括号 ( { .... } ) 和结构初始值列表的语法,如下所示:

orangeProduct productOrdered = { "Chiquita", { 13 } };

您不能在作业中使用它;该语句的语法不正确:

productOrdered = { "Chiquita", { 13 } };

有两种方法可以为结构分配值,而不是在定义结构时初始化它。一种是单独分配给每个成员:

productOrdered.brand = "Chiquita";
productOrdered.theAmount.individual = 13;

另一种方法是从另一个结构复制它:

productOrdered = SomeOtherProduct;

我们可以将上面的内容与另一个称为复合文字的 C 功能一起使用。可以在表达式中使用复合文字来提供对象,而无需为其指定名称。复合文字的一般形式是:

(type) { initial values... }

虽然(type)看起来像是 Actor 阵容,其实不是。此语法定义一个对象,并且它可以对声明中使用的初始值使用相同的语法。这意味着我们可以初始化一个复合文字并将其分配给一个结构:

productOrdered = (orangeProduct) { "Chiquita", { 13 } };

有关分配给结构的其他注意事项

以下所有内容具有相同的效果:

productOrdered = (orangeProduct) { "Chiquita", { 13 } };
productOrdered = (orangeProduct) { "Chiquita", 13 };
productOrdered = (orangeProduct) { "Chiquita", { .individual = 13 } };
productOrdered = (orangeProduct) { "Chiquita", .theAmount.individual = 13 };

在第一个中,内部大括号表示我们正在为主对象的子对象提供初始值 - 对于 union amount里面orangeProduct 。正如第二行所示,这不是必需的,因为如果省略大括号,编译器将采用未分组的初始值并将它们分配给子对象的成员。但是,最好明确地包含大括号,因为它可以避免更复杂的聚合中的错误,并有助于向人类读者传达意图。

第三和第四种形式显示我们可以使用他们的名字来初始成员。这种形式称为指定初始值设定项。当您跳过结构中的成员或想要初始化 union 体中除第一个列出的成员之外的成员时,它们最有用。

但是,另一个答案提出了这个不正确的说法:

productOrdered = (orangeProduct){"Chiquita", productOrdered.theAmount.individual = 13 }

这是错误的,因为 productOrdered.theAmount.individual = 13不仅仅是一个初始值;它是一个赋值表达式。它将 13 分配给 productOrdered.theAmount.individual 。这样做的问题是整个语句还将值分配给 productOrdered ,包括productOrdered.theAmount.individual 。这违反了 C 2018 6.5 2 中的规则,其中规定:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined…

productOrdered.theAmount.individual 的两项赋值是无序的,因为 C 标准中没有规则规定赋值何时相对于彼此发生。 (当赋值表达式更新对象的值时,这称为副作用,并且它不是表达式主要求值操作的一部分。)

其他说明

main应使用 int main(void) 声明或int main(int argc, char *argv) ,不与void main() 。也可以使用 C 实现允许的特定形式来声明它。

包括#include <stdio.h>在您的代码中声明 printf .

在此行后添加分号:

printf("You bought %d oranges\n\n", productOrdered.theAmount.individual)

关于c - 为结构体的 union 字段赋值时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58248749/

相关文章:

c++ - 为什么在 std::optional 的某些实现中存在虚拟 union 成员?

c - 未知 "for"语句 (C)

php - 在 c 和 php 之间传递数据

c++ - 使用 ostream 从另一个类的结构访问数据

json - 解码编码不佳的 JSON(嵌套过多、许多可能的键、键与值混淆)

C编程: Freeing nested multidimensional arrays inside structs

c - FreeImage 包含在 c 中

c - 数组存储问题

c - 具有不同大小成员的 union 数组

c++ - union 中的 std::shared_ptr