short、int、long 是C语言中常用的三种整数类型,分别称为短整型、整型、长整型。
在现代操作系统中,short、int、long 的长度分别是 2、4、4 或者 8,它们只能存储有限的数值,当数值过大或者过小时,超出的部分会被直接截掉,数值就不能正确存储了,我们将这种现象称为溢出(Overflow)。
溢出的简单理解就是,向木桶里面倒入了过量的水,木桶盛不了了,水就流出来了。
要想知道数值什么时候溢出,就得先知道各种整数类型的取值范围。
无符号数的取值范围
计算无符号数(unsigned 类型)的取值范围(或者说最大值和最小值)很容易,将内存中的所有位(Bit)都置为 1 就是最大值,都置为 0 就是最小值。
以unsigned char 类型为例,它的长度是 1,占用 8 位的内存,所有位都置为 1 时,它的值为 28- 1 = 255,所有位都置为 0 时,它的值很显然为 0。由此可得,unsigned char 类型的取值范围是 0~255。前面我们讲到,char 是一个字符类型,是用来存放字符的,但是它同时也是一个整数类型,也可以用来存放整数,请大家暂时先记住这一点,更多细节我们将在《C语言中的字符(char)》一节中介绍。有读者可能会对 unsigned char 的最大值有疑问,究竟是怎么计算出来的呢?下面我就讲解一下这个小技巧。
将unsigned char 的所有位都置为 1,它在内存中的表示形式为1111 1111,最直接的计算方法就是:
20+ 21+ 22+ 23+ 24+ 25+ 26+ 27= 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255
这种“按部就班”的计算方法虽然有效,但是比较麻烦,如果是 8 个字节的 long 类型,那足够你计算半个小时的了。
我们不妨换一种思路,先给 1111 1111 加上 1,然后再减去 1,这样一增一减正好抵消掉,不会影响最终的值。
给1111 1111 加上 1 的计算过程为:
0B1111 1111 + 0B1 = 0B1 0000 0000 = 28= 256
可以发现,1111 1111 加上 1 后需要向前进位(向第 9 位进位),剩下的 8 位都变成了 0,这样一来,只有第