逗号运算符是如何工作的 逗号运算符如何在C++中工作?< /P>

逗号运算符是如何工作的 逗号运算符如何在C++中工作?< /P>,c++,comma-operator,C++,Comma Operator,例如,如果我这样做: a = b, c; a最终等于b还是c (是的,我知道这很容易测试-只需在此处记录,以便有人快速找到答案。) 更新:这个问题暴露了使用逗号运算符时的细微差别。仅记录以下内容: a = b, c; // a is set to the value of b! a = (b, c); // a is set to the value of c! 这个问题实际上是受到代码输入错误的启发。计划是什么 a = b; c = d; 变成 a = b, //

例如,如果我这样做:

a = b, c;  
a最终等于b还是c

(是的,我知道这很容易测试-只需在此处记录,以便有人快速找到答案。)

更新:这个问题暴露了使用逗号运算符时的细微差别。仅记录以下内容:

a = b, c;    // a is set to the value of b!

a = (b, c);  // a is set to the value of c!
这个问题实际上是受到代码输入错误的启发。计划是什么

a = b;
c = d;
变成

a = b,    //  <-  Note comma typo!
c = d;

a=b,//它将等于
b


逗号运算符的优先级低于赋值。

b的值将被赋值给a。
C./P>

不会发生任何事情,注意C++中的逗号运算符可能会过载。因此,实际行为可能与预期行为大不相同

例如,非常巧妙地使用逗号运算符来实现符号表的列表初始值设定项。因此,它使以下语法成为可能和有意义的:

keywords = "and", "or", "not", "xor";
请注意,由于运算符的优先级,代码(有意地!)与

(((keywords = "and"), "or"), "not"), "xor";
也就是说,调用的第一个操作符是
keywords.operator=(“and”)
,它返回一个代理对象,其余的
操作符将在该对象上调用:

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");

a的值将等于b,因为逗号运算符的优先级低于赋值运算符。

a
的值将是
b
,但表达式的值将是
c
。就是在

d = (a = b, c);

a
将等于
b
d
将等于
c

在所有c/c++运算符中,逗号运算符的优先级最低。因此,它总是最后一个绑定到表达式,这意味着:

a = b, c;
相当于:

(a = b), c;
另一个有趣的事实是逗号运算符引入了一个。这意味着表达式:

a+b, c(), d
保证按顺序计算其三个子表达式(a+bc()d)。如果它们有副作用,这是非常重要的。通常,编译器被允许按照他们认为合适的顺序计算子表达式;例如,在函数调用中:

someFunc(arg1, arg2, arg3)

参数可以按任意顺序计算。请注意,函数调用中的逗号不是运算符;它们是分隔符。

第一件事是:逗号实际上不是运算符,对于编译器来说,它只是一个标记,在上下文中与其他标记一起获得意义

这意味着什么?为什么要麻烦呢? 示例1:

为了理解不同上下文中相同标记的含义之间的差异,我们看一看这个示例:

class Example {
   Foo<int, char*> ContentA;
}
逗号的含义取决于使用上下文,这里它是
结构的
上下文

上下文中的逗号实际上是什么意思? 更为复杂的是(就像在C++中一样),逗号运算符本身可能会被重载(感谢您指出这一点)

回到问题上来,代码

a = b, c;
对编译器来说意味着

(a = b), c;
由于
=
令牌/运算符的优先级高于
令牌的优先级

这是在上下文中解释的

a = b;
c;
(请注意,解释取决于上下文,这里既不是函数/方法调用,也不是模板安装。)

逗号运算符:

  • 具有最低的优先级
  • 是左关联的
为所有类型(内置和自定义)定义了逗号运算符的默认版本,其工作原理如下-给定
exprA,exprB

  • exprA
    进行评估
  • exprA
    的结果被忽略
  • exprB
    进行评估
  • exprB
    的结果作为整个表达式的结果返回
对于大多数运算符,编译器可以选择执行顺序,如果不影响最终结果,甚至需要跳过执行(例如,
false&&foo()
将跳过对
foo
的调用)。然而,逗号运算符的情况并非如此,上述步骤将始终发生*

实际上,默认的逗号运算符的工作方式几乎与分号相同。不同之处在于,两个用分号分隔的表达式形成两个单独的语句,而逗号分隔将所有语句保持为单个表达式。这就是为什么在以下场景中有时会使用逗号运算符:

  • C语法需要一个表达式,而不是一个语句。e、 g.在
    if(此处)
  • C语法需要一条语句,而不是更多,例如在
    for
    循环
    for(此处;)
  • 当您想跳过大括号并保留一条语句时:
    if(foo)HERE(请不要这样做,它真的很难看!)
当语句不是表达式时,分号不能替换为逗号。例如,这些是不允许的:

  • (foo,if(foo)bar)
    if
    不是表达式)
  • int x,int y(变量声明不是表达式)

就你而言,我们有:

  • a=b,c,相当于
    a=b;c
    ,假设
    a
    的类型不会重载逗号运算符
  • a=b,c=d相当于
    a=b;c=d
    ,假设
    a
    的类型不会重载逗号运算符

请注意,并非每个逗号实际上都是逗号运算符。有些逗号具有完全不同的含义:

  • inta,b---变量声明列表以逗号分隔,但这些不是逗号运算符
  • inta=5,b=3---这也是一个逗号分隔的变量声明列表
  • foo(x,y)
    ——逗号分隔的参数
    a = b;
    c;
    
    #include<stdio.h>
    int main()
    {
              int i;
              i = (1,2,3);
              printf("i:%d\n",i);
              return 0;
    }
    
     int main()
    {
          int i;
          i = 1,2,3;
          printf("i:%d\n",i);
          return 0;
    }