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
。
【讨论】:
很好的解释。 BTWthe comma operator has the lowest precedence of all
-- 如果您将 ;
视为运算符(我知道这是错误的,但只是为了说明),那么首先评估逗号。这就是return
采用逗号分隔列表的最后一个值的原因。 ideone.com/819cWn
@Wolf ;
不是操作员。此外,在return 4,3;
中,逗号是运算符,而不是分隔符。在逗号分隔的列表中没有排序,例如f(a(), b());
可以按任意顺序调用a
和b
。【参考方案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数据类型声明查询的主要内容,如果未能解决你的问题,请参考以下文章
为啥 LINQ 在我的查询中使用错误的数据类型,而它在 EF 架构中被正确声明?