C语言为什么不可以用int型存储float型?

今天我在写程序的时候发现了让我疑惑的一点:
#include "stdio.h"

int main() {
        //定义float变量a
    float a = 3.14f;
        //定义int变量b等于a
    int b = a;
    printf("%f\n%f", a, b);
}

运行的结果是

img

打印float数据a,正常输出,但是如果转换为int类型就变成了0,理论上讲int与float都是占四个字节
#include "stdio.h"

int main() {
    printf("%zd\n%zd", sizeof(int), sizeof(float));
}

img

但是为什么他们既然占空间大小一样,却不可以用int类型保存float类型数据呢?
后来我又尝试使用指针,代码如下:
#include "stdio.h"

int main() {
        //定义float变量a
    float a = 3.14f;
        //定义指向a的float指针p
    float* p = &a;
        //将p转换为int型指针
    int* p1 = (int*)p;
    printf("%f\n%f", *p, *p1);
}

img

运行结果还是没有变,为什么同样占用4字节,却不可以用int型变量存储float型变量呢?请问怎么做可以实现用int型变量存储float型?谢谢!

理论上,int型和float型都占用4个字节(或其他字节数,根据编译器和计算机架构)的内存空间。但是它们存储的数据类型不同,int存储整数,而float存储浮点数。两种类型的内存表示方法也不同,int使用二进制表示整数,而float使用IEEE 754标准表示单精度浮点数。因此,不能直接存储float类型的数据到int类型的变量中。

要详细说比较复杂,要用到汇编概念。
简单地说,其实b的值确实是3,你可以通过printf("%d", b)来验证,但是最严重的错误是printf的格式符与参数不匹配。在这里,a是整数但是对应了%f格式说明符。注意,这里printf并不会像变量赋值一样做一些友好的转换! 它会把a用二进制表示,再用IEEE754算法转换成浮点。
一句话概括就是,格式符和参数千万要对应啊!

  • 
     不仅仅是c语言,java也是这样的,用int来
    存储整数,用float来存储小数,如果将float
    数值类型的强制转为int类型的,则小数部分
    的值会丢失,只能得到整数部分的值,如果
    int类型的强制转换为float类型的,也会丢失
    数据,只有.000这样的小数。
     至于你说的intfloat都是占用4个字节,
    为啥不能int存储float类型的这个问题,
    从通俗的角度来说,如果intfloat都能
    互相存储,而不发生数据丢失,那为啥要
    有这两个类型,都能表示的话,只要有一
    种类型就行了。深层次来说,你说的都占
    4个字节,只是说这两种类型的储存的格式
    和长度一样,但是读取格式是不一样的,
    不同的数据类型对应不同的读取器。这涉及
    到编译器那一块的知识。有兴趣可以去找找
    资料学一下。
    望采纳哦!!!
    

这个问题有想法是好的,先不说什么IEEE 754标准表示单精度浮点数,你想啊int 是个整数,你就使劲往里面塞,最后肯定还是一个整数,但是float是小数,那他有小数和整数组成,不能只要整数不要小数了对吧,如果搞个算法把float和int 在存储上统一,那么肯定那个表示值的范围不一样对吧,那与其这样还不如讲float和int分别表示整数和小数,毕竟初中就有实数分有理数和无理数,有理数又分整数和分数,希望对你有帮助

具体原因要看深入理解计算机系统的整型编码和浮点编码规范才能明白.
虽然可以强制转换,但不利于编写程序,这种让人摸不着头脑的写法尽量避免.

#include <stdio.h>

int main()
{
    // 定义float变量a
    float a = 3.14F;

    // 定义int变量b等于a
    int b = *((int *)(&a));

    // 0x4048f5c3
    printf("%f\n%f", a, *((float *)&b));

    return 0;
}