main()
{
int x = 0;
int y;
y = (x++, x++);
printf("%d", y);
}
由于,
运算符的优先级是 R 到 L,我预计 o/p 为 0,但在编译代码时给出 o/p 为 1。
你有一个逗号运算符,所以这是相当明确的。 子表达式
x++, x++
右侧表示"将 1 添加到x
并返回x
的旧值,然后将 1 添加到x
并返回x
的旧值"。 但是第一个"返回值"被丢弃,第二部分是分配给y
的,即第一个"加1到x
"部分之后的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 */
但请注意,这之所以被明确定义,只是因为逗号运算符为您提供的序列点。 对于逗号运算符和其他一两个运算符,可以保证左侧的所有内容(x + 1
的计算和将此新值存储回x
)首先发生,然后右侧发生任何事情。 但对于 C 语言中的大多数运算符来说,情况并非如此。
特别是,如果我们要编写外观相似的表达式
y = (x++ + x++); /* WRONG, undefined */
不会有序列点,因此没有什么可以告诉我们x
增量发生的顺序,哪些值将相加,哪些值将分配给y
。 请参阅规范问题 为什么这些构造使用前增量和后增量未定义行为?有关这种未定义表达式的更多信息。
哦,回到你最初的问题,你说
由于 的优先级是 R 到 L,我预计...
但这在几个方面是错误的。
- 在这种情况下,像"右"和"左"这样的词通常是指结合性,而不是优先权。
- 逗号运算符的关联性是从左到右,而不是从右到左。
- 逗号运算符的优先级非常低(这并不重要)。
- 优先级和关联性实际上根本无法帮助您理解这样的评估顺序难题。
关于最后一点:我现在不打算在这里写另一篇关于这个主题的长文(见另一个问题),但如果你想弄清楚未定义表达式的行为
y = x-- - x--;
通过说"好的,-
运算符的关联性是从左到右的,所以我们知道左手x--
将首先被评估,然后是右手的",这将是一个错误的结论,这不会导致对表达式行为的正确预测。