类型转换
类型转换在维基百科中是这样定义的:
在计算机科学,特别是在程序设计语言中,类型转换(英语:type
conversion)指将数据从一种类型转换到另一种类型的过程。一个简单的例子是将整数转换成浮点数。
类型转换包括显式指定被转换到的类型的显式转换(explicit cast)(或称铸型(cast)),以及与之相对的隐式转换(implicit conversion)。其中,后者在一些语言中也被称为强制(coercion),被认为是一种特设多态机制。因为翻译不准确等原因,这两者之间的对应常被混淆。例如,C语言中的显式类型转换被误作为“强制转换”,这是技术上不正确的(事实上C语言的规范中完全没有“强制”的说法,但明确地有显式和隐式转换)。
在C语言中,类型转换分为显示转换和隐式转换。其中,显示转换往往用用户进行转换,比较显而易见,用户能直接感受出来,而隐式转换是由计算机自行完成的,用户不易察觉。
隐式类型转换
定义
C语言的整型算术运算总是至少以缺省整型类型的精度来进行的,为获得这个精度,表达式中的字符和短类型操作数在使用之前被转换为普通类型,这个转换称为整型提升。
原则
整形提升是按照变量的数据类型的符号位提升。
示例1
例如,看下边这个程序
//示例1
#include<stdio.h>
int main()
{
char a = 8;
char b = 127;
char c = a + b;
printf("%d\n", c);
return 0;
}
示例1运行结果:
这个结果正是因为出现了隐式类型转换,具体转换过程如下:
//示例1转换过程
a 为 char型,占用1个字节,故
a == 00001000
b 为 char型,占用1个字节,故
b == 01111111
c = a + b
此时,a和b将发生整形提升,提升到int型进行运算
int型,占用4个字节,故
8 == 00000000 00000000 00000000 00001000
127 == 00000000 00000000 00000000 01111111
127 + 8 == 00000000 00000000 00000000 10000111
由于 c 为 char型,占用1个字节,故
c == 10000111示例1的程序输出为十进制,c需要进行整型提升
整形提升是按照变量的数据类型的符号位提升,c的符号位是1,故
c的整型提升 == 11111111 11111111 11111111 10000111
(此时得到的是补码,需要转换为原码输出)
最高位为1,是负数,负数的反码=补码-1
11111111 11111111 11111111 10000110
(此时得到的是反码)
最高位为1,是负数,负数的原码=符号位不变,其它位取反
10000000 00000000 00000000 01111001
(此时得到的是原码)
令int d= 10000000 00000000 00000000 01111001
int型的最高位是符号位,d的最高位是1,故
d为负数
将d的其它位按二进制转十进制,得
d=-(1+8+16+32+64)=-121
示例2
//示例2
#include<stdio.h>
int main()
{
char a = 8;
printf("%u\n", sizeof(a));
printf("%u\n", sizeof(a++));
printf("%u\n", sizeof(++a));
printf("%u\n", sizeof(+a));
return 0;
}
示例2运行结果:
变量只要参与表达式运算过程,就会发生整型提升,示例转换过程如下:
sizeof(a)输出的是 a 的字节长度,由于 a 为 char型,故
sizeof(a)输出结果为1
a++ 和 ++a 输出的都是运算后的结果值
sizeof(a++) 和 sizeof(++a)都是发生整型提升后并截取到结果后的字节长度
由于 a 为 char型,为一个字节,故
sizeof(a++) 和 sizeof(++a)输出结果为1
变量只要参与表达式运算过程,就会发生整型提升
+a 是 a 发生了加法运算,在运算过程中,并没有把运算结果已经赋值给 a ,故
sizeof(+a)输出的是发生整型提升后 a 的字节长度,发生整型提升后 a 为int型,故
sizeof(+a)输出结果为4
显式类型转换
定义
显示类型转换,又称强制转换运算,显示类型转换符是一元运算符,用于临时将常量、变量或表达式转换为特定类型,从而使程序能正常执行。
语法
(datatype)expression
示例3
//示例3
#include<stdio.h>
int main()
{
int a = 8;
int b = 3;
double res;
res = a / b;
printf("%d / %d = %lf\n", a, b, res);
res = (double)a / b;
printf("%d / %d = %lf\n", a, b, res);
return 0;
}
示例3运行结果:
显示转换过程:
//示例3转换过程
定义的 a , b 为 int 型
定义的 res 为 double 型
第一次的 res = a / b
是把a/b得到的int型结果值赋值给res,由于int型计算值,多余小数会直接舍弃,故
输出结果为2.000000
第二次的 res = (double)a / b
是先把 a 进行了类型转换,从int型转换为double型
在计算时,由于a为double型,b为int型,不一致
计算机则会自动把int型的b转换为double型的b来进行计算,然后将计算结果赋值给res,故
输出结果为2.666667