【问题标题】:What happens to a double variable when %d is used in a printf? [closed]在 printf 中使用 %d 时,double 变量会发生什么情况? [关闭]
【发布时间】:2016-01-28 15:11:38
【问题描述】:

所以今天我的班主任给了我们3个问题,并说要在家研究..我努力得到解决方案。但是没有关于它的确切文章。

代码是:

#include <stdio.h>

int main(void){
    double x = 2.3;

    printf("%d\n", x);
    printf("%d, x\n");
    printf("%d\n", "x");
}

输出是:

  • 1717986918
  • 1717986918, x
  • 4206639

我知道我需要将 %lf 用于双精度。但是我想知道当我使用 %d 时出现了什么问题。 我认为存在内存问题(4 位到 8 位)或垃圾。但我想了解有关该问题的更多详细信息。这是一项任务。 TIA

【问题讨论】:

  • 你做了一件明显错误的事。你的老师知道这是错误的。你知道这是错的。果然,你的程序出错了。 UB,QED。
  • 您错误地认为需要将%lf 用于double,尽管您需要将%Lf 用于long double。 (float 没有 printf 转换说明符,因为用作printf 的可选参数之一的float 类型的值被默认参数提升自动转换为double .)

标签: c int double


【解决方案1】:

当在 printf 中使用 %d 时,double 变量会发生什么情况?

未定义的行为。您不应该滥用 printf 的格式说明符。

因此,从正常工作到使用 SIGSEGV 导致程序崩溃的任何事情都是可能的。

最有可能发生的情况是它会尝试将您的 double 视为 int,并且根据您的操作系统如何保存这些,垃圾会打印出来。

【讨论】:

  • 那么这个值是怎么来的?
  • @HabiburRahman 谁知道?未定义的行为是未定义的。想知道未定义的行为会发生什么是没有意义的。关键是,C 标准并没有规定如何将 double 和 float 数据类型的数据实际存储为二进制。考虑到这一点,试图把它当作一个整数来对待是一场赌博,这可能会也可能不会奏效,或者可能会做一些完全不同的事情。
【解决方案2】:

正如其他人所说,这显然是未定义的行为,但让我们一一看看。

  • 在第一种情况下,您要求打印一个整数并提供一个双精度数。这是未定义的行为,结果也是如此。每次启动程序时它可能会发生变化。

  • 第二种情况,你告诉 printf “嘿,我要给你一个整数”,而你没有。这导致了另一个未定义的行为:printf 在内存中的某处显示了一些未知的东西。

  • 第三种情况与第一种情况类似,但 x 用双引号括起来。双引号表示在 C/C++ 字符链中,由 char* 类型处理。因此,在第一种情况下,您为 printf 提供了错误的类型,这又导致了一次未定义的行为。

它的处理方式取决于您的 printf 实现。就像任何未定义的行为一样:避免它。

【讨论】:

    【解决方案3】:

    正如其他人所说,这是一种未定义的行为。

    如果你想知道这个值是怎么来的。双精度值使用 IEEE-754 标准进行编码。使用this converter 查看2.3 在内存中的样子。它是 bin 中的 01000000 00000010 01100110 01100110 01100110 01100110 01100110 011001100x4002666666666666 十六进制。因为int 的大小是4duoble 的大小是8(通常是这样,在其他平台上可能会有所不同)。

    所以我们采用0x400266660x66666666 值,因为printf 将使用其中之一。我们看到0x66666666 是十进制的 1717986918。

    这就是您获得第一个 1717986918 的方式,我无法想象您是如何收到第二个的,可能是因为类型大小不匹配堆栈没有正确清理并且它再次打印了相同的值。

    关于4206639,情况更加复杂,您将指针传递给字符串,因为"x" 是字符串,'x' 是可以转换为int 的字符。因此,您的指针被视为int 并被打印出来,这个值在每次程序启动时都应该不同。堆栈损坏也可能会影响此值。

    无论如何,这是一个未定义的行为,所以你不应该这样做。根据printf 使用不同的编译器实现,您可能会得到不同的结果。

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 2011-12-19
      相关资源
      最近更新 更多