++c 和 c++ 增量何时在此处准确应用?

When are the ++c and c++ increments applied exactly here?

本文关键字:应用 c++ 何时 ++c      更新时间:2023-10-16

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

int c = 5;
c = c - c++;
printf("%dn", c);

打印 1,我想逻辑是 ++ 应用在使用它的代码行之后,所以c变成= c - c即 0,在"下一行"上它增加了 1。但这对我来说似乎很奇怪,我想更详细地了解运营商优先级应该发生什么。

现在开始这个:

int c = 5;
c = c - ++c;
printf("%dn", c);

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

对于C++(所有版本,说明适用于 C++11 及更高版本(:

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

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

特别是未指定计算-操作数的顺序。据说这两个操作数相对于彼此是未排序的。 这本身就意味着我们将不知道c - [...]左侧的c是否会在增量之前或之后计算出c的值。

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

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

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

c = c - c++;

在C语言中,这是一个非常糟糕的主意(a(。不允许在没有干预序列点的情况下修改和修改/使用同一对象,并且该减法运算符不是序列点。

作为序列点的东西可以在ISO标准的附录C中找到。

(

a(从技术上讲,每个操作的行为(c1c++的评估,以及对c的分配(明确定义的,但顺序要么是无序的,要么是不确定的。在前一种情况下,每个部分的操作可以交错,而在后一种情况下,它们不交错,但您不知道这两个部分将以什么顺序完成。

但是,标准C11 6.5/2也明确指出,使用相同变量的测序问题是未定义的行为:

如果标量对象的副作用相对于同一标量

对象上的不同副作用或使用同一标量对象的值计算未排序,则行为是未定义的。如果表达式的子表达式有多个允许的排序,则当任何排序中发生此类未排序的副作用时,行为是未定义的。

最重要的是,这不是你应该做的事情。