以(unsigned)char为例笔记。数据的溢出实际上是补码运算最高位接受进位或产生进位造成的,可见笔记:C 位运算符操作的二进制码(补码)。
1 C语言数据类型
1:C语言数据类型
2 C语言数据类型表示范围
(1) 不同数据类型占用的内存大小
C标准所规定的各数据类型所定义变量会占用的内存大小:
在不同的平台上C的每一种数据类型变量所占用的内存大小可能会不同。一般在32位系统之上,char变量占用一个字节内存,short变量占用2个字节内存,int变量占用4个字节内存,float变量占用4个字节内存,double变量占用8个字节内存,long变量占用4个字节内存。每个字节为8位。测试这些数据类型变量占用内存大小时可用sizeof测试一下。
(2) 占用n位的有符号变量表示的范围数为什么是-2^[n - 1] ~ 2^[n - 1] – 1
针对有符号类型变量。
如char 类型变量占用8个位,可表示的数据范围-2^7 ~ 2^7 – 1。为什么呢?
- 在计算机中,数值的一律用[0,1]来表示。
- [0, 1]指数值的补码。
- 正数的补码跟原码(二进制)一致。负数补码为其绝对值的原码按位取反后再加1。
- 补码相加对符号位有进位时,进位被舍弃。
- 变量所占内存的最高位为符号位。最高位为1表示数值为负数,为0表示为数值为正数。
[1]n位所存正数的最大值
如当前数据类型变量占用n位,则在此n位中存最小的正数的补码应该为:
0 | 1 | ...... | 1 | 1 |
符号位 数据最高位 1bit 0bit
则n位所存的最大正数数为:2^0 + 2^1 + …+2^(n-2) = 1*( 1 – 2^[n-1]) / (1 – 2) = 2^[n-1] – 1。
[2]n位所存负数最小值
即补码转换成原码所对应的最大值是- (2^[n-1] – 1)。可根据实际的编程经验可知,最小的负数可以达到-2^[n-1]。
以下依据解决这个问题:
- 反码的出现解决了原码减法计算的不正确性。