C陷阱篇之移位运算

    C语言移位运算有一些不确定性及误区,主要包含两个问题:

右移运算的空出位用0还是符号位填充?换句话右移n位与除以2n是否等价?

    无符号整数右移,左边空位会用0填充,所以无符号右移n位与除以2n 等价。

    有符号整数右移,用0还是符号位填充由编译器自行决定C标准中未定义。当有符号数为正数时,符号位也为0,所以总是用0填充,右移n位与除以2n 等价;当有符号数为负,右移后填充位可能为0也可能为1,右移与除以2n不等价。所以要避免对有符号数的右移操作,因为其结果不确定。换句话,无符号数的右移操作才能确保得到期望结果。

    课堂上老师总讲,整数右移1位等于除2,移位比除法高效,这其实是很大的误导。能用移位代替除法的场合,编译器会自动优化;而对不能转换的(有符号负数),手动转换,反而落入陷阱,导致错误。去检查一下自己代码里是否包含有符号数的右移操作吧!

    保持用移位实现位操作,除法实现算术运算。自己把除法改成移位,纯属画蛇添足。

移位的数量范围怎样确定?

    如果待移位的变量长度为n,则移动位数必须大于等于0且小于n。也就是说,一次单独操作中不可能把所有位从变量中移出。例如对于int nn << 31n << 0合法,但n << 32n << -1则完全非法。这也是包含移位操作的代码要注意的。

你可能感兴趣的:(C语言,移位,陷阱,signed)