我想了解为什么我的程序
#include<stdio.h>
void main()
{
printf("%x",-1<<4);
}
打印fffffff0
。
这个程序正在做什么,<<
运算符做了什么?
答案 0 :(得分: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。这是非常有意的:历史上不同的平台有不同的方式来表示负数,并且各种处理器的移位指令具有不同的细微差别,因此我们为移位运算符获得的“定义行为”或多或少是大多数人常用的“安全子集”。 “正常”架构。
答案 1 :(得分:1)
这意味着取位表示-1并将其向左移动4次
这意味着
11111111 11111111 11111111 11111111 = ffffffff
转移:
11111111 11111111 11111111 11110000 = fffffff0
"%x"
格式说明符表示以十六进制表示法打印出来。
答案 2 :(得分:0)
这是左移二元运算符。你离开-1乘以4位:
-1 == 1111 1111 1111 1111 1111 1111 1111 1111(2) == FFFFFFFF
-1 << 4 == 1111 1111 1111 1111 1111 1111 1111 0000(2) == FFFFFFF0
答案 3 :(得分:0)
“%x”表示您的整数将以十六进制值显示。
-1&lt;&lt; 4意味着二进制值“-1”将被移位4位
答案 4 :(得分:0)
“&LT;&LT;”是左移算子。 -1&lt;&lt;&lt;&lt;&lt;&lt; 4表示左移-1,因为-1是-1 0xffffffff,你将得到0xfffffff0
更多内容可以在wiki http://en.wikipedia.org/wiki/Bitwise_operation
中找到