【问题标题】:C: What happens technically when int type is stored in long long type? [duplicate]C:当 int 类型存储在 long long 类型中时,技术上会发生什么? [复制]
【发布时间】:2021-11-01 00:58:01
【问题描述】:
#include <stdio.h>

int main() {
    long long a, b;
    scanf("%d %d", &a, &b);
    printf("%lld", a + b);
    return 0;
}

上面的代码读取两个数字并打印它们的总和。 我知道确切的应该使用格式说明符%lld 而不是%d,我认为这是编译错误的原因。

但是,问题是某些编译器,例如https://www.programiz.com/c-programming/online-compiler/,执行代码时没有任何语法错误,但会打印出如下所示的尴尬值,我根本不明白。

输入:123 -123
输出:235046380240896(此值不断变化)

当 int 类型存储在 long long 类型中时,基础级别发生了什么?

【问题讨论】:

    标签: c types syntax scanf


    【解决方案1】:

    形式上它是未定义的行为,因为格式说明符与类型不匹配。所以理论上任何事情都可能发生。编译器不需要对不匹配的格式字符串与提供的变量进行诊断。

    在实践中,许多(32/64 位)编译器可能会读取 4 个字节并将它们放置在 long long 的 4 个最低有效位置(小端),而最高 4 个最高有效字节保持其不确定值 -也就是说,垃圾,因为变量从未初始化。

    因此在实践中,如果您将 long long 初始化为零,您实际上可能会得到预期的输出,但不能保证它。

    【讨论】:

    • 它也可能将它们置于 4 个最重要的位置。您将获得一致的结果,但它们将是“预期”结果乘以 2^32。
    • 很好的答案。请注意,在大端架构上,归零后您可能仍无法获得预期的输出,因为该值被放置在 4 个最高有效字节中。
    • 将变量初始化为0 不会为OP 问题中的-123 等负输入值产生预期输出。
    【解决方案2】:

    这是未定义的行为,所以任何事情都可能发生。 在实践中最有可能发生的是 scanf() 将您输入的数字存储到每个 64 位 long long 变量的 32 位半中。由于您从未初始化变量,因此另一半包含不可预测的值。这就是为什么您每次都会得到不同的结果。

    【讨论】:

    • OP 的示例输出 235046380240896 支持该输出,其底部 32 位全为零 (0xD5C600000000)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 2013-03-07
    • 2016-04-15
    相关资源
    最近更新 更多