安静的类型转换

 

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。转换规则如下:

  1. 如果有一边的类型是long double ,则把另一边也转成long double

  2. 否则,如果有一边的类型是double ,则把另一边也转成double

  3. 否则,如果有一边的类型是float ,则把另一边也转成float

  4. 否则,两边应该都是整型,首先按上一小节讲过的规则对ab 做Integer Promotion,然后如果类型仍不相同,则需要继续转换。首先我们规定charshortintlonglong long 的转换级别(Integer Conversion Rank)一个比一个高,同一类型的有符号和无符号数具有相同的Rank。转换规则如下:

    1. 如果两边都是有符号数,或者都是无符号数,那么较低Rank的类型转换成较高Rank的类型。例如unsigned intunsigned long 做算术运算时都转成unsigned long

    2. 否则,如果一边是无符号数另一边是有符号数,无符号数的Rank不低于有符号数的Rank,则把有符号数转成另一边的无符号类型。例如unsigned longint 做算术运算时都转成unsigned longunsigned longlong 做算术运算时也都转成unsigned long

    3. 剩下的情况是:一边有符号另一边无符号,并且无符号数的Rank低于有符号数的Rank。这时又分为两种情况,如果这个有符号数类型能够覆盖这个无符号数类型的取值范围,则把无符号数转成另一边的有符号类型。例如遵循LP64的平台上unsigned intlong 在做算术运算时都转成long

    4. 否则,也就是这个有符号数类型不足以覆盖这个无符号数类型的取值范围,则把两边都转成有符号数的Rank对应的无符号类型。例如在遵循ILP32的平台上unsigned intlong 在做算术运算时都转成unsigned long (摘自http://learn.akae.cn/media/ch15s03.html)

回到前面那个例子,i是int类型,sizeof(i)是unsigned int类型。根据条件要用4.b这个分支来处理,两个数都要转换成 unsigned int ,而 -1 转换成无符号数是个很大的数,大于 sizeof(i),所以 JJ 就不见了。。。。
再来看个例子
这一次,
JJ他他妈的回来了!
要解释这个结果,可以用Integer Promotion 来回答。
因为两个操作数类型不一致,所以对unsigned char进行Integer Promotion,由于1完全可以用 int 来表示,所以右边的操作数就隐式转换为 int 类型,-1和1比较,当然-1比较小。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值