2.9 数值型数据间的混合运算
整型、单精度型、双精度型数据可以进行混合运算。由于字符型数据与整型数据通用,因此,整型、实型(包括单、双精度)、字符型数据之间可以进行混合运算。由于参与混合运算的各数据的类型不同,因此,在运算时需要进行类型转换。
在C语言中,共有两种类型转换:第一种是自动类型转换,即在运算时不必由用户指定,系统自动进行类型转换;第二种是强制类型转换,即使用强制类型转换运算符来实现强制类型转换,一般用于自动类型转换不能达到目的的情况。
1.自动类型转换
例如,4/2.1+34%3+'x'-11.1234*'a'是合法的。在进行运算时,不同类型的数据要由系统按照由低到高的次序进行类型转换,其转换规则如图2.11所示。
图2.11 数据类型转换规则
图2.11中横向向左的箭头表示必定的转换。例如,只要是字符型或短整型数据参与运算必定先转换成int型数据,float型数据在运算时为提高运算精度一律转换成double型数据。
图2.11中纵向向上的箭头表示不同类型的数据转换时的方向。例如,一个int型数据和一个double型数据进行运算时,要先将int型数据直接转换成double型数据,然后再在两个同类型(double)数据之间进行运算,结果为double型数据。注意,在这里,int型数据是直接转换成double型数据的。千万不要理解成int型先转换为unsigned型,再转换成long型,最后才转换为double型。又如,一个int型数据和一个long型数据进行运算时,也是先将int型数据直接转换成long型数据再进行计算。
在进行数据类型的混合运算时,需要注意:
① 当字符型数据转换成整型时,其ASCII码值在128~255之间的字符(最高位为1)会转换成负数。
② 当按照short→int→long的顺序进行类型转换时,其符号和数值都能够正确转换。当按照相反的顺序进行类型转换时,如果原数值不超出转换后较低类型的数值范围,一般也能正确转换;如果超出较低类型所能表示的数值范围,则会出现转换错误。
③ 由float型到int型转换时,会截去小数部分,如果数值超过int型的范围,一般会出错。
④ 由整数到实数转换时,如果该整数不能被精确转换(如long型转换为float型时),可能会丧失一些精度。
⑤ 由double型到float型转换时,当数值大小不超过float型的范围时,可能会丧失一些精度,但转换结果基本正确。
⑥ 如果参与混合运算的数据中有float型的,其结果一定是double型的,因为在运算时float型会先转换为double型再进行计算。
例如,假设已经声明i为int型变量,f为float型变量,d为double型变量,L为long型变量,c为char型变量,则混合运算i*f-d/L的运算顺序如下:
① 进行i*f的运算,先将i和f都转换成double型再相乘,运算结果为double型;
② 进行d/L的运算,先将L转换成double型再相除,运算结果为double型;
③ 将第①步的结果与第②步的结果相减,运算结果为double型。
又如,假设c为char型变量,则混合运算10+'a'-c的运算顺序如下:
① 进行10+'a'的运算:先将'a'转换成整数97,再进行10+97,得到整型结果107;
② 将第①步的结果与c(注意:先将c转换成int型)相减,运算结果为int型。
2.强制类型转换
例如,假设x已经声明为float型,则“x%3”是不合法的,必须使用如下形式:(int)x%3。其中,(int)x就是强制类型转换,将x的值由float型转换成为int型。
强制类型转换的一般形式为:
(数据类型名)(表达式)
注意,表达式应该用括号括起来,若是单个变量,则可以省略括号。例如:
● (int)(x*13.45/12)表示将x*13.45/12的运算结果转换成int型。
● (double)d表示将d的值转换成double型,d本身的类型不变。
● (float)(10%5)表示将10%5的运算结果转换成float型。
● (int)(x+y)表示将x+y的运算结果转换成int型。
● (int)x+y表示将x的值转换成int型,再与y相加,注意与上式的区别。
需要指出的是,在进行强制类型转换时,只是得到了一个所需类型的中间变量,原变量或表达式的类型并没有改变。例如,假设d已经声明为float型,则“(int)d”进行强制类型运算后得到一个int型的中间变量,它的值等于d的整数部分,而d的类型未变,仍然是float型。