这是代码:
int main()
{
char c = 0x00;
//c |= 0x0A;
c |= 0xA0;
while(c != 0x00)
{
cout << (c & 1) << endl;
c = (c >> 1);
}
}
为什么当or
使用0X0A
而不使用0xA0
时,此代码可以正常工作,因为数字0xA0很大,以适应已签名的字符,但为什么我不允许设置0xA0的位?
当我打印循环时,它永远不会打破,它只打印一个?怎么样?
答案 0 :(得分:4)
这是因为执行右移时的符号扩展。
0xA0 <=> 10100000 binary (and is a negative number because the MSB is set to 1)
(0xA0 >> 1) <=> 11010000
char c
替换unsigned char c
转移后掩盖MSB。
int main()
{
char c = 0x00;
//c |= 0x0A;
c |= 0xA0;
while(c != 0x00)
{
cout << (c & 1) << endl;
c = (c >> 1) & 0x7f;
}
}
请注意,char
通常是带符号的(范围-128..127),但有些c / C ++编译器将char
定义为unsigned
(AIX xlC编译器已知情况)。< / p>
答案 1 :(得分:1)
当正确移位负数时,您的实现必须在最高位添加1(操作符的行为是实现定义的,因此通常取决于可用的CPU指令)。
0xA0 = 1010 0000 binary
第一次取样c & 1
- 最低位 - 它实际上是0.然后......
c = (c >> 1)
...将其转移到1101 0000,然后转移到1110 1000,11111 0111,1111 1011,11111 1101,11111 1110,11111 1111 - 然后稳定并且永远不会进一步变化。因此,您继续打印1s并且永远不会满足c == 0的终止条件。
当我打印循环时,它永远不会打破,它只打印一个?怎么样?
嗯,它一开始会打印几个0,但是你的屏幕可能会在瞬间滚过它们,之后你只能看到1。