将float转换为int指针并返回float?

时间:2017-06-13 04:28:42

标签: c pointers types

有些人可以解释一下这个C程序的行为我试图理解它的行为......

#include<stdio.h>
float x = 3.33,*y,z;
int *a,b;
int main() {
    a = (int *)&x;
    b = (int)x;
    y = (float *)a;
    z = (float)b;
    printf("\nOriginal Value of X: %f \ncasting via pointer A:%d and back Y: %f \ndirect casting B:%d and back Z:%f\n",x,*a,*y,b,z);
}

输出:

Original Value of X: 3.330000                                                                                                                                                   

casting via pointer A:1079320248 and back Y: 3.330000                                                                                                                           

direct casting B:3 and back Z:3.000000     

好的,为什么A的值为1079320248而且它不是一些随机值,X = 3.33的值始终相同,如果X更改为某些值,则会更改不同的价值我期待A之类的东西是3,但不是。{/ p>

2 个答案:

答案 0 :(得分:3)

在您的代码中没有“通过指针A'进行投射”。您只是强制编译器将 [1] NA NA NA NA NA NA NA NA 742.5581 915.8140 1099.0698 1292.3256 [13] 1375.5814 NA NA 1625.3488 1828.6047 2041.8605 2265.1163 2378.3721 NA NA 2718.1395 2831.3953 [25] 2944.6512 3057.9070 3171.1628 NA NA 3510.9302 3624.1860 3737.4419 3850.6977 3963.9535 NA NA [37] NA NA NA NA NA NA 指向浮点值,其中假定它指向一个整数。

使用Reymond Chen在评论部分中指出的page,我们得到3.33的二进制表示形式:

a

现在,使用this页面查找其等效的32位有符号整数。你会得到01000000010101010001111010111000,这是让你困惑的非随机数字。

如果这对你没有任何意义,那就让我说清楚一点吧。 1079320248a都指向相同的二进制值y,它表示两个不同的值(3.33为float,1079320248为int),具体取决于您告诉编译器使用的数据类型为了它。

<强>更新

仅为了学术兴趣,如果您希望printf语句为01000000010101010001111010111000打印3,请将第三个参数替换为:

A

答案 1 :(得分:2)

TL; DR 将指针转换为不同的非兼容类型并返回然后访问最后一个是OK,当您尝试使用不兼容类型的中间指针时问题就开始了

详细说明,您的代码会导致undefined behavior,因为您违反了严格的别名规则。

引用C11,章节§6.5

  

对象的存储值只能由具有其中一个的左值表达式访问   以下类型: 88)

     

- 与对象的有效类型兼容的类型,

     

- 与对象的有效类型兼容的类型的限定版本

     

- 对应于有效类型的有符号或无符号类型   对象,

     

- 对应于合格版本的有符号或无符号类型的类型   有效的对象类型,

     

- 包含其中一种上述类型的聚合或联合类型   成员(包括,递归地,子集合或包含的联合的成员),或

     

- 字符类型。

所以在你的情况下,对于像

这样的定义
 float x = 3.33,*y,z;
 //....
  a = (int *)&x;
  b = (int)x;
  y = (float *)a;

您首先将指向float的指针转换为整数指针,然后将其转换回float *并根据章节§6.3.2.3/ P7中提到的规则

  

指向对象类型的指针可以转换为指向不同对象类型的指针。如果   对于引用的类型,结果指针未正确对齐 68),行为是   未定义。 否则,当再次转换回来时,结果应该等于   原始指针。 [...]

因此,访问y很好,但不是a。您将面临对齐不匹配,从而导致UB。不要试图这样做。尊重类型。