简体   繁体   English

将值分配给结构的联合字段的问题

[英]problem with assigning value to a unionized field of a struct

I am new here, hope that I can get some help.我是新来的,希望能得到一些帮助。 After doing a tutorial about structs and unions , I practice what I learned, and want to combine two ideas.在做了一个关于structsunions的教程之后,我实践了我所学的,并想结合两个想法。 But I get an error that I've been trying to solve couple of hours, without any luck.但是我遇到了一个错误,我一直在尝试解决几个小时,但没有任何运气。

The code is:代码是:

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;

    }
}

I have other cases as well, but this doesn't matter: if I solve the first one I will solve all of them.我也有其他情况,但这没关系:如果我解决了第一个问题,我将解决所有问题。 The goal is to have structure which can hold brands of oranges, and for each brand hold the amount bought, the correct weight type.目标是具有可以容纳橙子品牌的结构,并为每个品牌容纳购买的数量,正确的重量类型。

The problem is with the line:问题出在这条线上:

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

my gcc compiiler (using codeBlocks ) is shouting at me:我的gcc compiiler (使用codeBlocks )对我大喊:

error: expected expression before '{' token|错误:“{”标记之前的预期表达式|

and, no matter what I tried, it didn't help.而且,无论我尝试什么,它都没有帮助。

Please help.请帮忙。

Assigning To a Structure分配给结构

The syntax of using braces ( {.... } ) with a list of initial values for a structure can be used only when defining a structure, as in:只有在定义结构时才能使用带有结构初始值列表的大括号 ( {.... } ) 的语法,如下所示:

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

You cannot use it in an assignment;您不能在作业中使用它; this statement does not have correct grammar:此语句没有正确的语法:

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

There are two ways to assign values to a structure, rather than initializing it when it is defined.有两种方法可以为结构赋值,而不是在定义时对其进行初始化 One is to assign to each member individually:一种是单独分配给每个成员:

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

Another is to copy it from another structure:另一种是从另一个结构中复制它:

productOrdered = SomeOtherProduct;

We can use the above with another C feature called a compound literal .我们可以将上述内容与另一个称为复合文字的 C 功能一起使用。 A compound literal can be used in an expression to provide an object without giving it a name.可以在表达式中使用复合文字来提供 object 而无需为其命名。 The general form of a compound literal is:复合文字的一般形式是:

(type) { initial values... }

Although (type) looks like a cast, it is not.尽管(type)看起来像演员表,但它不是。 This syntax defines an object, and it can use the same syntax for initial values that is used in declarations.此语法定义了一个 object,它可以使用与声明中使用的初始值相同的语法。 That means we can initialize a compound literal and assign it to a structure:这意味着我们可以初始化一个复合文字并将其分配给一个结构:

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

Other Notes About Assigning To a Structure关于分配给结构的其他说明

All of the following have the same effect:以下所有内容都具有相同的效果:

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

In the first of these, the inner braces indicate we are providing an initial value for a subobject of the main object—for the union amount inside the orangeProduct .在其中的第一个中,内大括号表示我们正在为主对象的子对象提供初始值——用于orangeProduct内的联合amount As the second line shows, this is not required, because, if the braces are omitted, the compiler will take the ungrouped initial values and assign them to members of the subobjects anyway.如第二行所示,这不是必需的,因为如果省略大括号,编译器将采用未分组的初始值并将它们分配给子对象的成员。 However, it is good to include the braces explicitly, as it can avoid errors in more complicated aggregates and help convey intent to human readers.但是,最好明确地包含大括号,因为它可以避免更复杂的聚合中的错误,并有助于向人类读者传达意图。

The third and fourth forms show we can initial members using their names.第三个和第四个 forms 显示我们可以使用他们的名字来初始化成员。 This form is called designated initializers.这种形式称为指定初始值设定项。 They are most useful when you are skipping members in a structure or want to initialize a member of a union other than the first listed member.当您跳过结构中的成员或想要初始化除第一个列出的成员之外的联合成员时,它们最有用。

However, another answer suggested this incorrect statement:但是,另一个答案提出了这个错误的说法:

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

That is wrong because productOrdered.theAmount.individual = 13 is not just an initial value;这是错误的,因为productOrdered.theAmount.individual = 13不仅仅是一个初始值; it is an assignment expression.它是一个赋值表达式。 It assigns 13 to productOrdered.theAmount.individual .它将 13 分配给productOrdered.theAmount.individual The problem with this is that the whole statement also assigns values to productOrdered , including to productOrdered.theAmount.individual .这样做的问题是整个语句还为productOrdered ,包括productOrdered.theAmount.individual This violates the rule in C 2018 6.5 2, which says:这违反了 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…如果标量 object 上的副作用相对于同一标量 object 上的不同副作用或使用相同标量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值计算是未排序的,则行为未定义

The two assignments to productOrdered.theAmount.individual are unsequenced because no rule of the C standard says when the assignments occur relative to each other.productOrdered.theAmount.individual的两个分配是无序的,因为 C 标准的规则没有说明分配发生的时间。 (When an assignment expression updates the value of an object, that is called a side effect, and it is not part of the main evaluation operation of an expression.) (当赋值表达式更新 object 的值时,这称为副作用,它不是表达式的主要评估操作的一部分。)

Other Notes其他注意事项

main should be declared with int main(void) or int main(int argc, char *argv) , not with void main() . main应该用int main(void)int main(int argc, char *argv)声明,而不是用void main() It can also be declared with specific forms allowed by your C implementation.它也可以使用 C 实现允许的特定 forms 声明。

Include #include <stdio.h> in your code to declare printf .在您的代码中包含#include <stdio.h>以声明printf

Append a semicolon to this line: Append 此行的分号:

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

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

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