C语言中的表达式运算时,经常会有隐式的算数转换和整形提升。
1.浮点数算数转换
这一类比较简单,数据类型一般朝着浮点精度更高,长度更长的方向转换,比如:整形—>float—>double—>long double。
2.整形提升
对于整形类型(char, int, 枚举等),一律转换为整形(int),但是这里int有两种,一种是无符号的(unsigned int),一种是有符号的(signed int),具体转换为哪一种,遵循值保留原则:如果原来的整形数转换为signed int,不会丢失信息,那么就转换为singned int,否则转换为unsigned int。
也就是整形提升的优先级从前到后排序为:一般整形(char,int,枚举)—>signed int(也就是int)—>unsigned int。
一句话概括就是整形提升就是把整形提升为int,如果int装不下,那么提升为unsigned int。当然如果提升之前,如果原来操作数里面本来就有unsigned int,最后的结果肯定是把所有的整形都提升为unsigned int。
一旦整型提升执行完毕,类型比较就又一次开始。如果一个操作数是unsigned long型,则第二个也被转换成unsigned long型。如果两个操作数的类型都不是unsigned long,而其中一个操作数是long型,则另一个也被转换成long型。long 类型的一般转换有一个例外,如果一个操作数是long型,而另一个是unsigned int型,那么只有机器上的long型足够长,以便能够存放unsigned int的所有值时(一般来说,在32位操作系统中,long型和int 型都用一个字长来表示,所以不满足这里的假设条件),unsigned int才会被转换为long型,否则两个操作数都被提升为unsigned long型
说了这么多,看下面的例子
printf( "%d",sizeof ('A') );
printf( "%d",sizeof ('A' + 'B') );
两个问题的答案分别是1和4。是不是很诡异?
第一个是1,因为‘A’是char类型,相当于sizeof(char),答案是1。但是第二个sizeof里面是一个表达式,需要进行整形提升,两个char转换为均转换为int类型,最后相当于sizeof(int),答案当然是4。