为什么0x56 << 2
不等于0x58
?
0x56
为0 1 0 1 0 1 1 0
,因此向左移动2位
0 1 0 1 1 0 0 0
01011000
是0x58
。但它不是正确答案0x158
。那么我在这里缺少什么?
即使我这样做:
int main(){
unsigned char a;
a=0x56;
printf("%x",a<<2); // I am expecting the output to be 58 here.
}
为什么打印158. 为什么不考虑仅仅8位?
答案 0 :(得分:8)
位移运算符<style>
.float_center {
display: flex;
justify-content: center;
}
</style>
和<<
仅适用于整数。所以当你在这里使用它时,它们首先被提升为>>
(大于1个字节),然后完成转换。您可以看到6.5.7p3
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。
int
(带printf
和格式说明符)也期望参数为%x
类型。所以没有降级,你得到unsigned int
。
如果您希望结果只有一个字节,则应将结果转换回0x158
as -
unsigned char
或者您可以声明另一个变量printf("%x", (unsigned char)(a << 2));
并打印 -
b
您可以看到演示here。
答案 1 :(得分:2)
C11 6.5.7按位移位运算符
第2段:
每个操作数都应具有整数类型。
第3段:
对每个操作数执行整数提升。类型 结果是提升左操作数的结果。如果值 右操作数为负数或大于或等于宽度 在提升的左操作数中,行为未定义。
因此,由于整数提升,我们需要两个操作数int
类型。
答案 2 :(得分:2)
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
所以当你这样做时:
a<<2;
a
被提升为整数,然后完成移位操作。在printf()
中,您使用%x
格式说明符输出无符号十六进制整数,因此输出为158
。