C中的类型定义中的逗号分隔符是否保证顺序?

时间:2015-06-13 04:28:17

标签: c c99 c11

逗号运算符具有最低优先级和从左到右的关联性,因此这保证了以下顺序:

i = ++j, j = i++;

i将为2,如果ji最初都为0,则j在此声明后将为1。

但是,C中的类型定义中的逗号分隔符是否也保证了订单?如

int i = 1, j = ++i;

3 个答案:

答案 0 :(得分:19)

使用逗号运算符i = ++j, j = i++;的示例是明确定义的,因为逗号运算符是序列点。

优先级/关联性不足以保证这一点 - 它们与评估顺序和序列点不同。例如,i * 2 + i++ * 3未定义,因为没有序列点。

声明者之间的逗号分隔符 ,例如int i = 1, j = i++;,也是一个序列点。这包含在C11 6.7.6 / 3,C99 6.7.5 / 3:

  

完整声明符是一个不属于另一个声明符的声明符。完整声明符的结尾是一个序列点。

所以在i = 1之后有一个序列点,这个代码是明确定义的。

但是,函数参数f(i, i++)之间的逗号分隔符不是序列点;这样代码就会导致未定义的行为。

注意:在C11中,术语序列点主要被更复杂的序列关系所取代,以便清楚地指定线程模型,但这并不影响上述讨论

答案 1 :(得分:-1)

是的,这就是原因。想想逗号说的是什么。所有它说的是“嘿,我有一个我想在这个逗号的左边做的事情,一旦你做了那件事去右边的东西也做了。你也可以把它想象成一个较短的方法

int i = 1;
int j = i++;

我已经被分配到内存中的某个位置,所以j发生的一切就是它存储在i中的值,递增它,并将它设置为等于j。

所以在

的情况下
int i = 1, j = ++i;

你所说的只是创建一个整数,将其设置为1,现在转到下一个命令,这将是一个名为j的int,并将其设置为等于增量时的任何值。

所以要完全回答你的问题,是的,它保证了订单,因为编译器将从上到下执行所有操作,除非另有说明。

答案 2 :(得分:-2)

假设C在这方面与C#相同,逗号分隔值(int i = 0,j = 0;)应保持有序。

i ++ vs ++ i的不同之处在于验证时间:

int i = 0;

bool iGTZ = i++ > 0;//false

i = 0; iGTZ = ++i > 0;//true

比您提出的要多一点,但保证声明顺序。如果你或者读过这篇文章的人不知道希望这会有所帮助。 :)