C语言中的逗号运算符

38
#include<stdio.h> 
int main(void) {
   int a;
   a = (1, 2), 3; 
   printf("%d", a);
   return 0;
}

输出: 2
有人可以解释一下输出为什么是2吗?


5
你写代码时的期望是什么?它不仅仅是将语句和表达式组合在一起,代码应该具有意义。你试图实现什么目标? - Sourav Ghosh
6
回答这个问题并不需要知道 OP 的期望。如果你想回答,只需解释导致结果为“2”的机制即可(如果你愿意花费精力回答)。 - Ctx
4
这个问题显然不是关于调试的,但它是符合主题的。 - Ctx
12
@Olaf 问题提出者很好奇为什么C语言会表现出这种行为。操作符优先级在这里起到了一定作用,我不认为大多数好的C语言书籍中描述了这个特殊情况。这不是调试问题也不是“范围过大”,而是试图理解这个(非常复杂)结构体是如何工作的。我不同意这是一个需要详细解释的问题。 - Ctx
9
我不同意@Olaf的观点。即使是在预期结果时,你仍然可以思考“如何”或“为什么”。我以前没有见过这种情况,发现它很有趣。我同意@Ctx的看法。 - Hans Petter Taugbøl Kragset
显示剩余12条评论
3个回答

63
有人可以解释一下为什么输出是2吗?
因为赋值运算符(=)的优先级高于逗号运算符(,)。
因此,语句:
a = (1, 2), 3;
等同于:
(a = (1, 2)), 3;
而表达式(1, 2)的计算结果为2。

33
哦,是的,它回答了这个问题:它意味着 a 被赋值为表达式 (1, 2) 的值,即 2。逗号后面的 3 对赋值没有影响。 - cmaster - reinstate monica
1
@cmaster:我没有看到任何迹象表明OP假定“3”。他也可能期望“1”。这有不同的原因。 - too honest for this site
1
@Gam:我们不是一个辅导网站!通过试错或者晦涩的YouTube视频或博客学习C语言是行不通的,因为大多数作者并不真正了解这门语言,他们只关注特定的方面。找一本好的现代C语言教材(至少是C99,最好是C11),并逐步学习课程。 - too honest for this site
4
请重新阅读表达式(a = (1, 2)), 3:执行赋值的子表达式中甚至没有包含数字3。这样是否澄清了问题? - cmaster - reinstate monica
3
哦,对不起,我现在明白了!变量取值为2(1在这里毫无用处),然后计算表达式“3”,但它并没有任何作用。 - Gam
显示剩余5条评论

29

有人能解释一下输出为什么是2吗?

在这个语句中:

a = (1, 2), 3;   
< p >, used is a comma operator. Due to higher operator precedence of = operator than that of , operator, the expression operand (1, 2) will bind to = as

< p > ,被称为逗号操作符。由于=运算符的优先级高于,运算符,表达式操作数(1, 2)将绑定到=

(a = (1, 2)), 3;  

对于逗号运算符,逗号运算符的左操作数被求值为一个void表达式,然后右操作数会被求值,整个表达式的结果是右操作数的值和类型

此处有两个逗号运算符。在表达式(1, 2)中,第一个逗号运算符中,1被求值为void表达式,然后2被求值并赋值给a
现在a已经产生了副作用,因此第二个逗号运算符的右操作数3将被求值,表达式(a = (1, 2)), 3的值为3


4

的结果:

a = x, y     =>     x

a = (i, j)   =>     j

因此,如果我们有以下内容:
x = (1 , 2)

a = (1 , 2) , 3     =>     2

此处所述:
逗号运算符以类似于分号终止语句的方式分隔具有值的表达式,表达式序列用括号括起来,类似于用大括号括起来的语句序列:(a, b, c)是由逗号分隔的表达式序列,其计算结果为最后一个表达式c,而{a; b; c;}是由大括号括起来的语句序列,不计算任何值。逗号只能出现在两个表达式之间——逗号分隔表达式——而分号出现在(非块)语句的末尾——分号终止语句。
逗号运算符是C中优先级最低的运算符,并作为序列点。在逗号和分号的组合中,分号的优先级低于逗号,因为分号分隔语句,而逗号出现在语句内部,这与它们作为普通标点符号的使用相符:a, b; c, d被分组为(a, b);(c, d),因为这是两个独立的语句。
希望这回答了你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接