众所周知,在C语言中,整数和浮点数在内存中分别占用不同的空间大小。但你是否对于他们怎样在内存中怎样储存有过疑问?
整数
在整数中,最常见的就是整型(int),他在内存中占用4个字节,也就是32个比特位。如果你之前对计算机原理有基本的了解,那么很容易就能算出这4个字节空间能储存-2^32-1~2^32-1这些不同数字。如果不了解,接下来我会为你介绍,但需要你掌握基本的有关二进制的知识。给你一个二进制位的空间,它能存储0、1两个数字;给你两个二进制位,那么他能储存00(0)、01(1)、10(2)、11(3)这四个数字……而在计算机中一个比特位就代表一个二进制位。学会这些之后你可能会问:那32个比特位不就能存储0~2^32-1这些数吗,为什么会是-2^32-1~2^32-1?对于整型(int)变量,计算机往往会将最高位看作符号位:0代表“+”,1代表“-”。如果你不需要符号位,可以在用unsigned修饰int。如此你可以尝试对short、long int、long long int进行理解。
数据的存储
对于整型有一定的了解后,我们就可以对单个数据在内存中的储存进行了解来强化自身学识。如果你上过信息技术之类的课程,你可能会听老师讲过大端模式和小端模式。但其实大端模式和小端模式并不是由语言或者编译器来决定,而是由处理器决定的。对于一串16进制数0x11223344,在大端模式下,其按照字节由小地址到大地址存储为11 22 33 44;但在小端模式下其会按照44 33 22 11的顺序储存。
此外数据并不是直接存储在内存中的而是储存补码,因为CPU中只有加法器而没有减法器,以补码的形式储存就能用加法代替减法。他的实现方法就是正数那个数的补码是他的自身;负数的补码是其除符号位外取反(用0代替1,用1代替0),之后加一。
浮点数
#include
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 在内存中明明是同⼀个数,为什么浮点数和整数的解读结果会差别 这么⼤? 要理解这个结果,⼀定要搞懂浮点数在计算机内部的表⽰⽅法。 根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
V = (−1) ^ S * M * 2^E
(−1)^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
M 表⽰有效数字,M是⼤于等于1,⼩于2的
2^E 表⽰指数位
举例来说: ⼗进制的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。
IEEE 754还规定: 对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M 对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。
结语
到这里,有关数据在内存中如何存储的基本知识到这里就结束了。当然,数据存储的知识还远不止这些,如果你对这些知识感兴趣,可下去继续查找相关资料进行学习。