2012-09-26 160 views

回答

6

<<操作者是左移位运算符; a<<b的结果是a移位到b位的左侧。你的代码存在的问题是你左移一个负整数,这会导致未定义的行为(尽管你的编译器可能会对此操作提供一些保证);另外,%x用于以十六进制打印无符号整数,并且您正在向其提供一个有符号整数 - 这又是未定义的行为。至于你为什么看到你所看到的:在2的补充架构-1被表示为“所有的”;因此,与32位int的计算机上,你将有:

11111111111111111111111111111111 = -1 (if interpreted as a signed integer) 

现在,如果你转向这个4个位置的左边,你会得到:

11111111111111111111111111110000 

%x符使得printf将这些东西解释为一个无符号整数,十六进制表示法是0xfffffff0。这很容易理解,因为4个二进制数字等于一个十六进制数字;二进制组中的1111组以十六进制变为f,二进制中的最后一个0000为十六进制中的最后一个0

同样,这里所说的所有这些行为仅仅是您的具体编译器工作的方式,就C标准而言,这是所有的UB。这是非常有意的:历史上不同的平台有不同的表示负数的方式,而且各种处理器的移位指令有不同的细微之处,所以我们得到的用于移位操作符的“定义的行为”或多或少是大部分常见的“安全子集” “正常”架构。

+0

感谢这么好的解释! –

+0

这是32位电脑的意思吗?请解释我的处理器和操作系统都是64位。 –

+0

对不起,我的意思是“在具有32位int的计算机上”。 –

0

这是左移二元运算符。您左移-4位:

-1 == 1111 1111 1111 1111 1111 1111 1111 1111(2) == FFFFFFFF 
-1 << 4 == 1111 1111 1111 1111 1111 1111 1111 0000(2) == FFFFFFF0 
0

“%x”表示您的整数将以十六进制值显示。

-1 < < 4意味着二进制值“-1”将被转移的4位

1

这意味着-1 取位表示,并将其转移到还剩4倍

这意味着需要

11111111 11111111 11111111 11111111 = ffffffff 

和Shift:

11111111 11111111 11111111 11110000 = fffffff0 

"%x"格式说明符表示以十六进制表示法打印出来

相关问题