在一个表达式中,相同类型数据的运算(如两个整数相加、两个实数相乘)是没有问题的,但是不同类型的数据由于长度不同,在内存中存储的方式不同,在进行运算时,需要先转换成同一类型,然后才能运算 。在 C语言 中,数据类型的转换分为自动类型转换和强制类型转换两种方式。
3.4.1 自动类型转换
双目运算符两侧的操作数的类型必须一致,所得计算结果的类型与操作数的类型一致。如果一个运算符两边的操作数类型不一致则系统将自动按照转换规律先对操作数进行类型转换再进行运算。即转换为相同的类型(较低类型转换为较高类型),规律见下表。
双目运算符即有两个操作数,三目即有三个操作数,以此类推。
表3-13 运算的类型转换规则
操作数1 | 操作数2 | 转换结果类型 |
---|---|---|
短整型(short) | 长整型(long) | 短整型(short)->长整型(long) |
整型(int) | 长整型(long) | 整型(int)->长整型(long) |
字符型(char) | 整型(int) | 字符型(char)->整型(int) |
有符号型(signed) | 无符号型(unsigned) | 有符号型(signed)->无符号型(unsigned) |
整型 | 实型 | 整形->实型 |
实型 | 双精度型(double) | 实型->双精度型(double) |
实型变量即在程序运行过程中可以改变其值的实型量,实型变量分为单精度(float),双精度(double)和长精度(long double)型。
当运算符两边的操作数为不同类型时,如一个 long 型数据与一个 int 型数据一起运算,需要先将 int 型数据转换为 long 型,然后两者再进行运算,结构为 long 型;如 float 型和 double 型数据进行运算,要先将 float 型数据转换成 double 型再进行运算,结果也为 double 型。所有这些转换都是由系统自动进行的,使用时用户只需要从中了解结果的类型即可。
例如:
int i; float f; double d; long e;
10+‘a’+i×f-d/e;
其中 i 为 int 型变量,f 为 float 型变量,d 为 double 型变量,e 为 long 型变量,则此表达式运算次序为:
(1)进行 10+‘a’ 的运算。先将 ‘a’ 转换成整数 97,运算结构为 107;
(2)进行 i×f 的运算。先将 i 与 f 都转换成 double 型,运算结果为 double型;
(3)整数 107 与 i×f 的积相加,先将整数 107 转换成双精度数,结果为 double 型;
(4)将变量 e 转换成 double 型,d/e 的结果为 double 型;
(5)将 10+’a’+i×f 的结果与 d/e 的商相减,最后结果为 double 型。
3.4.2 强制类型转换
上面的转换是自动的,但 C语言 也提供了以显式的形式强制转换类型的机制,其一般形式为:
(数据类型名) 表达式
它把后面的表达式运算结果的类型强制转换为要求的类型,而不管类型的高低,如:
(double)a (将变量 a 转换成 double 型)
(int)(x+y) (将表达式 x+y 的结果转换为 int 型)
要转换的表达式要用括号括起来,如 (int)(x+y)与 (int)x+y 是不同的,后者相当于 (int)(x)+y,也就是说,只将 x 转换成整形,然后与 y 相加。
在很多情况下,强制类型转换是必需的。 例如,调用 sqrt()函数时,要求参数是 double 型数据。若变量 n 是 int 型,且作为该函数的参数使用时,则必须按下列方式强制进行类型转换。
sqrt((double)n)
需要指出的是,无论是自动地还是强制地实现数据类型的转换,仅仅是为了本次运算或赋值的需要而对数据长度进行一时性的转换,并不能改变在数据说明时对该数据规定的数据类型。