对于struct变量s1,s2,为什么我可以初始化“s1 = {25,3.5}”,将s2指定为“s1 = s2”,但是不能使用“s1 = {59,3.14}?

时间:2013-05-17 16:40:09

标签: c struct variable-assignment structure

在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}}

2 个答案:

答案 0 :(得分:2)

你需要这样抛出它:s1 = (struct test1){59, 3.14};让编译器知道它应该考虑你的{...}类型struct test1。

换句话说,您在括号内收集的数据没有类型,这就是您需要使用强制转换来指定一个类型的原因。

编辑:

编译器需要知道每个struct的字段的预期类型。这需要知道每个参数的正确字节数,填充等。否则它也可以将值59(这意味着是一个int)复制为char,因为它是一个适合一个字节的值。

答案 1 :(得分:2)

C语法严格区分赋值和初始化。

对于初始化,很清楚右侧的类型应该是什么:声明的对象的类型。所以初始化符号是明确的; { a, b, c }是声明顺序中的字段。

对于作业,事情不太清楚。赋值表达式X = Y首先评估两个子表达式(XY),查看其类型,然后根据Y的类型进行必要的转换(如果可能) X的类型。 { a, b, c }形式的表达式没有类型,因此该机制不起作用。

yoones在他的回答中使用的构造是另一种动物,称为复合文字。这是一种创建指定类型的未命名辅助对象的方法。您可以在初始化或任何其他您想要使用临时对象的地方使用它。复合文字的存储类和生命周期是从使用它的上下文推导出来的。如果它在函数范围内,则它是自动的(在“堆栈”上),因为它将是在同一块中声明的普通变量,只是它没有名称。如果在文件范围中使用它(例如“全局”变量的初始化),则具有静态存储持续时间和生命周期,该生命周期是程序执行的整个持续时间。