1.什么是隐式类型转换?
就是程序在编译时有时会进行一些我们看不到的类型转换。这种转换我们叫做隐式类型转换。
2.怎样转换?
一是算术转换,二是整型提升。
先说算术转换。
如果某个操作符的各个操作数属于不同类型,那么就需要转换类型,但是并不是随意转换参照下表:
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面列表中排名较低,那么首先要先转换为另外一个操作数的类型后执行运算。
什么意思?
就是假如一个操作数是int类型另一个操作数是double类型,那么会将int类型转换为double类型,再进行运算。
然后是整型提升。
整型提升:将出现的字符类型(char)和短整型(short)统一提升为int类型(特殊情况下,也会提升为unsigned int)
整形提升的意义:
表达式的整形运算要在cpu的相应运算器件内执行,cpu内整形运算器(ALU)的操作数的字节长度一般就是int字节长度,同时也是cpu的通用寄存器的长度。
因此,即使两个char类型的相加,在cpu执行时实际上也要先转换为cpu内整形操作数的标准长度
通用cpu是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以表达式中各种长度可能小于int长度的整形值,都必须先转换为int或unsigned int,然后才能送入cpu去执行运算。
看代码:
int main(void)
{
char a = 3;
char b = 127;
char c = a + b;
printf("%d",c);
return 0;
}
你先算c的值是多少?
没错结果是 -126
怎么算的呢?
来看,我们一步步的算
char a = 3;
这里3是一个整数,整数类型所占的内存空间是32比特位,所以3在内存中的二进制序列为00000000 00000000 0000000 00000011
但是这里用来存放常量3的变量a是char类型,其所占内存空间为8比特位,这时候c语言就会将其截断,截断的规则为将最低为的一个字节截断存储在a里面。
这时候a里面存的就是00000011
char b = 127;
同理127的二进制序列00000000 00000000 00000000 01111111
存到b里面的为01111111
char c = a + b;
那么a和b如何相加的呢?
这里a和b都是char类型,它的大小没有达到整形的大小,计算机为了提升计算精度这时候会整形提升,如何提升的?
整形提升是按照变量数据类型的符号位来进行提升的
a 为 00000011
提升后为 00000000 00000000 00000000 00000011
b 为 01111111
提升后为 00000000 00000000 00000000 01111111
注意:并不是将高位补0就完事了,这里补0是因为它们的符号位都为0也就是都为正所以才补0,如果为负符号位就为1,那么就补1.
这个时候就将a和b直接相加为00000000 00000000 00000000 10000010
然后因为c是char类型所以又要截断
这时候c里面就存的 10000010
printf("%d", c);
注意这里打印c的时候它的转换说明为% d,意思就是打印一个整形,但是c是char类型,这时候我们又要整形提升了,这里他的符号位为1那么就高位补1 为:
11111111 11111111 11111111 10000010
再注意我们内存中存的是补码,打印的是源码,所以还要补码转源码
先转为反码为 11111111 11111111 11111111 10000001
然后再转为源码为 10000000 00000000 00000000 01111110
最后打印为 -126