位移运算符忽略数据大小

时间:2014-01-30 21:57:23

标签: c++ c bit-manipulation

我在使用C编程为8位AVR微控制器时遇到了意外行为: 请考虑以下事项:

unsigned char a = 0xFF, b = 0xFF;
unsigned short c = ((a>>4)<<8)+b;
printf("%x",c);

其中字节a的高阶半字节包含位8..11且字节b包含12位值c的位7..0。该代码的目的最初是删除字节a中不需要的低半字节,然后将ab组合在一起以产生c的值。然而,后来我意识到代码不应该工作,因为a是一个8位值,并且将它向左移8位应该导致将字节清除为0,最终结果为0x00FF。相反,代码产生的结果为0x0FFF,如最初的预期。该代码在微控制器(avr-gcc)和PC(gcc)上产生相同的结果。这种行为的原因是什么?

2 个答案:

答案 0 :(得分:4)

对使用移位运算符时排名小于int的整数类型执行整数提升。所以在这个表达式中

(a>>4 )

a转换为int类型。

来自C ++标准

  

除bool,char16_t,char32_t或之外的整数类型的prvalue   wchar_t,其整数转换等级(4.13)小于等级   如果int可以表示all,则int可以转换为int类型的prvalue   源类型的值;否则,源prvalue可以   转换为unsigned int类型的prvalue。

答案 1 :(得分:1)

在C中,大多数较小类型的数学会产生int。您可以通过将结果转换回unsigned charuint8_t来获得所需的答案。