【问题标题】:Bit shift operator disregards data size位移运算符不考虑数据大小
【发布时间】:2014-01-31 06:24:51
【问题描述】:

我在用 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) 上产生相同的结果。这种行为的原因是什么?

【问题讨论】:

  • &gt;&gt; 的操作数根据标准 C 规则进行扩展(我现在忘记了)。但基本上a 扩展为int

标签: c++ c bit-manipulation


【解决方案1】:

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

(a>>4 )

a 被转换为 int 类型。

来自 C++ 标准

除 bool、char16_t、char32_t 或 wchar_t 其整数转换等级 (4.13) 小于 如果 int 可以表示所有,则 int 可以转换为 int 类型的纯右值 源类型的值;否则,源纯右值可以是 转换为 unsigned int 类型的纯右值。

【讨论】:

  • 我猜它提升为无符号整数?
  • 不,char 类型的值可以放在 int 类型中而不会丢失。
  • 在这种情况下没有问题,因为a是无符号字符并且提升的值是无符号的。
  • @chux a in 转换为有符号整数。但是提升的值是正的,符号位等于 0。所以没有任何问题。
  • @Joky 我确信更窄的 unsigned 会被提升为 unsigned int,而 int 会被提升为 int。但相反,我们将 unsigned char 转换为 int,这看起来很奇怪。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 2020-07-27
    相关资源
    最近更新 更多