对于结构变量s1,s2,为啥我可以初始化“s1 = 25,3.5”,将s2分配为“s1 = s2”,但不能使用“s1 = 59,3.14?

Posted

技术标签:

【中文标题】对于结构变量s1,s2,为啥我可以初始化“s1 = 25,3.5”,将s2分配为“s1 = s2”,但不能使用“s1 = 59,3.14?【英文标题】: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?对于结构变量s1,s2,为什么我可以初始化“s1 = 25,3.5”,将s2分配为“s1 = s2”,但不能使用“s1 = 59,3.14? 【发布时间】:2013-05-12 22:00:37 【问题描述】:

在C语言中,如果一个结构变量的类型相同,我们可以将它们的值分配给另一个。根据这一点,在我的以下程序中,当两者都是struct变量时,我可以使用s1=s2相同类型的。但是为什么在那之后我不允许使用s1=59,3.14

我知道除了在初始化语句中之外,我们不能将字符串 "Test" 分配给字符数组 arr,因为对于字符串 "Test",它在分配期间分解为类型 char*,因此存在类型不匹配错误。但是在我的程序中,59,3.14 不会分解为任何指针,是吗?为什么即使它是同一类型,也不允许将其分配给 s1,尤其是因为它在初始化?s259,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);


【问题讨论】:

最简单的答案(我并不是轻率):因为这就是语法的定义方式。 C99 引入了复合字面量,不知道现在能不能照你说的做。 虽然 yoones 的回答告诉我如何让它在我的代码中工作,但我仍然觉得需要一些解释,一些技术解释关于这里发生了什么。非常欢迎详细回答。 【参考方案1】:

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

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

对于分配,事情不太清楚。赋值表达式X = Y 首先计算两个子表达式(XY),查看它们的类型,然后进行必要的转换,如果可能的话,从Y 的类型到X 的类型。 a, b, c 形式的表达式没有类型,因此该机制不起作用。

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

【讨论】:

很高兴您提供了一个很好的答案。您能否进一步澄清You may use it in initializations or any other place where you'd want to use a temporary object. 的意思?我的意思是,如果我使用(struct test1)a,b,c ,那么如果它不是临时的,那么复合文字存储在哪里?在数据段中?【参考方案2】:

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

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

编辑:

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

【讨论】:

它有效,但我不知道为什么会这样。对我来说完全陌生。你能解释一下吗? 现在清楚了吗?或者,也许您可​​以尝试更具体地回答您的问题以帮助我回答。 那不是演员表;它是一个复合文字。 @Thokchom:如果你只写59, 3.14,编译器不知道那是什么——它只是一些数字,编译器不知道它应该是哪个结构或其他对象.当您编写(MyType) 59, 3.14 时,它会告诉编译器这是MyType 的数据。当59, 3.14 出现在定义中时,编译器已经知道类型,因为它是声明的一部分。 (另外,这是一个初始化器,而不是复合文字,您可以在其中使用一些额外的功能,但这是另一回事。)

以上是关于对于结构变量s1,s2,为啥我可以初始化“s1 = 25,3.5”,将s2分配为“s1 = s2”,但不能使用“s1 = 59,3.14?的主要内容,如果未能解决你的问题,请参考以下文章

第三章结构之法--------字符串移位包含

Arduino结构体变量使用

Ptyhon 变量的赋值详解

C语言中在定义了一个结构体,里面有char num[15],请问如何比较里面的内容?

C语言中,该怎样区分指针常量和指针变量?

C语言-字符串相加考虑进位