逗号运算符和分号之间是否存在实际的语义差异?

时间:2018-03-26 09:06:55

标签: c operators comma-operator

这是我到目前为止所理解的:

  1. 逗号运算符允许简洁代码,例如: int x = 0, y = 0, z = 0而不是int x = 0; int y = 0; int z = 0;。在这种情况下,它有点像分号的语法糖。

  2. 逗号运算符充当序列点。因此,在代码f(), g();中,函数f()可以保证在g()之前执行并生成所有副作用。但是,如果您使用代码f(); g();

  3. ,情况也是如此
  4. 逗号运算符是一个运算符,而分号只是一个不参与表达式求值的程序标记。由于逗号运算符具有如此低的优先级,因此在这方面它与分号的差别很小。

  5. 所以,我想知道这两种结构在实践中的语义差异是什么?是否存在使用逗号会因使用分号产生不同结果的情况?

4 个答案:

答案 0 :(得分:4)

如果是

int x = 0, y = 0, z = 0 ;

,不是逗号运算符,但它们是逗号分隔符 分号是声明和声明的一部分。

int i = 0;  // declaration
i = i + 5;  // statement

另一方面,逗号运算符是表达式的一部分。也就是说,在预期表达的情况下不能使用分号。例如

if(++i, i < 10) { /*...*/ }  // A semicolon can't be used.

答案 1 :(得分:3)

有些情况下,逗号用作令牌,还有其他情况下逗号为comma operator

引用维基百科,

  

使用逗号标记作为运算符不同于它在函数调用和定义,变量声明,枚举声明和类似结构中的使用,它用作分隔符。

澄清的一个例子,(直接从章节§6.5.17中借用,C11标准)

您可以进行类似

的功能调用
  f(a, (t=3, t+2), c);

这里,(t=3, t+2)中的逗号是逗号运算符,这是有效的并且已被接受。

但是,你不能写

  f(a, (t=3; t+2), c);

这是一个句法错误。

答案 2 :(得分:1)

它确实有所作为的一种情况是:

while(foo(), bar()) {
    ...
}

我不知道是否有任何真正的实际用法,但它确实用逗号编译,但没有用分号编译。

答案 3 :(得分:1)

在其他答案中,逗号运算符得到了相当好的讨论。仍然是分号。

分号(;)是语句终止符,这意味着它终止了任何语句的语法。它还意味着当一个表达式后面跟一个分号时,会变成一个语句:

foo();                // a statement
bar();                // a statement
3+5;                  // a statement
(t=3, t+2);           // a statement
while(foo(), bar());  // a statement

while(foo(), bar()) {
    ;                 // empty statement
}

分号也终止了声明。