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

时间:2016-01-28 15:11:38

标签: c int double

所以今天我的班级老师给了我们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用于double。但我想知道当我使用%d时出了什么问题。 我认为存在内存问题(4位到8位)或垃圾。但我想知道有关这个问题的更多细节。它的任务。 TIA

3 个答案:

答案 0 :(得分:3)

  

在printf中使用%d时双变量会发生什么?

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

因此,使用SIGSEGV解决程序崩溃的任何工作都是可能的。

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

答案 1 :(得分:2)

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

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

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

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

处理方式取决于你的printf实现。正如任何未定义的行为:只是避免它。

答案 2 :(得分:1)

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

如果你想知道这个值是怎么来的。双值使用IEEE-754标准编码。使用this converter查看2.3在内存中的显示方式。它是01000000 00000010 01100110 01100110 01100110 01100110 01100110 01100110 in bin,或0x4002666666666666 hex。由于int的大小为4duoble的大小为8(通常是这样,因此在其他平台上可能会有所不同)。

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

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

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

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