C++中逗号运算符的不同行为与返回?

ps9*_*s95 80 c++ return operator-precedence comma-operator language-lawyer

这个(注意逗号运算符):

#include <iostream>
int main() {
    int x;
    x = 2, 3;
    std::cout << x << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出2.

但是,如果您使用return逗号运算符,则:

#include <iostream>
int f() { return 2, 3; }
int main() {
    int x;
    x = f();
    std::cout << x << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出3.

为什么逗号运算符的行为与return

son*_*yao 138

根据运算符优先级,逗号运算符的优先级低于operator=,因此x = 2,3;相当于(x = 2),3;.(运算符优先级确定运算符将如何绑定到其参数,根据其优先级比其他运算符更紧或更松散.)

请注意逗号表达式在(x = 2),3这里,而不是2,3.x = 2首先评估(并且其副作用已完成),然后丢弃结果,然后3进行评估(事实上它什么都不做).这就是为什么价值的x原因2.注意,这3是整个逗号表达式(即x = 2,3)的结果,它不会用于赋值x.(将其更改为x = (2,3);,x将分配给3.)

return 2,3;,逗号表达式2,3,2评估则其结果会被丢弃,然后3被评估并返回作为整个逗号表达,这是由所返回的结果返回语句以后.


有关表达式语句的其他信息

表达式是一系列运算符及其操作数,用于指定计算.

x = 2,3;表达式语句,x = 2,3是这里的表达式.

后跟分号的表达式是一个语句.

句法: attr(optional) expression(optional) ; (1)

return 2,3;jump语句(return语句),2,3是这里的表达式.

句法: attr(optional) return expression(optional) ; (1)

  • 我已经看到它在`for`循环中使用了一次或两次,奇怪的是,它可以使代码*在数值计算中更清晰*. (11认同)
  • @ Jean-FrançoisFabre国际海事组织,它只是令人困惑,根本没用. (7认同)
  • @ Jean-FrançoisFabre:就像Bathesheba所说的那样,你可以在for循环中写出类似`i + = 1,j + = 2`的东西.有人认为C++语法(或者更确切地说是C语法,因为这部分是从那里复制的)已经足够复杂了,而没有试图定义当你写'x = 2,3,但是更低时逗号的优先级高于赋值当你写'x = 2,y = 3`时! (6认同)
  • @Holger:分号终止语句,它不是运算符。可以对答案进行调整以使其更加清楚。“x = 2 , 3”是一个具有 2 个运算符的表达式,并且由于支持 for(;;),= 具有更高的优先级。(正如其他人所说。)但是“return 2, 3;” 是包含表达式“2, 3”的语句。*技术上*关键字“return”没有优先级。(虽然*有效地*,因为它是接受表达式的语句的一部分,所以它是最后解析的——比表达式中*中的任何运算符的“优先级”都要低。) (2认同)
  • @prakharsingh95——我只是说一定存在沟通不畅。你用不同意的语气重复了我的观点。引用我写的内容:“那么你可以谈论 '(x=2), 3;' 与 '返回 (2, 3);' 就“=”而言,与采用表达式的 return 语句相比,具有更高的优先级。” 但无论如何,当我写到答案时,区别还没有体现出来。它是后来添加的,所以也许这就是让你失望的原因。 (2认同)

Bat*_*eba 32

从左到右评估逗号(也称为表达式分隔)运算符.所以return 2,3;相当于return 3;.

评估x = 2,3;(x = 2), 3;由于运营商的优先权.评估仍然是从左到右,整个表达式的值为3,其副作用是x假设值为2.

  • 你能否编辑和详细说明*表达式分离算子*?就像我在@ songyuanyao的回答评论中提到的,我可以理解为什么`return 2,3`和`return(2,3)`是相同的.我相信前者应该是`(返回2),3`. (2认同)
  • @ prakharsingh95根据C++的语法,`return`只能在以下情况下发生:(a)`return`*expression_opt*`;`,和(b)`return`*braced-init-list*`;` . (2认同)

Bia*_*sta 19

这个说法:

  x = 2,3;
Run Code Online (Sandbox Code Playgroud)

由两个表达式组成:

> x = 2
> 3
Run Code Online (Sandbox Code Playgroud)

由于运算符优先级, =具有比逗号更多的优先级,,因此x = 2被评估和之后 3.那就x等于了2.


return改为:

int f(){ return 2,3; }
Run Code Online (Sandbox Code Playgroud)

语言语法是:

return <expression>
Run Code Online (Sandbox Code Playgroud)

注意 return不是表达的一部分.

所以在这种情况下,将评估两个表达式:

> 2
> 3
Run Code Online (Sandbox Code Playgroud)

但只3返回第二个().

  • UV'd.非常挑剔,但如果你将`<expression>`标记为显式可选(从语法角度来看)会很好. (2认同)
  • 在"x = 2,3"的解析树中有5个表达式.文字"2"和"3"都位于解析树的底部,标识符"x"也是如此.这些都是单独有效的表达式.运算符优先级意味着`=`在解析树中出现_lower_,并将两个表达式`x`和`2`组合成第四个表达式`x = 2`.最后,第五个表达式由逗号运算符连接其两边的"x = 2"和"3"组成.但是,您错误地声明运算符优先级确定了评估的_order_.它没有.评估顺序由排序规则确定. (2认同)
  • 我投票赞成提到回报不是表达的一部分 (2认同)
  • "宏观表达"是一个技术术语吗?当预处理器的意义上的"宏表达式"也存在时,使用它似乎有点令人困惑. (2认同)