移位混乱

Bit Shifting Confusion

为什么0x56 << 2不等于0x58

0x560 1 0 1 0 1 1 0 所以向左移动 2 位我们得到

         0 1 0 1 1 0 0 0

010110000x58。但这不是正确答案 0x158。那么我在这里缺少什么?

即使我这样做:

int main(){
    unsigned char a;
    a=0x56;
    printf("%x",a<<2);  // I am expecting the output to be 58 here.
} 

为什么打印 158。为什么只考虑 8 位?

移位运算符 <<>> 仅适用于整数。所以当你在这里使用它时,它们首先被提升为int(大于1个字节)然后完成移位。你可以看到它在6.5.7p3

的标准中提到

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.

printf(带有 %x 和格式说明符)还期望参数的类型为 unsigned int。所以没有执行降级,你得到 0x158

如果你希望结果只有一个字节,你应该将结果转换回 unsigned char as -

printf("%x", (unsigned char)(a << 2));

或者您可以声明另一个变量 b 并打印 -

unsigned char b;   
b = a << 2;
printf("%x", b);

您可以看到Demo here

C11 6.5.7 移位运算符

第 2 段:

Each of the operands shall have integer type.

第 3 段:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behaviour is undefined.

因此,由于整数提升,我们需要两个操作数 int 类型。

来自C Standards#6.5.7

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

所以当你这样做时:

a<<2;

a被提升为整数,然后完成移位操作。在 printf() 中,您使用的是 %x 格式说明符,它输出无符号十六进制整数,因此您得到的输出为 158.