我刚刚遇到基本上执行以下操作的代码:
int a = (1, 2, 3);
我以前从未见过这种符号。这是什么意思?
这是逗号运算符:评估a, b
首先导致a
要评估的原因,然后b
是 ,结果是 的结果b
。
int a = (1, 2, 3);
first 计算1
,然后2
,finally 3
,并使用 last3
进行初始化a
。它在这里没用,但是当 的左操作数,
有副作用时(通常:当它是一个函数调用时)它会很有用。
它使用逗号运算符,它只是按顺序计算每个操作数表达式(在其间引入适当的序列点)并返回最后一个。因此,您的示例实际上等同于int a = 3;
.
但它确实是C和C++中使用最少的运算符之一,不要与函数调用表达式、初始化列表和所有其他地方中使用的逗号混淆。一个不太罕见的用例是 for 循环 ( for(...; ...; ++i,++j)
) 中的多个增量,即使您可能从未想过实际上使用所谓的逗号运算符。
另一个有趣的用例是,为了清楚和简洁起见,尝试将多个概念相关的表达式放入单个语句(如 return)时,例如在具有frexp
怪异指针返回参数的 good old 的实现中(忽略正确的事实C++ 只会返回一对):
double frexp(double arg, int *exp)
{
if(...)
return *exp=..., result;
...
}
这比同等的更精简
double frexp(double arg, int *exp)
{
if(...)
{
*exp = ...;
return result;
}
...
}
Wiki:逗号运算符
i = (a, b, c); // stores c into i
它是逗号运算符。C11 标准讲述了这种运算符的一个用例。
C11标准6:5:17
逗号运算符
逗号运算符的左操作数被评估为 void 表达式;在它的求值和右操作数的求值之间有一个序列点。然后对右操作数求值;结果有它的类型和值。114)
逗号运算符(如本小节所述)不能出现在使用逗号分隔列表中的项目的上下文中(例如函数的参数或初始化程序列表)。另一方面,在这种情况下,它可以用在带括号的表达式中或条件运算符的第二个表达式中。在函数调用 f(a, (t=3, t+2), c) 中,该函数具有三个参数,其中第二个参数的值为 5。
它只计算 1、2 和 3(因为它们只是值,但也可以是函数调用),并将最后一个的值(或返回值)设置为左操作数(在您的示例中为 a)。
也许这将帮助您了解它是如何工作的:
#include <stdio.h>
int toto()
{
printf("toto()\n");
return (21);
}
int tata()
{
printf("tata()\n");
return (42);
}
int main()
{
int a = (toto(), tata());
printf("%d\n", a);
return (0);
}
输出:
toto()
tata()
42
编辑:Tha 的 C 代码,在 C++ 中的工作方式相同
这是逗号运算符。它“包装”多个表达式,从左到右计算它们,整个表达式的值由最后一个子表达式确定。在您的示例中,它的计算结果为3
.
逗号运算符特别方便的一种情况是,如果您想在 for 循环“递增”表达式中执行多项操作,例如递增两个变量。
示例:沿对角线迭代图像,使用x
和y
作为单独的变量。我使用两个单独的变量x
,y
因为我可能想在循环中独立于另一个更改其中一个(请记住,这只是一个愚蠢的例子)。所以我想在for循环的“增量”语句中增加x
和增加:y
for(int x = 0, y = 0; x < width && y < height; ++x, ++y) {
// ... ^^^^^^^^
}
注意for循环的“初始化”表达式不使用逗号操作符;它只是声明了两个变量。