c - printf 的意外输出

标签 c casting printf garbage

int a=5;
float b=3.5;
printf("%d",b);
printf("\n%f",a);

谁能告诉我为什么这段代码显示意外输出(垃圾\n3.5)

最佳答案

您正在为 %d 格式字符串传递一个 float,但是 printf 需要一个 int

printf 是一个可变参数列表函数:printf(const char *format_string,...);

这意味着格式字符串之后的其余参数可以是任何类型和数字,编译器不知道它们应该是什么。由程序员提供 printf 期望的类型的参数。 printf 期望的内容由格式字符串决定。当您在格式字符串中提供 %d 时,printf 函数将期望下一个参数是 int。由于您传递的是 float,因此可能会发生一些奇怪的事情。例如,组成 float 的那些字节可能会被视为一个 int,这不会给您任何有意义的值。

实际上它比那要复杂一点。关于如何将参数传递给可变参数函数有一些特殊的规则。规则之一是 float 值作为 double 传递。这意味着您的 float 值在传递给 printf 之前首先转换为 doubledouble 在您的平台上很可能是八个字节,而 int 只有四个字节。因此 printf 函数可以将 double 值的前四个字节视为 int

也许更糟糕的是,在下一行中,int 被传递到预期为 double 的地方。这意味着 printf 函数可以将 int 的前四个字节视为 double 的一部分,然后读取另外四个字节'甚至是你的论点的一部分。

实际发生的细节因平台而异。该语言只是声明您不应该传递错误类型的参数,并且不保证如果您这样做了就会发生。

关于c - printf 的意外输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17898186/

相关文章:

c - ALSA 配置以启用多个进程之间的设备共享

c - 来自整数的指针,没有强制转换警告

c - 反转字符串变量,或反转打印字符数组

c - printf 命令导致段错误?

c - 使用信号量系统 V 的 Scanf 和 printf

c - "assignment makes integer from pointer without a cast -wint-conversion"

C编程: array

c# - 列表中的 foreach [C#]

c# - 将 LINQ 结果转换到 ObservableCollection

c - 在 PIC 上使用 long long 时的舍入问题