你有一个逗号操作符,所以这是相当明确的定义。子表达式
x++, x++
右侧的意思是“将x 加一并返回x 的旧值,然后将x 加1 并返回x 的旧值。”但是第一个“返回值”被扔掉了,第二部分是分配给y的值,即在第一个“将x加1”部分之后分配给x的值,即1。
逗号运算符总是丢弃其左侧计算的值,并返回其右侧计算的值。
更明确地分解它,我们有
y = (x++, x++);
x++, /* add 1 to x, giving 1, store 1 in x, return 0 (ignored) */
x++ /* add 1 to x, giving 2, store 2 in x, return 1 */
y = ( ); /* so the 1 gets stored in y */
但请注意,由于逗号运算符为您提供了序列点,因此 only 已经很好地定义了它。对于逗号运算符和其他一两个运算符,可以保证左侧的所有内容(x + 1 将这个新值存储回x)首先发生, 在右侧发生任何事情之前。但这对于 C 中的大多数运算符不是正确的。
特别是,如果我们要编写看起来相似的表达式
y = (x++ + x++); /* WRONG, undefined */
没有序列点,所以没有什么可以告诉我们x 的增量发生的顺序,什么值将被加在一起,什么值将分配给y。有关这种未定义表达式的更多信息,请参阅规范问题 Why are these constructs using pre and post-increment undefined behavior?。
哦,回到你原来的问题,你说
由于 , 运算符的优先级是 R-to-L,我预计...
但这在几个方面是错误的。
- 在这种情况下,“右”和“左”等词通常指的是关联性,而不是优先级。
- 逗号运算符的结合性是从左到右,而不是从右到左。
- 逗号运算符的优先级很低(这并不重要)。
- 优先级和关联性实际上根本无法帮助您理解这种求值顺序的谜题。
关于最后一点:我现在不打算在这里写另一篇关于这个主题的长文(参见the other question),但如果你想弄清楚未定义表达式的行为
y = x-- - x--;
通过说“好的,- 运算符的关联性是从左到右的,所以我们知道左侧的 x-- 将首先被评估,然后是右侧的”,那就是一个错误的结论,不会导致对表达式行为的正确预测。