逗号运算符具有最低优先级和从左到右的关联性,因此这保证了以下顺序:
i = ++j, j = i++;
i
将为2,如果j
和i
最初都为0,则j
在此声明后将为1。
但是,C中的类型定义中的逗号分隔符是否也保证了订单?如
int i = 1, j = ++i;
答案 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
比您提出的要多一点,但保证声明顺序。如果你或者读过这篇文章的人不知道希望这会有所帮助。 :)