C语言中的类型转换

类型转换

 通常,在语句和表达式中使用类型相同的变量和常量。但是,如果使用混合类型,C不会像Pascal那样停在那里死掉,而是采用一套规则进行自动类型转换。虽然这很便利,但是有一定的危险性,尤其是在无意间混合使用类型的情况下(许多Unix系统都使用lint程序检查类型“冲突”。如果选择更高错误级别,许多非Unix C编译器也可能会报告类型问题)。最好先了解一些基本的类型转换规则。

 1.当类型转换出现在表达式中时,无论是 unsigned 还是 signed 的 char 和 short 都会被自动转换成 int,如有必要会转换成 unsigned int(如果 short 与 int 的大小相同,unsigned short 就比 int 大,这种情况下,unsigned short 会被转换成 unsigned int)。在 K&R 那时的 C 中 float 会被自动转换成 double (目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级。

 2.涉及两种类型的运算,两个值都会被分别转换成两种类型的更高级级别。

 3.类型的级别从高到低依次是 long double、double、float、unsigned long、long long、unsigned long、long、unsigned int、int。例外的情况是,当 long 和 int 的大小相同时,unsigned int 比 long 的级别高。之所以 short 和 char 类型没有列出,是因为它们已经被升级到 int 或者 unsigned int。

 4.在赋值表达式语句中,计算的最终结果会被转换成赋值变量的类型。这个过程可能导致类型升级或降级。所谓降级,是指把一种类型转换成更低级别的类型。

 5.当作为函数参数传递时,char 和 short 被转换成 int,float 被转换成 double。
 类型升级通常不会有什么问题,但是类型降级会导致真正的麻烦。原因很简单:较低类型可能放不下整个数字。例如,一个8位的 char 类型变量存储整数101没有问题,但是存不下22334.

 如果带转换的值与目标类型不匹配的话,所引起的变化将取决于转换涉及的类型。待赋值的值与目标类型不匹配时,规则如下:

 1.目标类型是物符号整型,且待赋值的值是整数时,额外的位将会被忽略。例如,如果目标类型时8位 unsigned char,待赋的值是原始值求模256。

 2.如果目标类型是一个有符号整数,且待赋的值是整数,结果因实现而异。

 3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的。

 如果把一个浮点数转换成整型类型时,等于浮点数类型降级为整型类型,原来的浮点数会被截断。例如,23.12 和 23.99都会被截成23,而 -23.5则会被截成 -23。

/*程序清单 convert.c --自动类型转换*/
#include <stdio.h>
int main(void)
{
	char ch;
	int i;
	float f;
	
	fl = i ch ='C';
	printf("ch = %c, i = %d, fl = %2.2f\n",ch,i,fl);
	ch = ch + 1;
	i = fl + 2 * ch;
	fl = 2.0 * ch + i;
	printf("ch = %c, i = %d, fl = %2.2f\n",ch, i, fl);
	ch = 1107;
	printf("Now ch = %c\n",ch);
	ch = 80.89;
	printf("Now ch = %c\n",ch);
	
	return 0;
}

输出结果如下:
ch = C, i = 67,fl = 67.00
ch = D, i = 203, fl = 339.00
Now ch = S
Now 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 的值被转换为浮点类型,计算结果(339.00)被存储在 fl 中。
  • 第 15 行和第 16 行:演示了类型降级的示例。把 ch 设置为一个超出其类型范围的值,忽略额外的位后,最终 ch 的值是字符 s 的 ASCII 码。或者,更确切地说,ch 的值所1107 % 256,即83。
  • 第 17 行和第 18 行:演示了一个类型降级的示例。把 ch 设置为一个浮点数,发生截断后,ch 的值是字符 P 的 ASCII 码。

强制类型转换运算符

 通常,应该避免自动类型转换,尤其是类型降级。但是如果能够小心使用,类型转换也会很方便。我们前面讨论的类型转换都是自动完成的。然后,有时候需要进行精确的类型转换,或者在程序中表明类型转换的意图。这种情况下要用到强制类型转换,即在某个量的前面放置用圆括号括起来的类型名,该类型名即是希望转换成的目标类型。圆括号和它括起来的类型名称构成了强制类型转换运算符,其通用形式如下:

( type)

用实际需要的类型(如,long)替换 type 即可。
考虑下面两行代码,其中 mice 是 int 类型的变量。第 2 行包括两次 int 强制类型转换。

mice = 1.6 + 1.7;
mice = (int)1.6 + (int)1.7;

 第 1 行使用自动类型转换。首先,1.6 和 1.7 相加得 3.3 。然后,为了匹配 int 类型的变量,3.3被类型转换截断为整数 3.第 2 行,1.6 和 1.7 在相加之前被转换成整数(1),所以把 1 + 1 的和赋值给变量 mice。本质上,这两种类型转换都好不到哪里去,要考虑程序的具体情况再做取舍。

 一般而言,不应该混合使用类型(因此有些语言直接不允许这样做),但是偶尔这样做也是有用的。C 语言的原则是避免给程序员设置障碍,但是程序员必须承担使用的风险和责任。

以上。

文章摘取于 《C Primer Plus》第六版 中文版 第五章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值