我在使用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
中不需要的低半字节,然后将a
和b
组合在一起以产生c
的值。然而,后来我意识到代码不应该工作,因为a
是一个8位值,并且将它向左移8位应该导致将字节清除为0,最终结果为0x00FF。相反,代码产生的结果为0x0FFF,如最初的预期。该代码在微控制器(avr-gcc)和PC(gcc)上产生相同的结果。这种行为的原因是什么?
答案 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 char
或uint8_t
来获得所需的答案。