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< ... Read more »

Views: 34 | Added by: gigi | Date: 12.30.2018 | Comments (0)

加法和减法是计算机中最基本的运算,计算机时时刻刻都离不开它们,所以它们由硬件直接支持。为了提高加减法的运算效率,硬件电路要设计得尽量简单。

对于有符号数,内存要区分符号位和数值位,对于人脑来说,很容易辨别,但是对于计算机来说,就要设计专门的电路,这无疑增加了硬件的复杂性,增加了计算的时间。要是能把符号位和数值位等同起来,让它们一起参与运算,不再加以区分,这样硬件电路就变得简单了。

另外,加法和减法也可以合并为一种运算,就是加法运算,因为减去一个数相当于加上这个数的相反数,例如,5 - 3 等价于 5 + (-3),10 - (-9) 等价于 10 + 9。

相反数是指数值相同,符号不同的两个数,例如,10 和 -10 就是一对相反数,-98 和 98 也是一对相反数。

如果能够实现上面的两个目标,那么只要设计一种简单的、不用区分符号位和数值位的加法电路,就能同时实现加法和减法运算,并且非常高效。实际上,这两个目标都已经实现了,真正的计算机硬件电路就是如此简单。

然而,简化硬件电路是有代价的,这个代价就是有符号数在存储和读取时都要进行转化。那么,这个转换过程究竟是怎样的呢?接下来我们就详细地讲解一下。

首先,请读者先记住下面的几个概念。

1) 原码

将一个整数转换成二进制形式,就是其原码。例如short a = 6;,a 的原码就是0000 0000 0000 0110;更改 a 的值a = -18;,此时 a 的原码就是1000 0000 0001 0010

通俗的理解,原码就是一个整数本来的二进制形式。

2) 反码

谈到反码,正数和负数要区别对待,因为它们的反码不一样。

对于正数,它的反码就是其原码(原码和反码相同);负数的反码是将原码中除符号位以外的所有位(数值位)取反,也就是 0 变成 1,1 变成 0。例如short a = 6; ... Read more »

Views: 50 | Added by: liangcx126 | Date: 12.30.2018 | Comments (0)

C语言中的整数除了可以使用十进制,还可以使用二进制、八进制和十六进制。

二进制数、八进制数和十六进制数的表示

一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面加上特定的字符,也就是加前缀。

1) 二进制

二进制由 0 和 1 两个数字组成,使用时必须以0b0B(不区分大小写)开头,例如:

 
  1. //合法的二进制
  2. int a = 0b101; //换算成十进制为 5
  3. int b = ... Read more »
Views: 15 | Added by: liangcx126 | Date: 12.30.2018 | Comments (0)