我试图理解为什么我的程序
#include<stdio.h>
void main()
{
printf("%x",-1<<4);
}
打印fffffff0
。
这个程序在做什么,<<
操作员在做什么?
我试图理解为什么我的程序
#include<stdio.h>
void main()
{
printf("%x",-1<<4);
}
打印fffffff0
。
这个程序在做什么,<<
操作员在做什么?
运算符为<<
左移运算符;的结果a<<b
被a
移到b
位的左侧。
您的代码的问题是您将负整数左移,这会导致未定义的行为(尽管您的编译器可能会对此操作做出一些保证);此外,%x
用于以十六进制打印无符号整数,并且您正在向它提供有符号整数 - 再次未定义的行为。
至于为什么你看到你所看到的:在 2 的补码架构-1
上表示为“全1”;因此,在 32 位计算机上,int
您将拥有:
11111111111111111111111111111111 = -1 (if interpreted as a signed integer)
现在,如果你把它移到 4 个位置的左边,你会得到:
11111111111111111111111111110000
说明%x
符 makeprintf
将这些东西解释为一个无符号整数,在十六进制表示法中是0xfffffff0
. 这很容易理解,因为 4 个二进制数字等于一个十六进制数字;二进制中的1111
组变成f
十六进制,0000
二进制中的最后一个0
是十六进制的最后一个。
同样,特此解释的所有这些行为只是您的特定编译器的工作方式,就 C 标准而言,这都是 UB。这是非常有意的:历史上不同的平台有不同的方式来表示负数,并且各种处理器的移位指令有不同的微妙之处,所以我们得到的移位运算符的“定义行为”或多或少是大多数人常见的“安全子集” “正常”架构。
这意味着取-1的位表示并将其向左移动4次
这意味着采取
11111111 11111111 11111111 11111111 = ffffffff
并转移:
11111111 11111111 11111111 11110000 = fffffff0
"%x"
格式说明符意味着以十六进制表示法将其打印出来。
这是左移二元运算符。您将 -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
“%x”表示您的整数将以十六进制值显示。
-1 << 4 表示“-1”的二进制值将移动 4 位
“<<”是左移运算符。-1<<4 表示将 -1 左移 4。因为 -1 是 0xffffffff,所以你会得到 0xfffffff0
更多可以在 wiki http://en.wikipedia.org/wiki/Bitwise_operation中找到