前言
今天有人问了 Shaun 一个移位的问题,就是下面这段 C 语言代码:
1 | unsigned short a = 0xffff; |
你认为会输出什么结果? ੧ಡ ⌣ ಡ੭
解答篇
正确答案是:0xfff0
。恐怕有一部分会像 Shaun 一样觉得答案就是 0xff0
才对,还像模像样的给出对应的说法:看 a
首先向左移四位,即去掉最左边的 f
,右边补 4 个 0 变成这样 0xfff0
;然后再向右移 8 位,a 将会变成这样 0x00ff
;最后向左移四位,得到 0x0ff0
,所以应该输出 0xff0
。但是,正确答案终究是正确答案。之所以会输出正确答案,是因为这里面还有一个整型提升。所谓的整型提升就是:
在一个表达式中,如果int能够表示原始类型中的所有数值,那么这个数值就被转成int型,否则,它被转成unsigned int型。这种规则被称为整型提升。所有其它类型都不会被整型提升改变。
所以在 a << 4 >> 8 << 4
中,会先将 a 提升为 int 型,即 a 会变成 0x0000ffff
,接着向左移四位,a 变成 0x000ffff0
,再向右移 8 位,变成 0x00000fff
,最后向左移 4 位,变成 0x0000fff0
,最后为了输出,再做一个隐式的类型转换(由 int 转 unsigned short),得到 0xfff0
,所以最后输出 0xfff0
。
后记
这个问题是一个刚入大学的童靴问 Shaun 的,刚问 Shaun 时 Shaun 还没反应过来,后来才想起有整型提升这么回事 o(╯□╰)o。btw,这位童靴主要是想去掉高 4 位和低 4 位只取中间 8 位的值,其实最简单的办法就是直接 a & 0x0ff0
,这样管它有没有整型提升,肯定能得到中间 8 位的值 (╯▽╰)。
参考资料
[1] C语言进阶:整型提升(http://blog.csdn.net/mishifangxiangdefeng/article/category/1058873)