2017-02-12 73 views
-3

算术运算符谁能帮我解决这个问题逻辑程序:增量,和c

void main() 
{ 
    int num, a=5; 
    num = -a-- + + ++a; 
    printf("%d %d\n", num, a); 
} 

答:0 5

怎么会呢?任何人都可以解释背后的逻辑?

+3

没有人能解释它,因为表达式没有意义。 –

+0

注意[main()应该在C和C++中返回什么?](http://stackoverflow.com/questions/204476/) –

回答

0

曾几何时,我看到两个积极进取的波士顿司机试图在同一个停车位停车,以至于他们实际上将车撞向对方。非常像这样的事情发生在这里。

此代码还有其他错误,但我们只关注存储在a中的内容。如果我们想象表达式a-- + ++a从左到右进行评估,则首先发生的是a--部分。 a起始为5,因此a--的值为5,并将注释存储到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确实不是保证表达式严格按照从左到右的顺序进行评估,并且确实不是保证a--++a立即更新a的值。试图在一个表达式中更新a的值两次会导致未定义的行为,未定义的行为意味着可能发生任何事情。