C++ 逗号运算符如何工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the Comma Operator work
提问by Joe Schneider
How does the comma operator work in C++?
逗号运算符如何在 C++ 中工作?
For instance, if I do:
例如,如果我这样做:
a = b, c;
Does a end up equaling b or c?
a 最终等于 b 还是 c?
(Yes, I know this is easy to test - just documenting on here for someone to find the answer quickly.)
(是的,我知道这很容易测试 - 只是在这里记录,以便有人快速找到答案。)
Update:This question has exposed a nuance when using the comma operator. Just to document this:
更新:这个问题暴露了使用逗号运算符时的细微差别。只是为了记录这一点:
a = b, c; // a is set to the value of b!
a = (b, c); // a is set to the value of c!
This question was actually inspired by a typo in code. What was intended to be
这个问题实际上是受代码中的错字启发。什么是打算
a = b;
c = d;
Turned into
转换成
a = b, // <- Note comma typo!
c = d;
采纳答案by Leon Timmermans
It would be equal to b
.
这将等于b
。
The comma operator has a lower precedence than assignment.
逗号运算符的优先级低于赋值。
回答by Konrad Rudolph
Take care to notice that the comma operator may be overloaded in C++. The actual behaviour may thus be very different from the one expected.
请注意逗号运算符可能在 C++ 中被重载。因此,实际行为可能与预期的非常不同。
As an example, Boost.Spirituses the comma operator quite cleverly to implement list initializers for symbol tables. Thus, it makes the following syntax possible and meaningful:
例如,Boost.Spirit非常巧妙地使用逗号运算符来实现符号表的列表初始值设定项。因此,它使以下语法成为可能且有意义:
keywords = "and", "or", "not", "xor";
Notice that due to operator precedence, the code is (intentionally!) identical to
请注意,由于运算符优先级,代码(有意!)与
(((keywords = "and"), "or"), "not"), "xor";
That is, the first operator called is keywords.operator =("and")
which returns a proxy object on which the remaining operator,
s are invoked:
也就是说,调用的第一个运算符 iskeywords.operator =("and")
返回一个代理对象,其余operator,
s在该对象上被调用:
keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");
回答by efotinis
The comma operator has the lowestprecedence of all C/C++ operators. Therefore it's always the last one to bind to an expression, meaning this:
逗号运算符在所有 C/C++ 运算符中的优先级最低。因此它总是最后一个绑定到表达式,意思是:
a = b, c;
is equivalent to:
相当于:
(a = b), c;
Another interesting fact is that the comma operator introduces a sequence point. This means that the expression:
另一个有趣的事实是逗号运算符引入了一个序列点。这意味着表达式:
a+b, c(), d
is guaranteed to have its three subexpressions (a+b, c()and d) evaluated in order. This is significant if they have side-effects. Normally compilers are allowed to evaluate subexpressions in whatever order they find fit; for example, in a function call:
保证按顺序计算其三个子表达式(a+b、c()和d)。如果它们有副作用,这很重要。通常,编译器可以按照它们认为合适的任何顺序对子表达式求值;例如,在函数调用中:
someFunc(arg1, arg2, arg3)
arguments can be evaluated in an arbitrary order. Note that the commas in the function call are notoperators; they are separators.
可以按任意顺序评估参数。注意函数调用中的逗号不是运算符;它们是分隔符。
回答by CygnusX1
The comma operator:
逗号运算符:
- has the lowest precedence
- is left-associative
- 具有最低优先级
- 是左结合的
A default version of comma operator is defined for all types (built-in and custom), and it works as follows - given exprA , exprB
:
为所有类型(内置和自定义)定义了默认版本的逗号运算符,其工作方式如下 - 给定exprA , exprB
:
exprA
is evaluated- the result of
exprA
is ignored exprB
is evaluated- the result of
exprB
is returned as the result of the whole expression
exprA
被评估- 结果
exprA
被忽略 exprB
被评估- 的结果
exprB
作为整个表达式的结果返回
With most operators, the compiler is allowed to choose the order of execution and it is even required to skip the execution whatsoever if it does not affect the final result (e.g. false && foo()
will skip the call to foo
). This is however not the case for comma operator and the above steps will always happen*.
对于大多数运算符,允许编译器选择执行顺序,如果不影响最终结果,甚至需要跳过执行(例如false && foo()
将跳过对 的调用foo
)。然而,逗号运算符并非如此,上述步骤将始终发生*。
In practice, the default comma operator works almost the same way as a semicolon. The difference is that two expressions separated by a semicolon form two separate statements, while comma-separation keeps all as a single expression. This is why comma operator is sometimes used in the following scenarios:
实际上,默认的逗号运算符的工作方式与分号几乎相同。区别在于用分号分隔的两个表达式形成两个单独的语句,而逗号分隔将所有表达式保留为单个表达式。这就是为什么有时在以下场景中使用逗号运算符的原因:
- C syntax requires an single expression, not a statement. e.g. in
if( HERE )
- C syntax requires a single statement, not more, e.g. in the initialization of the
for
loopfor ( HERE ; ; )
- When you want to skip curly braces and keep a single statement:
if (foo) HERE ;
(please don't do that, it's really ugly!)
- C 语法需要单个表达式,而不是语句。例如在
if( HERE )
- C 语法需要一条语句,而不是更多,例如在
for
循环的初始化中for ( HERE ; ; )
- 当你想跳过花括号而只保留一个语句时:(
if (foo) HERE ;
请不要那样做,真的很丑!)
When a statement is not an expression, semicolon cannot be replaced by a comma. For example these are disallowed:
当语句不是表达式时,分号不能用逗号代替。例如,这些是不允许的:
(foo, if (foo) bar)
(if
is not an expression)- int x, int y (variable declaration is not an expression)
(foo, if (foo) bar)
(if
不是表达式)- int x, int y(变量声明不是表达式)
In your case we have:
在您的情况下,我们有:
a=b, c;
, equivalent toa=b; c;
, assuming thata
is of type that does not overload the comma operator.a = b, c = d;
equivalent toa=b; c=d;
, assuming thata
is of type that does not overload the comma operator.
a=b, c;
, 相当于a=b; c;
, 假设它a
的类型不会重载逗号运算符。a = b, c = d;
等价于a=b; c=d;
,假设它a
的类型不重载逗号运算符。
Do note that not every comma is actually a comma operator. Some commas which have a completely different meaning:
请注意,并非每个逗号实际上都是逗号运算符。一些具有完全不同含义的逗号:
int a, b;
--- variable declaration list is comma separated, but these are not comma operatorsint a=5, b=3;
--- this is also a comma separated variable declaration listfoo(x,y)
--- comma-separated argument list. In fact,x
andy
can be evaluated in anyorder!FOO(x,y)
--- comma-separated macro argument listfoo<a,b>
--- comma-separated template argument listint foo(int a, int b)
--- comma-separated parameter listFoo::Foo() : a(5), b(3) {}
--- comma-separated initializer list in a class constructor
int a, b;
--- 变量声明列表以逗号分隔,但这些不是逗号运算符int a=5, b=3;
--- 这也是一个逗号分隔的变量声明列表foo(x,y)
--- 逗号分隔的参数列表。事实上,x
并且y
可以在被评估的任何命令!FOO(x,y)
--- 逗号分隔的宏参数列表foo<a,b>
--- 逗号分隔的模板参数列表int foo(int a, int b)
--- 逗号分隔的参数列表Foo::Foo() : a(5), b(3) {}
--- 类构造函数中逗号分隔的初始化列表
*This is not entirely true if you apply optimizations. If the compiler recognizes that certain piece of code has absolutely no impact on the rest, it will remove the unnecessary statements.
*如果您应用优化,这并不完全正确。如果编译器识别出某段代码对其余代码完全没有影响,它将删除不必要的语句。
Further reading: http://en.wikipedia.org/wiki/Comma_operator
回答by MobyDX
The value of a
will be b
, but the value of the expressionwill be c
. That is, in
的值a
将是b
,但表达式的值将是c
。也就是说,在
d = (a = b, c);
a would be equal to b
, and d
would be equal to c
.
a 将等于b
,并且d
将等于c
。
回答by prakash
b's value will be assigned to a. Nothing will happen to c
b 的值将分配给 a。什么都不会发生在 c
回答by Jason Carreiro
The value of a will be equal to b, since the comma operator has a lower precedence than the assignment operator.
a 的值将等于 b,因为逗号运算符的优先级低于赋值运算符。
回答by Roopam
Yes Comma operator has low precedence than Assignment operator
是逗号运算符的优先级低于赋值运算符
#include<stdio.h>
int main()
{
int i;
i = (1,2,3);
printf("i:%d\n",i);
return 0;
}
Output : i=3
Because comma operator always return rightmost value.
In case of comma operator with Assignment Operator:
输出:i=3
因为逗号运算符总是返回最右边的值。
在逗号运算符和赋值运算符的情况下:
int main()
{
int i;
i = 1,2,3;
printf("i:%d\n",i);
return 0;
}
Ouput: i=1
As we know comma operator has lower precedence than assignment.....
输出:i=1
正如我们所知,逗号运算符的优先级低于赋值.....
回答by Quonux
First things first:Comma is actually not an operator, for the compiler it is just a token which gets a meaning in contextwith other tokens.
首先:逗号实际上不是运算符,对于编译器来说,它只是一个标记,它在与其他标记的上下文中获得含义。
What does this mean and why bother?
这是什么意思,为什么要打扰?
Example 1:
示例 1:
To understand the difference between the meaning of the same token in a different context we take a look at this example:
为了理解不同上下文中相同标记的含义之间的差异,我们看一下这个例子:
class Example {
Foo<int, char*> ContentA;
}
Usually a C++ beginner would think that this expression could/would compare things but it is absolutly wrong, the meaning of the <
, >
and ,
tokens depent on the context of use.
通常 C++ 初学者会认为这个表达式可以/会比较事物,但它绝对是错误的<
,>
和,
标记的含义取决于使用的上下文。
The correct interpretation of the example above is of course that it is an instatiation of a template.
上面例子的正确解释当然是它是一个模板的实例化。
Example 2:
示例 2:
When we write a typically for loop with more than one initialisation variable and/or more than one expressions that should be done after each iteration of the loop we use comma too:
当我们编写一个典型的 for 循环时,它有多个初始化变量和/或多个应该在循环的每次迭代后完成的表达式,我们也使用逗号:
for(a=5,b=0;a<42;a++,b--)
...
The meaning of the comma depends on the context of use, here it is the context of the for
construction.
逗号的含义取决于使用的上下文,这里是for
构造的上下文。
What does a comma in context actually mean?
上下文中的逗号实际上是什么意思?
To complicate it even more (as always in C++) the comma operator can itself be overloaded (thanks to Konrad Rudolphfor pointing that out).
更复杂的是(就像在 C++ 中一样)逗号运算符本身可以重载(感谢Konrad Rudolph指出这一点)。
To come back to the question, the Code
回到这个问题,守则
a = b, c;
means for the compiler something like
对编译器来说意味着类似
(a = b), c;
because the priorityof the =
token/operator is higher than the priority of the ,
token.
因为优先的的=
令牌/操作比的优先级更高的,
令牌。
and this is interpreted in context like
这是在上下文中解释的
a = b;
c;
(note that the interpretation depend on context, here it it neither a function/method call or a template instatiation.)
(请注意,解释取决于上下文,这里它既不是函数/方法调用,也不是模板实例化。)