1、整数型存储
整数型存储就是所有整型家族里的数据类型的存储方式,也就是说包含了字符类型的存储(因为字符的''
操作符的返回值是ASCII码值,故实际上存储的是整数)。
1.1、有符号整数
有符号整数包含char
,short
,int
,long
,long long
这几种类型的数据。
他们的二进制表示方法有三种:原码,反码,补码。
这三种表示方法均有符号位和数值位两部分,符号位都是用0
表示正,用1
表示负,最高位的一位是被当做符号位,剩余的都是数值位。
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
正整数的原、反、补码都相同;负整数的三种表示方法各不相同。
有符号整数在内存中统一以补码的形式存储,并且以补码形式参与任何操作。
以补码形式进行存储的原因:
在计算机系统中,有符号数值一律用补码来表示和存储。
原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
1.2、有符号整数的特性
由于补码与数据类型限制精度的特性,产生了一种有意思的循环:
以char
类型为例子:
-128,-127…-2,-1,0,1,2…126,127,-128,-127…-2,-1,0,1,2…126,127,-128,-127…
总结为:阳极生阴,阴极生阳(有点模运算的感觉在里面)。
1.3、无符号整数
无符号整数包含unsigned char
,unsigned short
,unsigned int
,unsigned long
,unsigned long long
这几种类型的数据。
无符号数中没有原码-反码-补码
的概念。
无符号整数的二进制表示形式只有一种,即直接将无符号整数翻译成对应的二进制形式,并且以这种形式在内存中存储。
1.4、无符号整数的特性
由于数据类型限制精度的特性,也产生了一种有意思的循环:
以char
类型为例子:
0,1,2…126,127,128…254,255,0,1,2…126,127,128…254,255,0,1,2…126,127,128
2、大小端字节序存储
我们知道,变量与变量在内存中的存储顺序是由定义顺序与所处内存区域决定(例如在主函数中先后定义a
,b
两个变量,由于这两个变量存放在栈区,故a
变量存放于高地址,b
变量存放于低地址),这是变量与变量之间的存储顺序。
而大小端字节序存储指的是单个变量内部,字节与字节之间的两种存储顺序。
大端字节序存储指的是:
单个数据内部,数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容保存在内存的低地址处。
小端字节序存储指的是:
单个数据内部,数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容保存在内存的高地址处。
有大小端模式之分的原因:
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit
位,但是在C语言中除了8bit
的char
之外,还有16bit
的short
型,32bit
的long
型(这个要看具体的编译器),另外,对于位数大于8位
的处理器,例如16位
或者32位
的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
例如:一个16bit
的short
型变量x
,在内存中的地址为0x0010
,x
的值为0x1122
,那么0x11
为高字节,0x22
为低字节。对于大端模式,就将0x11
放在低地址0x0010
中,0x22
放在高地址0x0011
中。小端模式,刚好相反。我们常用的X86
结构是小端模式,而KEIL C51
则为大端模式。很多的ARM
,DSP
都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。