C数据类型声明查询

Posted

技术标签:

【中文标题】C数据类型声明查询【英文标题】:C data type declaration query 【发布时间】:2016-02-08 18:17:46 【问题描述】:

在 C 编程语言中,将 4,3 分配给整数类型变量,例如:

int a;

a = 4,3;

变量接收逗号左侧的值(即,a 在示例中设置为 4)。但是,在分配带括号的列表时,例如

a = (4,3);

,变量取逗号分隔列表中的最后一个值(示例中为3)。

这是什么原因?

【问题讨论】:

能否请您发布您用于测试的代码? 【参考方案1】:

C 以两种不同的方式使用逗号 (,):作为复合结构(如数组文字或声明列表)中的元素分隔符,以及作为二元运算符。它不像某些高级语言那样具有基于列表的分配。

作为运算符,逗号首先计算其左侧操作数,然后计算其右侧操作数。整体表达式的值是第二个结果。这在某些方面是对 &&|| 运算符的补充,这两个运算符都首先评估其左侧操作数,但每个运算符仅根据左侧结果有条件地评估其右侧操作数。

了解您的观察的另一个关键是等号 (=) 也是 一个运算符。它以未指定的顺序计算两个操作数,其结果与右侧操作数相同。修改左侧操作数的值是一个副作用。

赋值运算符的优先级很低,但逗号运算符的优先级最低。因此,如果您不使用括号来更改评估顺序,这...

a = 4,3;

... 等价于 ...

(a = 4), 3;

。它首先评估赋值,产生值4,同时将该值赋给变量a。然后它丢弃该值并评估3,产生值3 作为整体结果。由于整个事情不是任何更大表达式的一部分,因此结果被丢弃。

另一方面,您可以通过适当使用括号来覆盖优先级,如下所示:

a = (4, 3);

。在这种情况下,首先计算逗号运算符,产生3 作为其结果,这是赋值运算符的右手操作数。赋值表达式产生结果3,副作用是将该值赋给变量a

【讨论】:

很好的解释。 BTW the comma operator has the lowest precedence of all -- 如果您将 ; 视为运算符(我知道这是错误的,但只是为了说明),那么首先评估逗号。这就是return 采用逗号分隔列表的最后一个值的原因。 ideone.com/819cWn @Wolf ; 不是操作员。此外,在return 4,3; 中,逗号是运算符,而不是分隔符。在逗号分隔的列表中没有排序,例如f(a(), b()); 可以按任意顺序调用ab【参考方案2】:

是的。这才是正确的操作。

   i = (a, b);             // stores b into i 
                          // ... a=1, b=2, c=3, i=2
   i = a, b;               // stores a into i. Equivalent to (i = a), b;
                          // ... a=1, b=2, c=3, i=1

检查逗号运算符的属性。 “在 C 和 C++ 编程语言中,逗号运算符(由标记 , 表示)是一个二元运算符,它计算其第一个操作数并丢弃结果,然后计算第二个操作数并返回此值(和类型)。” - ***

【讨论】:

你是对的,但你还没有把这些点联系起来。解释为什么括号会有所不同会很有帮助。【参考方案3】:

C/C++ 中,comma(,) 运算符从左到右进行求值,并丢弃左表达式的值。结果的类型和值是右操作数的类型和值。左操作数求值的所有副作用在开始右操作数求值之前完成。取自 KR book A.7.18

此外,逗号运算符具有评估的最低优先级和顺序

由于= 运算符的优先级高于, 运算符。在下面的声明中

int a;
a = 4,3;

分配首先发生导致a = 4

而且众所周知,() 会覆盖precedence,所以我们有a = 3 以防出现

int a = (4,3);

现在,我们都了解了,=的原理,让我们集中精力什么时候使用,应谨慎使用逗号运算符,最适合用于彼此密切相关的构造。例如for loop

for (i = 0, j = strlen(s)-1; i < j; i++, j--)

只要可能,我将(), 结合使用

【讨论】:

int a = 4,3; 格式不正确。 OP 在询问 int a; a = 4,3;a = (4,3); 我的错误,感谢您指出这一点。你介意重新考虑一下吗

以上是关于C数据类型声明查询的主要内容,如果未能解决你的问题,请参考以下文章

go语言基础语法-容器数据类型-数组

为啥 LINQ 在我的查询中使用错误的数据类型,而它在 EF 架构中被正确声明?

C语言数据类型所占字节是和运行的机器位数有关还是编译器有关

Intellisense 声明强类型 DataSet 查询的参数是 Decimal,而它应该是 String

第二部分

C中不同的数据类型