2017-05-30 46 views
4

我的问题是为什么a>>1移位标志位,但不是(a & 0xaaaaaaaa) >> 1当右移操作>>移位标志位,当它不?

代码片断

int a = 0xaaaaaaaa; 
std::cout << sizeof(a) << std::endl; 
getBits(a); 
std::cout << sizeof(a>>1) << std::endl; 
getBits(a >> 1); 
std::cout << sizeof(a & 0xaaaaaaaa) << std::endl; 
getBits(a & 0xaaaaaaaa); 
std::cout << sizeof((a & 0xaaaaaaaa)>>1) << std::endl; 
getBits((a & 0xaaaaaaaa) >> 1); 

结果

4 
10101010101010101010101010101010 
4 
11010101010101010101010101010101 
4 
10101010101010101010101010101010 
4 
01010101010101010101010101010101 
+1

移位操作服从左边参数的符号性。所以你应该质疑'a'的类型以及'a&0xaaaaaaaa'的类型。 –

+2

_“对于负数a,a >> b的值是实现定义的(在大多数实现中,这将执行算术右移,以便结果保持负值)。”_ source:http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators –

回答

8

a >> 1很无聊。它只是signed类型的实现定义为负数a

(a & 0xaaaaaaaa) >> 1更有趣。对于您有32位int(其中包括)的可能情况,0xaaaaaaaaunsigned文字(十六进制文字的模糊规则)。因此,由于C++类型促销规则a也转换为unsigned类型,因此表达式a & 0xaaaaaaaa的类型因此是unsigned

为酒吧测验提出了一个很好的问题。

参考:http://en.cppreference.com/w/cpp/language/integer_literal,尤其是“文字的类型”表。

+0

根据引用,0xaaaaaaaa不能放入'int'。所以它有'unsigned int'类型。这条规则并不晦涩。 – crvv

+1

确实,对于32位'int'你是对的。尽管只有一小部分C++程序员知道这一点。 – Bathsheba

+0

@crvv我认为引发大多数人的一点是使用无符号类型只适用于十六进制到八进制文字。如果一个十进制整数文字对于'int'来说太大了,它会选择下一个更大的有符号整数,如果十六进制和八进制符合,并且如果不符合则是下一个较大的有符号整数。 – NathanOliver