问题
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