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

一、整型数据的分类

类型 字节数 输出格式
unsigned int 4 %d
[signed] int 4 %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) signed unsigned 备注
符号位 符号位:1表示负 0表示正
范围 0~(2321)(232−1) 231−231~(2311)(231−1) signed 没有负数

二、浮点型数据的分类

类型 字节数 输出格式
float 4 %f
double 8 %f
long double 8 %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个的数据,在内存中存放的时候有一个字节序的问题,分大端和小端两种。
大端:数据的高字节数据存放在低地址处,低字节数据存放在高地址处。
小端:数据的高字节数据存放在高地址处,低字节数据存放在高地址处。

C语言中整型和浮点型数据在内存的存储_第1张图片

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

#include 
#include 

//方法一:利用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 
//无符号型数据一定大于零,所以循环来到 -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.010231.010∗23。相当于S = 0;M = 1.010;E = 3。

  <2>根据规定:

  对于32 bit的浮点数,最高位是符号位S,接下来 8 位是指数位E,剩下的23位是有效数字M。
C语言中整型和浮点型数据在内存的存储_第2张图片

  对于63 bit的浮点数,最高位是符号位S,接下来 11 位是指数位E,剩下的52位是有效数字M。
C语言中整型和浮点型数据在内存的存储_第3张图片

  <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)01.01023(−1)0∗1.010∗23 ->S = 0, M = 1.010, E = 3 + 127 = 130
即:0 10000010 010 0000 0000 0000 0000 0000

你可能感兴趣的:(C语言)