C语言的类型转换 Conversion and Casting


C语言的类型转换 Conversion and Casting

文章插图
 
通常,在语句和表达式中应使用类型相同的变量和常量 。但是,如果使用混合类型,最好先了解一些基本的类型转换规则 。
1 类型转换规则1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned-int(如果short与int的大小相同,unsigned short就比int大 。这种情况下,unsigned short会被转换成unsigned int) 。在K&R那时的C中,float会被自动转换成double(目前的C不是这样) 。由于都是从较小类型转换为较大类型,所以这些转换被称为升级(promotion) 。
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.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型 。这个过程可能导致类型升级或降级(demotion) 。所谓降级,是指把一种类型转换成更低级别的类型 。
5.当作为函数参数传递时,char和short被转换成int,float被转换成double 。
类型升级通常都不会有什么问题,但是类型降级会导致真正的麻烦 。原因很简单:较低类型可能放不下整个数字 。例如,一个8位的char类型变量存储整数101没问题,但是存不下22334 。
如果待转换的值与目标类型不匹配怎么办?这取决于转换涉及的类型 。待赋值的值与目标类型不匹配时,规则如下 。
1.目标类型是无符号整型,且待赋的值是整数时,额外的位将被忽略 。例如,如果目标类型是8位unsigned-char,待赋的值是原始值求模256 。
2.如果目标类型是一个有符号整型,且待赋的值是整数,结果因实现而异 。
3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的 。
2 浮点数的类型转换如果把一个浮点值转换成整数类型会怎样?当浮点类型被降级为整数类型时,原来的浮点值会被截断 。例如,23.12和23.99都会被截断为23,-23.5会被截断为-23 。程序清单5.14演示了这些规则 。
#include <stdio.h>int main(void){char ch;int i;float fl;fl = i = ch = 'C';/* line 9 */printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl); /* line 10 */ch = ch + 1;/* line 11 */i = fl + 2 * ch;/* line 12 */fl = 2.0 * ch + i;/* line 13 */printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl); /* line 14 */ch = 1107;/* line 15 */printf("Now ch = %cn", ch);/* line 16 */ch = 80.89;/* line 17 */printf("Now ch = %cn", ch);/* line 18 */return 0;}运行convert.c后输出如下:
ch = C, i = 67, fl = 67.00ch = D, i = 203, fl = 339.00Now ch = SNow ch = P在我们的系统中,char是8位,int是32位 。程序的分析如下 。
- 第9行和第10行:字符'C'被作为1字节的ASCII值存储在ch中 。整数变量i接受由'C'转换的整数,即按4字节存储67 。最后,fl接受由67转换的浮点数67.00 。
- 第11行和第14行:字符变量'C'被转换成整数67,然后加1 。计算结果是4字节整数68,被截断成1字节存储在ch中 。根据%c转换说明打印时,68被解释成'D'的ASCII码 。
- 第12行和第14行:ch的值被转换成4字节的整数(68),然后2乘以ch 。为了和fl相加,乘积整数(136)被转换成浮点数 。计算结果(203.00f)被转换成int类型,并存储在i中 。
- 第13行和第14行:ch的值('D',或68)被转换成浮点数,然后2乘以ch 。为了做加法,i的值(203)被转换为浮点类型 。计算结果(339.00)被存储在fl中 。
- 第15行和第16行:演示了类型降级的示例 。把ch设置为一个超出其类型范围的值,忽略额外的位后,最终ch的值是字符S的ASCII码 。或者,更确切地说,ch的值是1107%256,即83 。
- 第17行和第18行:演示了另一个类型降级的示例 。把ch设置为一个浮点数,发生截断后,ch的值是字符P的ASCII码 。
3 强制类型转换运算符通常,应该避免自动类型转换,尤其是类型降级 。但是如果能小心使用,类型转换也很方便 。我们前面讨论的类型转换都是自动完成的 。然而,有时需要进行精确的类型转换,或者在程序中表明类型转换的意图 。这种情况下要用到强制类型转换(cast),即在某个量的前面放置用圆括号括起来的类型名,该类型名即是希望转换成的目标类型 。圆括号和它括起来的类型名构成了强制类型转换运算符(cast operator),其通用形式是:


推荐阅读