【BUG】C语言|左移之后,最高位的数字还在吗?(整型提升)

问题概述

这个错是刚学c语言的时候碰到的,突然好想我的c语言老师,所以在此记录一下。

#include<stdio.h>
void main(){
	unsigned short a=0x1000,debug,bug;
	bug=a<<4>>4;
	debug=a<<4;
	debug=debug>>4;
	printf("%x %x\n%d %d",bug,debug,sizeof(bug),sizeof(debug));
}

这里的运行结果是1000 0 2 2。因为我只截取了这一个突出问题,所以结果比较明显。
我希望得到的结果是0,但是如果直接往左移再往右移,由于整型提升[1],在运算过程中实际使用的是int类型,所以得到的结果是1000。
最高位数字只是在它能去的地方走了一趟,然后又回到原点,什么也没改。

[1]整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。

如果拆开赋值,在赋值过程中,4字节赋值给2字节的变量,得到的自然是2字节的值,所以并没有出错,符合预期,得到结果为0。

应用

循环位移类题目时可能会被坑。
如果想通过左移之后右移的方式把高位弄没,对于unsigned short变量,不能直接z=x<<4>>4,而应该分开写成z=x<<4,z=z>>4。

怀旧

当时对整型提升只是个模模糊糊的概念,误以为是栽在了内存溢出啊、强制类型转换啊之类的听起来高大上的坑上。于是鼓起勇气,跑讲台上问老师——这是俺大学第一次问老师题目~
因为问题表面有点扭曲,一开始老师也没找到问题根源嘿嘿嘿。因为这个问题是整型提升的典型,还特意在班上讲到了~(超高兴)
老师人超级好。这是大学第一个能认出我的老师~c语言只学一学期,太可惜了,以后找机会还选他的课(虽然卷子出得挺难)(期末没考好好难过,感觉愧对信任orz)

posted @ 2020-06-27 23:32  shandianchengzi  阅读(1)  评论(0编辑  收藏  举报  来源