使用printf打印出浮动值

ter*_*era 3 c printf pointers

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
  int x, *ptr_x;
  float f , *ptr_f;

  ptr_f = &f;
  ptr_x = &x;
  *ptr_x = 5;
  *ptr_f = 1.5; //printf("%d %f\n", f,x);

  printf ("\n\nxd = %d \t xf = %f \n ff = %f \t fd = %d", x,x,f,f);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

ff =%f的输出不是预期的.

xd = 5 xf = 0.000000
ff = 0.000000 fd = 1073217536

此代码的要点是显示如果使用%d打印浮动值并且打印int值为%f将会发生什么.

为什么即使我使用%f,浮点值也不能正确打印?

Ker*_* SB 15

printf()不是类型安全的.

您传递给的参数printf()将根据对编译器的承诺进行处理.

此外,当通过可变参数传递时,floats被提升为doubles.

因此,当您%f第一次(for xf)承诺编译器时,编译器double从参数中吞噬整个(通常是8个字节),吞噬浮动过程.然后第二个%f切入第二个双尾的零尾数.

这是你的论点的图片:

+-0-1-2-3-+-0-1-2-3-+-0-1-2-3-4-5-6-7-+-0-1-2-3-4-5-6-7-+
|    x    |    x    |        f        |        f        |
+---------+---------+-----------------+-----------------+

%d--------|%f----------------|%f---------------|%d------|
Run Code Online (Sandbox Code Playgroud)

f看起来像这样(已晋升为double):

f = 3FF8000000000000
Run Code Online (Sandbox Code Playgroud)

让我们再次使用值绘制它,并推测您的机器字节序:

| 05000000 | 05000000 | 00000000 0000F83F | 00000000 0000F83F |
| %d, OK   | %f, denormal...    | %f, denormal...   | %d, OK  |
Run Code Online (Sandbox Code Playgroud)

请注意,1073217536是0x3FF80000.

  • 这是高度实现定义的.对于某些编译器,它可能是正确的.对于其他人 - 不是.例如,一些现代的64位编译器传递8字节字段中的所有可变参数,而不管它们的实际大小(而不是如图所示紧密打包它们).如果OP使用这样的编译器,问题可能会隐藏. (3认同)
  • 是的,关于这个答案的所有内容完全取决于机器,并且充满了猜测和虚构.关于它唯一的便携部分是最初的警告. (2认同)