|
计算机中所有的数据最终都是以0和1二进制的形式体现。比如一个int型的变量数值为2时,内存中存储的值为0000 0010,为什么是00000010而不是0010,这就要说到计算机的存储单元和基本数据类型的内存大小。
计算机的最小存储单元是位也用bit表示,谐音比特,比特币因此而来。其次是字节,用byte表示。8位等于一个字节。字节是程序的最小单位。程序的基本数据类型所占内存大小没有小于1字节的。以下是windows平台下常见的数据类型的内存大小,单位为字节:
int byte_bool = sizeof(bool);// 1字节
int byte_char = sizeof(char);//1字节
int byte_short = sizeof(short);// 2字节
int byte_int = sizeof(int);//4字节
int byte_float = sizeof(float);//4字节
int byte_double = sizeof(double);//8字节
int byte_long = sizeof(long);//4字节
int byte_ll = sizeof(long long);//8字节

还有unsigned修饰的一些数据类型,它的内存大小跟没有修饰的一样,区别在于能表示的范围不同,unsigned修饰表示非负数变量。例如char的范围是-128-127. unsigned char 能表示的范围则为0-256.其他类型相似。其他类型有:
unsigned char,unsigned short,unsigned int,unsigned float,unsigned double,unsigned long,unsigned long long等等。
为了利于内存分析我们引入union联合体的概念。联合体中的成员共享相同的内存数据。所以联合体对象成员所占内存大小必须保持一致,如下联合体:
union mem_u
{
char byte_char[4];
int byte_int;
float byte_float;
};
byte_char是char数据类型,一个char占一个字节,长度为4的char数组正好占4个字节。byte_int是int型,占四个字节,byte_float是float型,也占四个字节。
我们用以下代码给byte_char赋值"abcd".
mem_u ifuu;
memcpy(ifuu.byte_char, "abcd",sizeof(ifuu.byte_char));

由于是共享内存byte_int中对应的值是1684234849。我们用windows系统的程序员计算器计算一下1684234849的二进制数值:

可以看到1684234849对应的二进制值为0110 0100 0110 0011 0110 0010 0110 0001。
内存中是低字节在前,高字节在后。
字节1:0110 0100=十进制的100,刚好对应byte_char变量的第四个字符d的ascii码。
字节2:0110 0011=十进制的99,刚好对应byte_char变量的第三个字符c的ascii码。
字节3:0110 0010=十进制的98,刚好对应byte_char变量的第三个字符b的ascii码。
字节4:0110 0001=十进制的97,刚好对应byte_char变量的第三个字符a的ascii码。
当byte_char=abcd是byte_float成员变量是乱码,没有实际意义不好分析。下面我们给byte_float赋值来进行分析内存数据:
mem_u ifuu;
ifuu.byte_float = 4.2f;

byte_int的值为1082549862,打开程序员计算器,换算成二进制表示为:01000000100001100110011001100110

C++中浮点数的表示遵循IEEE754标准,一个浮点数由三部分组成:符号位S、指数部分E(阶码)以及尾数部分M。其中符号位占一位,取值为0-负数,1-正数。指数部分占用8位,尾数部分占用23位。单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位。
加VX:Ajubray 申请加入C++技术交流群,作者及大部分群友皆10年+行业从业者。 |
|