【问题标题】:%d with Long Int%d 长整数
【发布时间】:2012-05-06 20:56:04
【问题描述】:

以下代码是否正确?据我了解,它应该无法正常工作,但在 Dev-C++ 编译器上,它可以。有人可以详细解释一下吗?

#include<limits.h>

int main()
{
long int num_case=LONG_MAX;

scanf("%d",&num_case);

printf("%ld",num_case);
return 0;
}

谢谢

【问题讨论】:

标签: c printf long-integer scanf


【解决方案1】:

与标准 C 库告诉您不要做的大多数事情一样,它会调用未定义的行为。未定义意味着它可能在某些条件下工作,但在您最不期望的时候崩溃。

在这种情况下,它可以工作,因为long intint 实际上是相同的数字表示:四字节,二进制补码。对于另一个平台(例如 x86-64 Linux),情况可能并非如此,您可能会看到某种问题。特别是,8 字节 long int 的高位字节将保持未初始化状态。

编辑:问“但它会崩溃”是想错了。根据语言标准,仅仅将未初始化的字节读入long int 类型的变量就可以使C 程序崩溃。我们不需要找到一个这样做的平台示例,就可以理解该程序是错误指定的。这就是我想说的。 C 不会马上把规则手册扔给你,它会等到你移植并打破最初的假设。

【讨论】:

  • 除非 x86-64 是 Windows,其中 long int 保持 32 位。
  • 真的会有问题吗?我的意思是,这个数字不能代表我们想要的,但这不会导致程序以任何方式崩溃,对吧?关于 64 位,唯一真正的 64 位整数类型是 long long,它已在 C99 中引入,是 C++11 标准的一部分。
  • @Geoffroy 继续运行具有未初始化或意外值的程序可能会导致崩溃,尽管我从未提到过崩溃;我说“某种问题”。通常我们希望避免所有的不当行为,而不仅仅是崩溃。在 Mac OS 和 Linux 上,longlong long 都是 64 位;我不知道 Windows 做了其他事情,但它并没有改变任何东西。
【解决方案2】:

通常在 32 位系统上 long int 有 32 位(与 int 相同),而在 64 位系统上 long int 有 64 位(与 long long int 相同)。如果您希望您的代码可移植,请将 scanf 与“%ld”一起使用。

【讨论】:

    【解决方案3】:

    正如 RageD 所说,您确实应该在 scanf() 调用中使用 %ld。它起作用的原因是因为在您的系统上(或者在我看来),intlong int 的大小相同(可能是 4),所以 scanf() 不会覆盖它不应该覆盖的任何内存。

    【讨论】:

      猜你喜欢
      • 2012-11-04
      • 2020-08-17
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 2015-04-21
      • 2011-10-05
      相关资源
      最近更新 更多