sizeof(i)等于4,i等于-1,照理来说控制台应该会打印JJ,可是实际上
JJ他他妈的不见了 !
这和C的隐式转换有关。先解释一个术语 Integer Promotion
在一个算术表达式中,编译器总要把表达式的操作数统一成同一种类型才能做处理,如果不同,就要进行类型转换。类型转换过程中,遇到char, short int 或者 bit-field (包括他们的有符号和无符号类型),如果源类型能完整的用 int 类型表示,就转换成 int,否则转换成 unsigned int,这个过程叫做Integer Promotion 。
下面是ANSI C标准6.2.1.5的翻译
两个算术类型的操作数做算术运算,比如a + b
,如果两边操作数的类型不同,编译器会自动做类型转换,使两边类型相同之后才做运算,这称为Usual Arithmetic Conversion。转换规则如下:
-
如果有一边的类型是
long double
,则把另一边也转成long double
。 -
否则,如果有一边的类型是
double
,则把另一边也转成double
。 -
否则,如果有一边的类型是
float
,则把另一边也转成float
。 -
否则,两边应该都是整型,首先按上一小节讲过的规则对
a
和b
做Integer Promotion,然后如果类型仍不相同,则需要继续转换。首先我们规定char
、short
、int
、long
、long long
的转换级别(Integer Conversion Rank)一个比一个高,同一类型的有符号和无符号数具有相同的Rank。转换规则如下:-
如果两边都是有符号数,或者都是无符号数,那么较低Rank的类型转换成较高Rank的类型。例如
unsigned int
和unsigned long
做算术运算时都转成unsigned long
。 -
否则,如果一边是无符号数另一边是有符号数,无符号数的Rank不低于有符号数的Rank,则把有符号数转成另一边的无符号类型。例如
unsigned long
和int
做算术运算时都转成unsigned long
,unsigned long
和long
做算术运算时也都转成unsigned long
。 -
剩下的情况是:一边有符号另一边无符号,并且无符号数的Rank低于有符号数的Rank。这时又分为两种情况,如果这个有符号数类型能够覆盖这个无符号数类型的取值范围,则把无符号数转成另一边的有符号类型。例如遵循LP64的平台上
unsigned int
和long
在做算术运算时都转成long
。 -
否则,也就是这个有符号数类型不足以覆盖这个无符号数类型的取值范围,则把两边都转成有符号数的Rank对应的无符号类型。例如在遵循ILP32的平台上
unsigned int
和long
在做算术运算时都转成unsigned long
(摘自http://learn.akae.cn/media/ch15s03.html)
-