void main()
{
float a=2;
printf("%d",a);
}
在我的机器中,float是4个字节,int是2个字节,字节以little-endian格式存储。
a是0x 00 00 00 02
现在我的机器是小端,字节应该存储为0x 02 00 00 00
现在当我使用%d指定符时,应该获取前2个字节,输出应该是512,但我没有得到那个输出。
有人可以告诉我为什么会这样吗?
答案 0 :(得分:2)
使用错误的格式说明符printf
调用undefined behavior。
在这种特殊情况下,可能发生的事情是浮点类型不会像整数类型一样被推入堆栈。但是你不能依赖这种行为,因为标准没有规定会发生什么。
如果要打印float
中的字节,请指向unsigned char
并循环显示字节:
float a=2;
unsigned char *c = (unsigned char *)&a;
int i;
for (i=0; i<sizeof(float); i++) {
printf("%02x ", c[i]);
}
printf("\n");
此外,假设您的计算机使用IEEE754格式表示浮点数,则2的表示形式不是0x00000002
,而是0x40000000
。
答案 1 :(得分:1)
您好像假设在printf("%d", a)
中,float
的{{1}}值将被放置在传递a
值的同一位置因此,int
参数会int
读取printf
的字节,就好像它们是float
一样。
这不是许多C实现中发生的事情。 C标准并未说明所有参数都以相同的方式或相同的方式传递,无论其类型如何。当您将不匹配的参数传递给int
时,它不会定义行为。在许多C实现中,前几个浮点参数在处理器的浮点寄存器中传递,这些寄存器与通用整数寄存器分开。
如果要检查对象的字节,支持的方法包括:
将指向对象的指针转换为指向printf
的指针,然后通过指向unsigned char
的指针检查字节。
使用unsigned char
将字节复制到另一个对象,例如memcpy
。 (目标对象应与源对象的大小相同,因此这取决于实现。)
声明一个包含两种类型对象的联合,即您要检查的类型和另一种类型,如int x; memcpy(&x, &a, sizeof a);
或int
数组。将值写入联合的一个成员并从另一个成员中读取它。例如,unsigned char
。同样,两个对象的大小应该匹配。