为什么答案总是等于5?

时间:2019-02-26 09:22:02

标签: c++ math

提供此代码:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int k, x;

    while(k > x-3) {
         k--;
         // cout << "x = " << x << "\n";
    }
    x++, k--;

    int aux = abs(k-x);
    cout << aux;
}

当我们运行它时,它总是弹出一个常数x(x = 50),并且整数k和x之间的绝对值始终为5。能否请您解释一下为什么以及它如何工作?

3 个答案:

答案 0 :(得分:4)

在约束“ k大于x”的情况下,这段代码在这里

while(k > x-3) {
     k--;
     // cout << "x = " << x << "\n";
}

k减少为3 x

下一行x++, k++;将它们都增加1,但不会改变结果。 k仍比3x

k-x-3,而abs(k-x)3,因此为什么程序总是打印3。当然,假设kx都已初始化,并且kx大。用kx未初始化发布的程序表现出未定义的行为,因此无法保证会发生什么。同样,如阿空加瓜所指出的那样,如果x小于INT_MIN + 3,也会导致不确定的行为。

答案 1 :(得分:0)

Matthieu和πάνταῥεῖ是正确的:这是经典的未定义行为。 (将其设为 undefined 而非简单地定义为 unspecified 实现定义的一个基本原理是,某些体系结构具有未初始化寄存器的标志并且会被捕获。)编译器实际上可以自由地将其编译为空程序:读取未初始化的变量可能会导致任何东西 —而 nothing anything 的子集。未定义行为之后的所有后续代码都被前面的错误“污染”,可以忽略。请注意,不同的体系结构和不同的编译器,甚至可能是不同的C标准库(使用相同的编译器!)可能会得出不同的结果。甚至不同的编译器标记(关于优化或函数调用约定)也可能会更改此不确定的行为。

此答案的其余部分适用于该问题的版本,其中循环后的行读取x++, k++;(而不是现在的k--)。

但是您遇到了一致的行为,问题是为什么它是一致的。第一个假设是编译器不会简单地生成代码以输出“ 5”(它可以合法地),而是实际上“天真”地生成与C语句相对应的机器代码。我们将按照声明进行推理。

然后,该行为表明x和k所在的存储位置包含立即使k > x -3为假的值。 (否则,k将递减,直到相差为3,而不是5)。

如果条件为假,变量差将不会改变;从中我们可以得出结论,从x-k == 5开始它是5。如果省略abs(),则输出应为-5

变量具有这些一致的初始值的原因可能与操作系统或C运行时环境在程序启动时所做的事情有关,例如初始化标准流。尝试使用printf而不是cout来查看结果是否更改。

答案 2 :(得分:0)

我真的认为您应该尝试两个任意数字。 例如,假设我们正在使用k= 10 & x=8。 您的循环如下所示:    While(10>5) 10-1=9 ...依此类推,直到K不大于(X-3)。 您将得到k = 5,x是相同的值,8。 在while循环之后,您递减k,然后递增x,因此k = 4和x = 9。 Abs(k-x) = 5

如果您需要更多理论上的解释,则循环将使您的两个变量之间的差为3,则X将大于K。 在循环之后,您递减K并递增X,它们之间的差总是5。