预计阅读本页时间:-
语句和表达式通常应该只使用一种类型的变量和常量。然而,如果您混合使用类型,C不会像Pascal那样停在那里死掉。相反,它使用一个规则集合来自动完成类型转换。这可能很方便,但是它也很危险,尤其是在您无意地混合使用类型的情况下(许多UNIX系统都有自带的lint程序可以检查类型“冲突”。如果您选择了一个更高的错误等级,许多非UNIX的C编译器将报告可能的类型问题)。您最好能有一些类型转换规则的知识。基本的规则如下:
1.当出现在表达式里时,有符号和无符号的char和short类型都将自动被转换为int,在需要的情况下,将自动被转换为unsigned int(如果short与int有相同的大小,那么unsigned short比int大;在那种情况下,将把unsigned short转换为unsigned int)。在K&RC下,但不是当前的C下,float将被自动转换为double。因为是转换成较大的类型,所以这些转换被称为提升(promotion)。
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
2.在包含两种数据类型的任何运算里,两个值都被转换成两种类型里较高的级别。
3.类型级别从高到低的顺序是long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int和int。一个可能的例外是当long和int具有相同大小时,此时unsigned int比long的级别更高。之所以short和char类型没有出现在此清单里,是因为它们已经被提升到int或也可能被提升到unsigned int。
4.在赋值语句里,计算的最后结果被转换成将要被赋予值的那个变量的类型。像规则1中一样,这个过程可能导致提升;但也可能导致降级(demotion),降级是将一个值转换成一个更低级的类型。
5.当作为函数的参数被传递时,char和short会被转换为int,float会被转换为double。像在第9章“函数”中讨论的那样,可以通过函数原型来阻止自动提升的发生。
提升通常是一个平滑的无损害的过程,但是降级可能导致真正的问题。原因很简单:一个较低级别的类型可能不够大,不能存放一个完整的数。一个8字节的char变量可以存放整数101,但是不能存放整数22334。当把浮点类型降级为整数类型时,它们被趋零截尾或舍入。这意味着23.12和23.99都被截尾成23,-23.5被截尾成-23。程序清单5.14说明了这个规则。
程序清单5.14 convert.c程序
下面是运行convert.c产生的结果:
ch=C,i=67, fl=67.00
ch=D,i=203, fl=339.00
Now ch= -
下面是在8位char、32位int的系统上运行程序的过程分析:
● 第9行和第10行:字符‘C’被作为1字节的ASCII值存储在ch里。整数变量i接受由‘C’转换成的整数,即67,它以4个字节存储。最后,fl接受由67转换成的浮点数,即67.00。
● 第11行和第14行:字符变量‘C’被转换成整数67,然后把该整数加1。结果的4字节的整数68被截为1字节并存储在ch里。当使用%c说明符进行打印时,68被解释为‘D’的ASCII码。
● 第12和第14行:为了和2相乘,ch的值被转换为一个4字节的整数(68)。乘积整数(136)为了和fl相加而被转换为浮点类型。结果(203.00f)被转换成int类型并存储在i中。
● 第13和第14行:为了和2.0相乘,ch的值(‘D’,即68)被转换为浮点类型。为了做加法,i的值(203)被转换为浮点类型。结果(339.00)被存储在fl中。
● 第15和第16行:在这里,示例程序尝试了一个降级的实例,把ch设置为一个很大的数。在截去高位后,ch最终变成连字符这一字符的ASCII码。
指派运算符
通常您应该避免自动类型转换,尤其是避免降级。但是倘若您小心使用,有时候它对做类型转换很方便。到目前为止我们已经讨论的类型转换是自动完成的。然而,您也有可能需要准确的类型转换,或者需要在程序中表明您是知道您正在做类型转换的。完成这一任务的方法被称为指派(cast),其步骤是在某个量的前面放置用圆括号括起来的被希望转换成的类型名。圆括号和类型名一起构成了指派运算符(cast operator)。指派运算符的一般形式如下:
(type)
用实际所需的类型(例如long)来代替type。
考虑下面两个代码行,其中mice是一个int变量。第二行包含两个向int类型的指派。
mice=1.6+1.7;
mice=(int)1.6+(int)1.7;
第一个例子使用了自动转换。首先,1.6和1.7相加得到3.3。然后这个数通过截尾被转换成整数3来匹配int类型变量。第二个例子中,在相加前,1.6被转换成一个整数(1),1.7也是如此。所以mice被赋值为1+1,即2。这两个形式本质上没有哪个比另一个更准确;只有通过考虑具体编程问题的上下文才能判断哪一个更有意义。
通常,您不应该混合使用类型(这就是为什么一些语言不允许这样做),但是偶尔它也是有用的。C的原则是避免给您设置障碍,但由您承担起不滥用自由的责任。