C语言:关于数据类型的自动转换

在C语言中,当使用多个不同数据类型的变量进行数据运算时,有两种方法可以将同一表达式中不同数据类型的数据转换成同一类型的数据,分别是自动类型转换和强制类型转换(sizeof)。

其中自动类型转换有如下基本规则:

1、当出现在表达式里时,有符号和无符号的char和short类型都将自动被转换为int,在需要的情况下,将自动被转换为unsigned int。

2、在包含两种数据类型的任何运算里,两个值都被转换成两种类型里较高的级别,因为是转换成较大的类型,所以这些转换被称为[color=green]提升[/color]。

3、类型级别从高到低的顺序是long double、double、float、unsigned long、long、unsigned int和int。之所以short和char类型没有出现在此清单中,是因为它们已经被提升到int或也可能被提升到unsigned int。

4、在赋值语句里,计算的最后结果被转换成将要被赋予值的那个变量的类型。这个过程可能导致提升;但也可能导致降级,[color=green]降级是将一个值转换成一个更低级的类型[/color]。

5、[color=green]当作为函数的参数被传递时,char和short会被转化为int,float会被转换为double。[/color]

需要注意的是,提升通常是一个平滑的无损害的过程,但是降级可能导致问题。因为一个较低级别的类型可能不够大,不能存放一个完整的数。如:一个8位的char变量可以存放整数101,但不能存放整数22334;当把浮点类型降级为整数类型时,它们会被趋零截尾或舍入。

基于以上原理,书上举出了一个例子:
int i;
float a=3.5;
i=1;
i=i+a;
对于最后一句i=i+a,书上说i最后的值为4。

对此我表示疑惑,根据第3条基本规则:float级别高于int,那为什么最后i的值不会是4.5?

随后我上机开始试验,如图1。
[color=blue]图1:[/color]
[img]http://dl.iteye.com/upload/attachment/0082/5264/f91d3edf-7fc1-3132-9c35-fe41e6bd7e70.jpg[/img]
在这个程序中,最后的printf输出的就是%d类型,我认为即使i为4.5,结果也会因为被截尾而变成4,所以这个程序并不能说明问题。

因此我对程序作了修改,将printf中i的输出类型改为%f,如图2。
[color=blue]图2:[/color]
[img]http://dl.iteye.com/upload/attachment/0082/5797/4d9c98b5-2a91-37c1-902f-861e210938d3.jpg[/img]
修改后,程序虽然通过了编译,但是却不能输出结果。

经过前2例,我有了如下[color=red]判断:[/color]
1、printf函数中,指定的输出类型和输出表列的类型如果不一致,能通过编译,但是不能正确输出结果。
2、如果i的值为4.5,那么图2中的printf应该能正确输出结果。所以,程序中最后i的值为4,而且并不是由于printf的%d截尾。

那么,i+a作为不同数据的混合类型运算,基本规则里的第3条又是怎么发挥作用的?
这就有了两种猜想:一种是先把a截尾变成3,再和i相加,最后得到4,就相当于是降级;另一种是先把i的值转化为float型数据1.0(此处相当于提升),再和a相加,最后得到4.5,由于一开始i是定义为int型,所以这里把4.5进行截尾操作得到4。

利用之前的判断1,对程序做了如下的修改,如图3。
[color=blue]图3:[/color]
[img]http://dl.iteye.com/upload/attachment/0082/5800/ef20e58b-da60-368d-8fb5-9a5fb4b2a739.jpg[/img]
根据图3,能判断出i+a的值为4.5,因为指定输出类型为%d的printf不能输出结果,而指定输出类型为%f的printf可以正确输出。由此可见,猜想2是正确的,

[color=red]结论:[/color]系统在计算本例时,先把i的值转化为float型数据1.0,再和a相加,最后得到4.5,由于一开始i是定义为int型,所以这里把4.5进行截尾操作得到4,最后再把4赋值给整型变量i。

以上观点均为个人看法,如有错误,欢迎大家批评指正
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值