For struct variables s1,s2,why can I initialize “s1={25,3.5}”,assign s2 as “s1=s2”,but then can't use "s1={59,3.14}?

醉酒当歌 提交于 2019-12-08 05:45:34

问题


In C we are allowed to assign the value of one structure variable to other if they are of the same type.In accordance with that, in my following program I am allowed to use s1=s2 when both are struct variables of the same type.But why then I am not allowed to use s1={59,3.14} after that?

I know we can't assign a string "Test" to a character array arr other than in the initialization statement because for the string "Test",it decomposes to type char* during assignment and hence there is a type mismatch error.But in my program, {59,3.14} doesn't decompose to any pointer,does it?Why then it is not allowed to be assigned to s1 even though it is of same type,especially since it is allowed during the initialization?What is the different between s2 and {59,3.14} such that one is allowed to be assigned to s1 but the other is not?

#include<stdio.h>

int main(void)
{
    struct test1
    {
        int a;
        float b;
    } s1= {25,3.5},s2= {38,9.25};

    printf("%d,%f\n",s1.a,s1.b);

    s1=s2;   // Successful
    printf("%d,%f\n",s1.a,s1.b);

    s1= {59,3.14}; //ERROR:expected expression before '{' token|
    printf("%d,%f\n",s1.a,s1.b);

}

回答1:


The C grammar strictly distinguishes between assignment and initialization.

For initialization it is clear what the type on the right side ought to be: the type of the object that is declared. So the initializer notation is unambiguous; { a, b, c } are the fields in declaration order.

For assignment things are less clear. An assignment expression X = Y first evaluates both subexpressions (X and Y), looks at their types and then does the necessary conversions, if possible, from the type of Y to the type of X. An expression of the form { a, b, c } has no type, so the mechanism doesn't work.

The construct that yoones uses in his answer is yet another animal, called compound literal. This is a way of creating an unnamed auxiliary object of the specified type. You may use it in initializations or any other place where you'd want to use a temporary object. The storage class and lifetime of a compound literal is deduced from the context where it is used. If it is in function scope, it is automatic (on the "stack") as would be a normal variable that would be declared in the same block, only that it doesn't have a name. If it is used in file scope (intialization of a "global" variable, e.g) is has static storage duration and a lifetime that is the whole duration of the program execution.




回答2:


You need to cast it this way: s1 = (struct test1){59, 3.14}; to let the compiler know that it should consider your {...} of type struct test1.

Put in an other way, your data gathered between brackets doesn't have a type, that's why you need to specify one using a cast.

Edit:

The compiler needs to know the expected type for each struct's fields. This is needed to know the right number of bytes for each argument, for padding, etc. Otherwise it could as well copy the value 59 (which is meant to be an int) as a char since it's a value that fits in one byte.



来源:https://stackoverflow.com/questions/16614045/for-struct-variables-s1-s2-why-can-i-initialize-s1-25-3-5-assign-s2-as-s1-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!