C语言程序设计任务驱动式教程(第2版)(微课版)
上QQ阅读APP看书,第一时间看更新

拓展与提高

(一)进制及进制转换

1.进制

进制是一种计数机制,在C语言程序中常用的进制有二进制、八进制、十进制和十六进制。

(1)二进制

在绝大多数计算机系统中,数据都是通过二进制的形式存在的。二进制是一种“逢二进一”的机制,它用0和1两个符号来描述。当用二进制表示十进制数字2时,由于二进制的数码只有0和1,所以根据“逢二进一”的规则,需要向高位进一位,表示为0010。同理,使用二进制表示十进制数字4时,继续向高位进一位,表示为0100。

(2)八进制

八进制是一种“逢八进一”的进制,它由0~7八个符号来描述。当使用八进制表示十进制数字8时,由于表示八进制的符号只有0~7,因此,根据逢八进一的规则,需要向高位进一位,表示为10。同理,使用八进制表示十进制数字16时,继续向高位进一位,表示为20。

(3)十六进制

十六进制是一种“逢十六进一”的进制,它由0~9、A~F十六个符号来描述。当使用十六进制表示十进制数字16时,由于表示十六进制的符号只有0~9、A~F,因此,根据逢“逢十六进一”的规则,需要向高位进一位,表示为10。同理,使用十六进制表示十进制数字32时,继续向高位进一位,表示为20。

2.进制转换

在计算机中,一个数值可以用不同的进制形式来表示,但实际上,不管用哪种进制形式来表示,数值本身是不会发生变化的。因此,各种进制之间可以实现转换,下面就以前面提到的十进制、二进制、八进制、十六进制为例来讲解进制如何实现转换。

(1)十进制与二进制之间的转换

十进制与二进制之间的转换是最常见也是必须掌握的进制转换方式。

①十进制转二进制

十进制转二进制可以采用除2取余的方式。也就是说,将要转换的数,先除以2,得到商和余数,将商继续除以2,得到商和余数,此过程一直重复直到商为0。最后将所有得到的余数倒序排列,即可得到转换结果。

接下来就以将十进制的7转换为二进制为例进行说明,其演算过程如图2-6所示。

从图2-6中可以看出,十进制的7连续3次除以2后,得到的余数依次是0、1、1、1。将所有余数倒序排列后为0111,因此,十进制的7转换成二进制后的结果是0111。

图2-6 十进制转二进制

②二进制转十进制

二进制转化成十进制要从右到左用二进制位上的每个数去乘以2的相应次方,例如,将最右边第一位的数乘以2的0次方,第二位的数乘以2的1次方,第n位的数乘以2的n-1次方,然后把所有乘的结果相加,得到的结果就是转换后的十进制。

例如,把一个二进制数0110转换为十进制,转换方式如下。

得到的结果6就是二进制数0110转化为十进制的表现形式。

(2)八进制与二进制之间的转换

比较常见的操作就是将一个二进制数转为八进制。在转换过程中有一个技巧,就是将二进制数自右向左每3位分成一段(若不足3位,用0补齐),然后将二进制每段的3位转为八进制的一位,转换过程中数值的对应关系如表2-7所示。

表2-7 二进制和八进制数值对应表

接下来,用二进制数00101110演示如何转为八进制,具体演算过程如下。

①每3位分成一段,结果为000101110。

②将每段的数值分别查表替换,结果如下。

③将替换的结果组合,组合后的八进制为0065(注意八进制必须以0开头)。

(3)十六进制与二进制之间的转换

将二进制转换为十六进制与将二进制转换为八进制类似,不同的是,要将二进制数每4位分成一段(若不足4位,则用0补齐),查表转换即可。二进制转十六进制过程中数值的对应关系如表2-8所示。

表2-8 二进制和十六进制数值对应表

接下来,二进制数01000110转换为十六进制,具体步骤如下。

①每4位分成一段,结果为01000110。

②将每段的数值分别查表替换,结果如下。

③将替换的结果组合,转换的结果为0x46或0X46(注意十六进制必须以0x或者0X开头)。

上述讲解了二进制与其他进制的转换,除二进制外,其他进制之间的转换也很简单,只需将它们转换成二进制数,然后将二进制转为其他进制即可。

(二)数据类型转换

在C语言中,整型、单精度型、双精度型、字符型数据可以共存于一个表达式中,并按一定的规则进行计算,如1.5*2+10−'3'/1.2。

C语言对参与运算的数据做某种转换,把它们转换成同一类型的数据,然后再进行计算,C语言的数据类型转换分为自动转换和强制转换。

1.自动转换

C语言自动类型转换的原则是:把短类型转换为长类型,如图2-7所示。

图2-7 数据类型转换

在图2-6中,水平方向的转换是自然进行的,即char型和short参与运算时,编译系统先将它们转换成int型,而float型先转换成double型。需要指出的是,即使是两个均为float型数据之间的运算,也要先转换成double型,以便提高运算精度。

垂直方向的转换表示当运算对象为不同类型时的转换方向。例如,int型数据和double型数据运算,先将int型转换成double型,然后两个同类型的数据进行运算,结果为double型。不要以为int型先转换成unsigned型,再转换成long型,然后再转换成double型。例如,对于表达式:

其中,3.14159265为双精度浮点型,2为整型,1.5为单精度浮点型,2269978为长整型,根据规则,均转换为双精度浮点型再运算。

2.强制转换

强制转换是通过类型转换运算来实现的。其功能是把表达式的运算结果强制转换成类型说明符表示的类型,其一般形式为

功能是把表达式结果的类型转换为圆括号中的数据类型。注意,类型名必须用括号()括起来。表达式一般用括号()括起来,但单个变量可以不用括号括起来。

例如:

注意:数据前面的圆括号称为强制类型转换符,优先级高于算术运算符。强制类型表达式的类型是(类型名)代表的类型,原来变量本身的类型不变。

例2.8 数据类型强制转换

运行结果如下。

(三)经典算法

1.累加和累乘

所谓累加,就是将一系列的数字分别相加,最后得到一个结果。例如,计算1+2+3+4+5,程序代码如例2.9所示。

例2.9 累加程序

代码x=0;是给x赋初值,重点关注:

这行代码使用了非常经典的累加算法,即把“=”右边表达式的值赋给左边的变量。

注意:累加算法x的初值为0,累乘算法x的初值为1。

累乘和累加相似,例如,计算1*2*3*4*5,程序代码如例2.10所示。

例2.10 累乘程序

2.交换两个变量的值

假设有两个变量,x=10,y=8,现在要求使得x=8,y=10,该如何交换两个变量的值呢?这是非常经典的交互算法。这里需要使用第3个变量来临时保存数值,如图2-8所示,引入第3个变量z。程序代码如例2.11所示。

图2-8 交换算法示意图

例2.11 交换两个变量的值

运行结果为