逻辑程序:C的递增和算术运算符

时间:2017-02-12 12:38:44

标签: c

任何人都可以帮我解决这个问题

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

答案:0 5

但是怎么样?任何人都可以解释背后的逻辑吗?

1 个答案:

答案 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号,所以打印5printf能做的最好的。)

正如我所说,这段代码还有其他问题。首先,我们不应该想象它会从左到右进行评估;根本不保证这一点。我们也不知道++a部分是应该对a的原始值,还是受a--影响的值进行操作。事实上,我们不知道这个表达式应该做什么,也许令人惊讶的事实是,编译器也不知道!不同的编译器会以不同的方式解释这样的表达式不同的答案。没有一个答案是对的,没有一个是错的,因为这个表达式是 undefined

表达式未定义,因为在其中有两个不同的尝试来为a分配新值。 (您将在链接的答案中找到更多关于未定义行为的正式定义。)因此,避免未定义行为的简单规则是,不要尝试两次设置变量的值。一个表达"。

你可能会认为这个表达应该有一个定义明确的解释。你可能会认为它显然应该从左到右进行评估。您可能会认为a--应该立即将新值存储到a中,这样可以保证"稍后"部分表达。您可能会想到这些事情,并且他们可能对其他一些编程语言也是如此,但不是C. C 保证表达式从左到右严格评估,而不 em>保证a--++a立即更新a的值。尝试在一个表达式中两次更新a的值会导致未定义的行为,未定义的行为意味着任何事情都可能发生。