什么时候 ++c 和 c++ 增量完全应用在这里?

mem*_*eme 4 c c++ unary-operator pre-increment post-increment

只是为了看看我对++c/c++运算符的工作原理了解多少,我尝试运行这些 C 程序:

int c = 5;
c = c - c++;
printf("%d\n", c);
Run Code Online (Sandbox Code Playgroud)

打印 1,我猜逻辑是 ++ 在使用它的代码行之后应用,因此c变为= c - c0,并在“下一行”增加一。但对我来说似乎很奇怪,我想更详细地了解操作员优先级应该发生什么。

现在开始:

int c = 5;
c = c - ++c;
printf("%d\n", c);
Run Code Online (Sandbox Code Playgroud)

这个打印0,我真的不明白为什么。如果从左到右解析右手值,我想它会读取c哪个是 5,然后++c哪个是 6,因为它应该立即应用。或者它是否++c在整个右手值计算之前计算,因此它实际上是在做 6 - 6,因为增量还涉及第一次调用c

wal*_*nut 5

对于 C++(所有版本,解释适用于 C++11 及更高版本):

两者都有未定义的行为,这意味着不仅它将返回的值未指定,而且会导致整个程序以未定义的方式运行。

这样做的原因是表达式中的求值顺序仅在某些情况下指定。表达式计算的顺序不遵循源代码中的顺序,并且与运算符优先级或结合性无关。在大多数情况下,编译器可以自由选择对表达式求值的顺序,遵循一些一般规则(例如,运算符的求值在其操作数的值计算之后进行排序等)和某些特定规则(例如&&'s 和||' s 左手操作数总是排右手操作数之前)。

特别是操作数的-计算顺序是未指定的。据说这两个操作数彼此之间是无序的。这本身意味着我们不知道c左侧的c - [...]will 是否评估为c增量之前或之后的值。

然而,有一条更严格的规则禁止c以相对于对同一标量对象的副作用而言无序的方式使用来自标量对象(此处)的值计算。在您的情况下,++c和 都会对c++产生副作用c,但它们与c - [...].左侧的值的使用无关。不遵守此规则会导致未定义的行为。

因此你的编译器可以输出任何它想要的东西,你应该避免编写这样的代码。

有关 C++ 的所有求值顺序规则的详细列表,请参阅cppreference.com。请注意,它们随着 C++ 版本的不同而有所改变,从而定义了越来越多的以前未定义或未指定的行为。但是,这些更改均不适用于您的特定情况。