给出以下代码片段:
int *iptr;
float *fptr;
float fval;
fval = 0.0;
fptr = &fval;
iptr = fptr;
printf("%d \n", *iptr);
fval = 1.0;
printf("%d \n", *iptr);
输出结果为:
0
1065353216
为什么第一个print语句至少大致匹配与* iptr(0.0)关联的值,但第二个print语句没有?
答案 0 :(得分:12)
当您编写printf("%d \n", *iptr);
时,您要求printf
将iptr
指向的值解释为整数。
恰好float
0
版本的int
由0
0
版本1.0
表示。特别是,这些位都是int
。
但是,任意浮点数(例如{{1}})将具有不同的位表示(由IEEE标准定义),这在解释为{{1}}时没有意义。
这个Wikipedia article解释了浮点如何表示为位。
答案 1 :(得分:3)
语句iptr = fptr;
将调用未定义的行为。
因此推测结果没有多大意义。
答案 2 :(得分:3)
@merlin非常清楚地解释了代码的输出。但是,还有更多内容,所以我会在这里添加它。您的代码违反了strict aliasing rule并调用了未定义的行为。严格别名规则意味着不同的指针类型不应指向相同的内存位置。
iptr = fptr;
iptr
的类型为int *
,fptr
的类型为float *
。此语句将fptr
分配给iptr
- 另一种类型 - 这意味着现在都指向fval
。这打破了严格的别名规则。这会导致未定义的行为,这意味着不可预测的行为。该标准对实施这些案件没有要求。简而言之,您应该避免导致未定义行为的代码。
答案 3 :(得分:2)
答案 4 :(得分:1)
零浮点数由零组成。任何其他数字不仅仅是数字而是指数和尾数 - 当然它们都不是你的数字。
答案 5 :(得分:1)
浮点数以IEEE754格式存储,其中1.0之类的数字的值与1完全不同(它是偏移量以允许负数和指数)。您不能将float打印为int,并且结果类似于分配给float的数字。