[C语言]数据的存储


目录

整形数据的存储

原码\反码\补码

大小端字节序

浮点型存储方式

IEEE754标准


当我们在使用C语言进行编程时,肯定离不开C语言中的基本数据类型。

char //字符型
short //短整型
int //整型
long //长整型
long long //更长的整型
float //单精度浮点型
double //双精度浮点型

当我们使用这些数据类型时,都是根据需要存储或操作的数据和占用空间的大小来进行判断的。
接下来我们就谈谈这些基本的数据类型在内存中是如何存放的。

整形数据的存储

int a = 10, b = -10; //a和b在内存中分别存放什么?

我们都知道,在x86平台下一个int占4个字节,也就是32个比特位,但a是10,b是-10,它们在内存中的存放显然不可能都是10的二进制,那么如何区分正数和负数?一段二进制数,如果它是有符号数,那么它的二进制位最高位来表示符号位 (0为正 1为负) 其他位表示数值位。

如10 表示为: 00000000 00000000 00000000 00001010

则-10表示为:10000000 00000000 00000000 00001010

我们都知道 10 + (-10) 结果为 0 但上面这样相加 结果很显然不为0 计算机如何解决这个问题?

原码\反码\补码

原码: 直接将正负数翻译为二进制位 最高位表示符号位

反码:正数反码是本身 负数的反码是除符号位外 其他二进制位按位取反

补码:正数的补码是本身 负数的补码是反码+1

计算机内存中对整型的存储是按照补码的方式来存储的。

-10的反码: 11111111 11111111 11111111 11110101
-10的补码:11111111 11111111 11111111 11110110
10的补码: 00000000 00000000 00000000 00001010
我们用-10的补码去加上10 会发现 结果为0 由此可见 计算机内存储整数就是补码的形式。

[C语言]数据的存储_第1张图片我们可以看到,计算器中的二进制也是补码存储的。

大小端字节序

int a = 10;//当我们存储了一个10
//int4个字节 那么内存中应该是 00000000 00000000 00000000 00001010
//十六进制表示应该是 00 00 00 0a;

但是当我们查看内存时发现:

[C语言]数据的存储_第2张图片

按理说应该是 00 00 00 0a存入内存的 为什么会是0a 00 00 00呢?

由此我们引入大小端字节序的概念。

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

 注意,这里是字节序 每个字节的顺序 而不是每个比特位的顺序 所以0a依旧有序 不会变成a0。
我们这里所演示的存储方式显然就是小端存储。

如何检查自己的机器是大端还是小端存储?

int a = 1;//00 00 00 01或01 00 00 00
printf("%d", *(char*)&a);

我们把一个整型的地址强制类型转换为char* 这样就可以访问第一个字节。

查看为0还是为1 为1便是小端存储 为0就是大端存储。。


浮点型存储方式

我们来看看以下代码:

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;
}

我们发现最终输出结果是:9        0.000000        1091567616        9.000000
那么为什么有些和9一致有些又不是9呢?我们就要引入浮点数存储机制的概念了。

IEEE754标准

对于 32 位的浮点数,最高的 1 位是符号位S ,接着的 8 位是指数 E ,剩下的 23 位为有效数字 M。
[C语言]数据的存储_第3张图片

 

对于 64 位的浮点数,最高的 1 位是符号位S,接着的 11 位是指数 E ,剩下的 52 位为有效数字 M
[C语言]数据的存储_第4张图片

 

如果E为8位(float),它的取值范围位0~255,但是我们知道科学计数法中的E是可以出现负数的。所以IEE754存入内存时E的真实值必须加上一个中间数,如果E是8位那么它的中间数就是127。​

当E全为1时 或者 E全为0时 我们可以想象到 2的-127次方和2的127次方分别表示无穷小和无穷大

正负去取决于符号S。

对于之前的问题,因为int n = 9所以在内存中 

0000 0000 0000 0000 0000 0000 0000 1001 的存储 导致转化为浮点数读取时 E全为0
而它的指针为float型 我们利用float的方式来存储9.0到int n中 9表示为1.001 x 2^3 
E = 127 + 3 = 130 所以E的二进制位中存储的是130 用%d来解读就是一个很大的数了。

你可能感兴趣的:(c语言,c++,开发语言)