在C中,如果它们属于同一类型,我们可以将一个结构变量的值赋给其他。根据这个,在我的下一个程序中,当s1=s2
都是{{}时,我可以使用struct
1}}相同类型的变量。但为什么之后我不允许使用s1={59,3.14}
?
我知道我们不能将字符串"Test"
分配给除初始化语句之外的字符数组arr
,因为对于字符串"Test"
,它会分解为类型char*
在赋值期间,因此存在类型不匹配错误。但在我的程序中,{59,3.14}
不会分解为任何指针,是吗?为什么然后不允许将其分配给s1
,尽管它是相同的类型,特别是因为在初始化期间允许它?s2
和{59,3.14}
之间有什么不同,以便允许一个被分配给s1
但另一个不是#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}}
答案 0 :(得分:2)
你需要这样抛出它:s1 = (struct test1){59, 3.14};
让编译器知道它应该考虑你的{...}类型struct test1。
换句话说,您在括号内收集的数据没有类型,这就是您需要使用强制转换来指定一个类型的原因。
编辑:
编译器需要知道每个struct的字段的预期类型。这需要知道每个参数的正确字节数,填充等。否则它也可以将值59(这意味着是一个int)复制为char,因为它是一个适合一个字节的值。
答案 1 :(得分:2)
C语法严格区分赋值和初始化。
对于初始化,很清楚右侧的类型应该是什么:声明的对象的类型。所以初始化符号是明确的; { a, b, c }
是声明顺序中的字段。
对于作业,事情不太清楚。赋值表达式X = Y
首先评估两个子表达式(X
和Y
),查看其类型,然后根据Y
的类型进行必要的转换(如果可能) X
的类型。 { a, b, c }
形式的表达式没有类型,因此该机制不起作用。
yoones在他的回答中使用的构造是另一种动物,称为复合文字。这是一种创建指定类型的未命名辅助对象的方法。您可以在初始化或任何其他您想要使用临时对象的地方使用它。复合文字的存储类和生命周期是从使用它的上下文推导出来的。如果它在函数范围内,则它是自动的(在“堆栈”上),因为它将是在同一块中声明的普通变量,只是它没有名称。如果在文件范围中使用它(例如“全局”变量的初始化),则具有静态存储持续时间和生命周期,该生命周期是程序执行的整个持续时间。