C 我不知道';我不理解这段代码的输出
我正在学C,老师给了我们一些家庭作业。我们必须确定一些代码的输出。我不明白为什么C 我不知道';我不理解这段代码的输出,c,post-increment,pre-increment,C,Post Increment,Pre Increment,我正在学C,老师给了我们一些家庭作业。我们必须确定一些代码的输出。我不明白为什么y=4 代码如下 int main() { int w = 3, y = 3; printf("w = %i\n", --w + w--); printf("y = %i\n\n", y = w + y++); return 0; } 由于在两个序列点之间修改变量值两次,因此该行为未定义 您应该阅读更多关于序列点的信息。这是标准对其的说明: 在被称为序列点的执行序列中的某些指定点
y=4
代码如下
int main() {
int w = 3, y = 3;
printf("w = %i\n", --w + w--);
printf("y = %i\n\n", y = w + y++);
return 0;
}
由于在两个序列点之间修改变量值两次,因此该行为未定义 您应该阅读更多关于序列点的信息。这是标准对其的说明: 在被称为序列点的执行序列中的某些指定点,先前评估的所有副作用应完整,且后续评估的副作用不得发生 未定义的行为 此代码(至少)在以下两部分中存在未定义的行为(如中所述):
--w + w--
y = w + y++
这意味着你得到的结果不是可移植的,也不是有保证的
说谎代码
除了未定义的行为之外,输出实际上由您决定<代码>printf(“w=%i\n”,--w+w--)看起来像是在打印w
的值(因为它打印w=…
),但它不是在打印w
的值,而是在打印--w+w--
的值(这是未定义的,所以它实际上是在打印编译器编译的--w+w--
的值)
那么w
的值是多少呢?
编译器为--w+w--
生成的代码具有使w
的值为1
的副作用,因为它最初是3
,并且--w
和w--
递减w
。但是,--w+w--
(在编译器生成的代码中,基于您得到的输出,4
。这是什么原因?首先可以计算--w
,它将w
从3
递减到2
,并返回w
的新值,即2
。然后可以计算w-->
已计算,它将w
从2
递减到1
,但返回w
的原始值,即2
。2
和2
之和当然是4
因此,--w+w--
的值是4
,而w
的新值是1
那么y
会发生什么呢?
w
的新值是1
,因此执行时(回想一下y
的值是3
):
y++
的副作用是y
是递增的(但不确定是在赋值之前还是之后发生),但表达式的值是y
,在本例中是3
。因此,您要添加w
,其值是1
,以及y++
,其值是3
。然后将4
赋值给y
,赋值的值是4
,因此您得到了4
作为输出。在y=w+y++
中仍然存在未定义的行为,因为不清楚y
的增量应该在什么时候发生:在分配之前还是之后?让我以一条重要的公共服务公告作为序言:
当你的编译器给你一个警告,任何警告,你最好注意它。你问题中的代码示例会导致未定义的行为——换句话说,C标准不能保证每个编译器都会给出相同的结果,因为你的代码。这总是一件坏事
有了这一点,下面是对正在发生的事情的解释
我稍微修改了您的代码,以查看w的中间值:
#include <stdio.h>
int main(void) {
int w = 3, y = 3;
printf("w = %i\n", --w + w--);
printf("w is actually %d\n", w);
printf("y = %i\n\n", y = w + y++);
return 0;
}
输出是
w = 4
w is actually 1
y = 4
发生了什么?因为编译器从左到右解析语句,所以
--w + w--
似乎会导致以下步骤(对于我的编译器):
结果是求和为2+2
,第一行打印4
,但求和后w
递减为1
。但是,您不能依赖于此行为-这就是编译器抛出警告的原因。正如Eric Postdischil指出的,可能存在执行顺序可能错误的情况与众不同。“不要这样做”是底线——你在追求未定义的行为
请注意,程序打印的w等于4这一事实并不意味着在任何时候都是正确的。正如您所看到的,当您实际打印w
时,它是1
假设编译器按照上述顺序执行这些语句,我们转到下一行:
y = w + y++
我们从w=1
和y=3
开始。这两者的总和是4
,这是表达式的值
y = w + y++
这就是印刷的内容(4)
作为一个副作用,y是递增的。不管怎样,y的值在最后都是4。如果你改变代码,从w=5
开始,你的结果是y=6
。换句话说,y++
的效果被y=
作业覆盖。你的老师假设了一个特定的评估顺序语言不保证的不一致性
假设严格的从左到右评估,并假设立即应用副作用,然后给定w
和y
的起始值,会发生以下情况:
--w
计算为w-1
(2),作为副作用,w
递减;w
现在为2
w--
的计算结果为w
(2),作为副作用,w
;w
现在为1--w+w--
计算结果为4y++
的计算结果为y
,作为副作用,y
;y
现在为4w+y
--w : decrement w, it is now 2
w-- : use the value of '2', but decrement w when you are done
y = w + y++
y = w + y++
x++ + x++
a[i++] = i
y = y++
foo(y++, y++);