当前位置 博文首页 > mac_timmy:C语言中整型和浮点型数据在内存的存储

    mac_timmy:C语言中整型和浮点型数据在内存的存储

    作者:[db:作者] 时间:2021-08-15 13:34

    一、整型数据的分类

    类型字节数输出格式
    unsigned int4%d
    [signed] int4%u
    unsigned short [int]2%hd
    [signed] short [int]2%hu
    unsigned long [int]4 (32位) 8 (64位)%ld
    [signed] long [int]4 (32位) 8 (64位)%lu

    (带 [] 的内容是可以省略不写出来)

      <1>整型的数据默认类型是有符号型(signed)
      
      <2>signed 的符号位是二进制的最高位
      

    标题(例: int)signedunsigned备注
    符号位符号位:1表示负 0表示正
    范围0~ (232?1) ( 2 32 ? 1 ) ?231 ? 2 31 ~ (231?1) ( 2 31 ? 1 ) signed 没有负数

    二、浮点型数据的分类

    类型字节数输出格式
    float4%f
    double8%f
    long double8%lf

      <1>浮点型数据在内存是以指数的形式存放的,所以还有一种 %e 以指数格式输出
      
      <2>定义一个浮点型数据时,默认 double 双精度浮点型,如果要定义 float 单精度浮点型,在数据后加上 f 如: int a = 12.0f,如果要定义 long double 长双精度浮点型,在数据后加上 l ,如: int a = 2.3l 。

    三、整型数据的存储

      <1>整型数据在内存中的计算都是转换成二进制来进行计算的
      
      <2>数据在内存中的存储都是以补码的形式存放,利用补码的方式存放可以将符号位和数值域统一起来计算,同时使得加法和减法可以统一处理(CPU只有加法)  
    例:int a = -20
    原码:10000000 00000000 00000000 00010100
    反码:11111111 11111111 11111111 11101011
    补码:11111111 11111111 11111111 11101100

      <3>正数的原反补码都一样,负数的原码取反得到反码,反码加一得到补码。
      
      <4>字节数大于1个的数据,在内存中存放的时候有一个字节序的问题,分大端和小端两种。
    大端:数据的高字节数据存放在低地址处,低字节数据存放在高地址处。
    小端:数据的高字节数据存放在高地址处,低字节数据存放在高地址处。

    这里写图片描述

    例子:编写函数求得当前机器的字节序

    #include <stdio.h>
    #include <stdlib.h>
    
    //方法一:利用char型指针只能获取1个字节,来获取int型数据的第1个字节处数据
    int check_sys()
    {
        int a = 1;
        return  *(char *)&a;
    }
    
    int main()
    {
        int a = 1;
        *(char *)&a;
        int ret = check_sys();
        if (ret == 1)
        {
            printf("小端\n");
        }
        if (ret == 0)
        {
            printf("大端\n");
        }
    
        system("pause");
        return 0;
    }
    
    //方法二:利用共用体union,联合体成员共用一个起始地址的原理
    int check_sys()
    {
        int ret = 0;
        union Un
        {
            int i;
            char c;
        }u;
    
        u.i = 1;
        return u.c;
    
    }
    

    例题:

    #include <stdio.h>
    //无符号型数据一定大于零,所以循环来到 -1 的时候,会被解析为2的32次方,结果是从最大的整型往下递减
    int main()
    {
       unsigned int i;
       for(i = 9; i >= 0; i--)
       {
           printf(“%u\n”,i);
       }
    
       return 0;
    }

    四、浮点型数据的存储

      <1>浮点型的数据在内存中是转化为科学计数法的形式进行存储的。内存中分别存储符号位,指数,有效数字。其中根据国际标准IEEE 754,任意一个二进制浮点数V可以表示为:

    • (-1)^S *M *2^E
    • (-1)^S 代表符号位,当S = 0,V是正数;当S = 1,V是负数。
    • M表示的是有效数字,有效数字大于 1,小于 2。
    • 2^E表示指数位。

    例子:
    十进制的10.0,二进制表示为:1010.0,科学计数法表示为: 1.010?23 1.010 ? 2 3 。相当于S = 0;M = 1.010;E = 3。

      <2>根据规定:

      对于32 bit的浮点数,最高位是符号位S,接下来 8 位是指数位E,剩下的23位是有效数字M。
    这里写图片描述

      对于63 bit的浮点数,最高位是符号位S,接下来 11 位是指数位E,剩下的52位是有效数字M。
    这里写图片描述

      <3>关于M
      因为M的范围是在1~2的,为了给有效数字增加一位,所以将 1 舍弃地进行存储。如1.011,只保存011。在将浮点型数据取出的时候,再在原处加上 1 。
      
      <4>关于E

    • 若E的范围是0~255(8 bit),即是无符号型,但是实际中指数有负的,E的实际存放是加了127的。若E的范围是0~2047(11 bit),E的存放是加了1023。
    • E中存储的二进制数不全 0 或不全 1,E的计算就减去127 或 1023。
    • E中存储的二进制数全为 0 ,该浮点型数据表示的是正负无限接近 0 的数 ,M的 1 没有必要加上。
    • E中存储的二进制数全为 1 ,该浮点型数据表示的是正负无限接近无穷大的数,M的 1 没有必要加上。

    例子:
    10.0 ->1010.0 -> (?1)0?1.010?23 ( ? 1 ) 0 ? 1.010 ? 2 3 ->S = 0, M = 1.010, E = 3 + 127 = 130
    即:0 10000010 010 0000 0000 0000 0000 0000

    cs