任何人都可以帮我解决这个问题
void main()
{
int num, a=5;
num = -a-- + + ++a;
printf("%d %d\n", num, a);
}
答案:0 5
答案 0 :(得分:0)
曾几何时,我看到两个咄咄逼人的波士顿司机试图停在相同的停车位,这样他们就真的把车撞到了对方。非常像这样的事情发生在这里。
此代码还有其他问题,但我们只关注存储在a
中的内容。如果我们想象表达式a-- + ++a
从左到右进行评估,那么首先发生的是a--
部分。 a
的起始值为5,因此a--
的值为5,并附加一条注释,将4存储到a
。想象一下,这张纸条是给第一辆车的司机送货的。
接下来我们到达++a
。暂时假设将4
存储到a
的邮件还没有通过。因此,++a
的值为6,并附加一条注释,将6存储到a
中。想象一下,这张纸条是给第二辆车的司机送货的。
一个很大的问题是,num
的最终价值是多少,但我现在并不担心这一点。我们问一下,a
的最终价值是多少?我们有一个汽车司机试图把它设置为4,一个试图设置为6.但是只有一个停车位标有a
。也许第一个驱动程序首先到达那里并将其设置为4,或者可能是第二个驱动程序到达那里并将其设置为6.或者他们可能在同一时间到达那里并且相互撞击,a
获得从第二辆汽车的前保险杠设置成一块扭曲的金属。 (也许扭曲的金属片看起来有点像5号,所以打印5
是printf
能做的最好的。)
正如我所说,这段代码还有其他问题。首先,我们不应该想象它会从左到右进行评估;根本不保证这一点。我们也不知道++a
部分是应该对a
的原始值,还是受a--
影响的值进行操作。事实上,我们不知道这个表达式应该做什么,也许令人惊讶的事实是,编译器也不知道!不同的编译器会以不同的方式解释这样的表达式不同的答案。没有一个答案是对的,没有一个是错的,因为这个表达式是 undefined 。
表达式未定义,因为在其中有两个不同的尝试来为a
分配新值。 (您将在链接的答案中找到更多关于未定义行为的正式定义。)因此,避免未定义行为的简单规则是,不要尝试两次设置变量的值。一个表达"。
你可能会认为这个表达应该有一个定义明确的解释。你可能会认为它显然应该从左到右进行评估。您可能会认为a--
应该立即将新值存储到a
中,这样可以保证"稍后"部分表达。您可能会想到这些事情,并且他们可能对其他一些编程语言也是如此,但不是C. C 保证表达式从左到右严格评估,而不> em>保证a--
或++a
立即更新a
的值。尝试在一个表达式中两次更新a
的值会导致未定义的行为,未定义的行为意味着任何事情都可能发生。