深度剖析数据在内存中的存储(C语言)

目录

一、数据类型介绍

1.数据类型介绍

2.类型的基本归类

2.1整型家族

2.2浮点数家族

2.3构造家族

2.4指针家族

2.5空家族

二、整形在内存中的存储:原码、反码、补码

三、大小端字节序介绍及判断

四、浮点型在内存中的存储解析

五、浮点数从内存中取出

六、总结


一、数据类型介绍

1.数据类型介绍

char            //字符数据类型

short           //短整型

int               //整型

long            //长整型

long long    //更长的整型

float            //单精度浮点数

double        //双精度浮点数

2.类型的基本归类

2.1整型家族

char    unsigned char   (无符号)

           signed char       (有符号)

short   unsigned short  [int]

           signed short      [int]

int       unsigned int   

           signed int

long    unsigned long   [int]

           signed long       [int]

2.2浮点数家族

float

double

2.3构造家族

>  数组类型

>  结构体类型 struct

>  枚举类型     enum

>  联合类型     union

2.4指针家族

int  *pi;

char *pc;

float *pf;

void *pv;

2.5空家族

void表示空类型(无类型)

通常用于函数的返回类型、函数的参数、指针类型

二、整形在内存中的存储:原码、反码、补码

计算机中的有符号数有三种表示方法,即原码、反码和补码。
三种表示方法均有 符号位 数值位 两部分,符号位都是用0表示“正”,用1表示“负”,而数值位
三种表示方法各不相同。
原码
直接将二进制按照正负数的形式翻译成二进制就可以。
反码
原码的符号位不变,其他位依次按位取反就可以得到了。
补码
反码+1就得到补码。
正数的原、反、补码都相同。
对于整形来说:数据存放内存中其实存放的是补码。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理( CPU只有加法器 )此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

三、大小端字节序介绍及判断

变量在内存中的存储

 从这里我们看出上变量在内存中是以补码的形式存储的,但是顺序却跟我们想的不太一样,这就是我接下来要讲的大小端存储。

大小端存储的概念
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

如何判断当前机器的是大端还是小端存储?

 取出a的地址将其强制类型转化为char*类型后再解引用得到的就是a的第一个字节,若结果是1则为小端存储,若是0,则是大端存储。

练习:

int main() 
{ 
 char a[1000]; 
 int i; 
 for(i=0; i<1000; i++) 
 { 
 a[i] = -1-i; 
 } 
 printf("%d",strlen(a)); //255
 return 0; 
}

所以a数组存储的内容为-1,-2,-3……-127,-128,127……2,1,0,-1,-2,-3……
又因为'\0'的ASCII码值为0,所以strlen计算范围只有-1--1,中间字符的个数共有255。

四、浮点型在内存中的存储解析

常见的浮点数:
3.14159 1E10 浮点数家族包括: float、double、long double 类型。 浮点数表示的范围:float.h中定义

浮点数存储的例子:
 

#include<stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

我们从中可以看到虽然num和*pFloat在内存中是同一个数,但在内存中存储的数据差距十分大,这是因为整数和浮点数在内存中存储的方式不同。
根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面的形式:

···  (-1)^S * M * 2^E
···  (-1)^s表示符号位,当 s=0 V 为正数;当 s=1 V 为负数。
···  M表示有效数字,大于等于 1 ,小于 2
···  2^E表示指数位
IEEE 754规定: 对于 32 位的浮点数,最高的 1 位是符号位 s ,接着的 8 位是指数 E ,剩下的 23 位为有效数字 M
float类型的存储:      
double类型的存储:
对于M的规定:
在存储的过程,默认这个数的第一位总是1,因此可以舍去,只存入小数部分 。如存入1.01时,只将01存入M,不足的位数补0补全。
对于E的规定:
E为一个无符号整数,所以E中所有位都是数据位,没有符号位。E为8位时,取值范围为0-255。
E为11位时,取值范围为0-2047。
因为科学计数法中E可以为负数,所以存入内存是E要加上一个中间数,对于8位的E,中间数是127;对于11位的E,中间数是1023。 比如, 2^10 的E 10 ,所以保存成 32 位浮点数时,必须保存成 10+127=137 ,即 10001001。    
举个例子:十进制的 5.0 ,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面 V 的格式,可以得出 s=0, M=1.01, E=2
十进制的 -5.0 ,写成二进制是 - 101.0 ,相当于 - 1.01×2^2 。那么, s=1 M=1.01 E=2

五、浮点数从内存中取出

  1.S直接取出

  2.E、M取出分为3种情况

(1)E不全为0或者不全为1:此时E=E-127或者E=E-1023,再将有效数字M前加上第一位1。

(2)E全为0:E=1-127或者E=1-1023;M此时不用加上1,而是还原成0.xxxxxx的小数。此时取出的数无限接近±0.

(3)E全为1:取出的浮点数为正无穷或者负无穷大。


六、总结

以上就是数据在内存中存储的全部内容,希望对大家有所帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值