C语言前缀后缀问题

C语言前缀后缀问题,c,prefix,postfix-notation,C,Prefix,Postfix Notation,我用c写了以下代码 int x = 8; x -= --x - x--; printf("%d", x); 它正在打印6,但根据我的逻辑,应该将语句转换为(从右向左执行) 所以答案应该是-8 有人能说出这里发生了什么吗?这是未定义的行为。C99标准§6.5¨2规定 在上一个序列点和下一个序列点之间,对象应具有 通过表达式求值最多修改一次的存储值。 此外,应仅读取先前值以确定值 储存 现在,这里需要注意的重要一点是,-运算符的操作数的计算是相对不排序的。这意味着不确定将首先计算哪个子表达式(x-

我用c写了以下代码

int x = 8;
x -= --x - x--;
printf("%d", x);
它正在打印6,但根据我的逻辑,应该将语句转换为(从右向左执行)

所以答案应该是-8


有人能说出这里发生了什么吗?

这是未定义的行为。C99标准§6.5¨2规定

在上一个序列点和下一个序列点之间,对象应具有 通过表达式求值最多修改一次的存储值。 此外,应仅读取先前值以确定值 储存

现在,这里需要注意的重要一点是,
-
运算符的操作数的计算是相对不排序的。这意味着不确定将首先计算哪个子表达式
(x-(-x))
(x-)

从这篇优秀的文章中引用-

C中没有从左到右或从右到左求值的概念, 这不能与从左到右和从右到左混淆 运算符的关联性:表达式a+b+c解析为(a+ b) +c,因为运算符+从左到右的关联性,但 子表达式c可以首先(或最后)求值,也可以同时求值 在运行时作为a或b)

第二个需要注意的重要事项是在上面的语句中,
x
的值由于表达式
--x
x--
的副作用被修改了两次。这两个表达式的计算之间没有序列点,因此不能保证副作用何时发生。因此,参考标准中的上述部分,它是未定义的行为

结合上述两点,表达式可以计算为多个值

int x = 8;
x = (x - (--x)) - (x--);
//  (a)   (b)      (c)   name of the sub expressions

// assume (c) is evaluated first and side effect
// takes place immediately. Then (b) is evaluated and
// side effect takes place immediately

x = (6 - (6)) - (8);   // -8

// assume (a) is evaluated first, then (b)
// however the side effect of (b) does not take
// place before (c) gets evaluated          

x = (8 - (7)) - (7);   // -6      

这只是两个示例,用于说明执行语句后
x
可能具有的不同值。这并不意味着
x
将始终具有所有可能值中的一个值。该标准称其为未定义的行为,这意味着该行为是不可预测的。该标准未对处理此类情况的实施提出任何要求。未定义的行为意味着任何事情都可能发生,从后台进程飞出到硬盘格式化。您应该始终避免编写调用未定义行为的代码。有关更多详细信息,请阅读此-。

这是未定义的行为。C99标准§6.5¨2规定

在上一个序列点和下一个序列点之间,对象应具有 通过表达式求值最多修改一次的存储值。 此外,应仅读取先前值以确定值 储存

现在,这里需要注意的重要一点是,
-
运算符的操作数的计算是相对不排序的。这意味着不确定将首先计算哪个子表达式
(x-(-x))
(x-)

从这篇优秀的文章中引用-

C中没有从左到右或从右到左求值的概念, 这不能与从左到右和从右到左混淆 运算符的关联性:表达式a+b+c解析为(a+ b) +c,因为运算符+从左到右的关联性,但 子表达式c可以首先(或最后)求值,也可以同时求值 在运行时作为a或b)

第二个需要注意的重要事项是在上面的语句中,
x
的值由于表达式
--x
x--
的副作用被修改了两次。这两个表达式的计算之间没有序列点,因此不能保证副作用何时发生。因此,参考标准中的上述部分,它是未定义的行为

结合上述两点,表达式可以计算为多个值

int x = 8;
x = (x - (--x)) - (x--);
//  (a)   (b)      (c)   name of the sub expressions

// assume (c) is evaluated first and side effect
// takes place immediately. Then (b) is evaluated and
// side effect takes place immediately

x = (6 - (6)) - (8);   // -8

// assume (a) is evaluated first, then (b)
// however the side effect of (b) does not take
// place before (c) gets evaluated          

x = (8 - (7)) - (7);   // -6      

这只是两个示例,用于说明执行语句后
x
可能具有的不同值。这并不意味着
x
将始终具有所有可能值中的一个值。该标准称其为未定义的行为,这意味着该行为是不可预测的。该标准未对处理此类情况的实施提出任何要求。未定义的行为意味着任何事情都可能发生,从后台进程飞出到硬盘格式化。您应该始终避免编写调用未定义行为的代码。有关更多详细信息,请阅读此-。

这是未定义的行为。C99标准§6.5¨2规定

在上一个序列点和下一个序列点之间,对象应具有 通过表达式求值最多修改一次的存储值。 此外,应仅读取先前值以确定值 储存

现在,这里需要注意的重要一点是,
-
运算符的操作数的计算是相对不排序的。这意味着不确定将首先计算哪个子表达式
(x-(-x))
(x-)

从这篇优秀的文章中引用-

C中没有从左到右或从右到左求值的概念, 这不能与从左到右和从右到左混淆 运算符的关联性:表达式a+b+c解析为(a+ b) +c,因为运算符+从左到右的关联性,但 子表达式c可以首先(或最后)求值,也可以同时求值 在运行时作为a或b)

第二个需要注意的重要事项是在上面的语句中,
x
的值由于表达式
--x
x--
的副作用被修改了两次。这两个表达式的计算之间没有序列点,因此不能保证副作用何时发生。因此,关于
int x = 8;
x = (x - (--x)) - (x--);
//  (a)   (b)      (c)   name of the sub expressions

// assume (c) is evaluated first and side effect
// takes place immediately. Then (b) is evaluated and
// side effect takes place immediately

x = (6 - (6)) - (8);   // -8

// assume (a) is evaluated first, then (b)
// however the side effect of (b) does not take
// place before (c) gets evaluated          

x = (8 - (7)) - (7);   // -6