我想知道为什么我的程序为什么我的程序打印fffffff0?
#include<stdio.h>
void main()
{
printf("%x",-1<<4);
}
打印fffffff0
。
这个程序在做什么,<<
运营商做了什么?
我想知道为什么我的程序为什么我的程序打印fffffff0?
#include<stdio.h>
void main()
{
printf("%x",-1<<4);
}
打印fffffff0
。
这个程序在做什么,<<
运营商做了什么?
的<<
操作者是左移位运算符; 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。这是非常有意的:历史上不同的平台有不同的表示负数的方式,而且各种处理器的移位指令有不同的细微之处,所以我们得到的用于移位操作符的“定义的行为”或多或少是大部分常见的“安全子集” “正常”架构。
这是左移二元运算符。您左移-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
这意味着-1 取位表示,并将其转移到还剩4倍
这意味着需要
11111111 11111111 11111111 11111111 = ffffffff
和Shift:
11111111 11111111 11111111 11110000 = fffffff0
"%x"
格式说明符表示以十六进制表示法打印出来。
感谢这么好的解释! –
这是32位电脑的意思吗?请解释我的处理器和操作系统都是64位。 –
对不起,我的意思是“在具有32位int的计算机上”。 –