C语言中的位移运算符优先级

4
在C语言中,位移操作符并不像我预期的那样工作。这无疑是我的误解,能否有人解释一下发生了什么?
unsigned char in = 155;
unsigned char res;

res = (in << 6) >> 7;

应该与之相同

res = in << 6;
res = res >> 7; // can also use res >>= 7;

但实际情况并非如此。
第一个结果是:
in  = 10011011
res = 01001101

第二个(如预期):
in  = 10011011
res = 00000001

看起来在第一次操作中,它是在原始数据上每个转移都进行操作,而不是先进行第一个转换,然后在第一个结果上执行第二个转换。有什么想法?


1
@keshlam 这是一个答案。 - Maroun
在此处阅读有关 C 的 int 提升规则的更多信息:http://en.cppreference.com/w/cpp/language/implicit_cast - phuclv
尝试使用“-Wall -Wextra -Wconversion”编译。请参阅OWAP的“C-Based Toolchain Hardening”(http://www.owasp.org/index.php/C-Based_Toolchain_Hardening)以尽早发现这些问题。 - jww
2个回答

11

计算使用 int 类型。在第二种情况下,你正在赋值给 res,它会被截断成8位,然后再进行移位操作。而在第一种情况下,你没有这样做,因此截断不会发生,高位将被保留并向下移位。


1
解释编译器为什么要操作整数:整数提升规则。 - mfro
编译器也有可能将你的 <<6 和 >>7 优化为单个 >>1。虽然编译器这样做会被认为是一个小故障,但这并不是不可想象的。 - Robherc KV5ROB

2

据我所知,对于按位移位运算符,每个操作数都应该是整型类型。您不应该使用字符类型。

如果您这样做,您将会发现差别:

res = in << 6;
printf("%p %p \n",res,(in << 6));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接