运算符“<<=”:这是什么意思?

Operator "<<= " : What does it it mean?

我需要帮助解决这个问题,所以如果有人有类似的问题,它会帮助我。

这是我的代码:

char c=0xAB;
printf("01:%x\n", c<<2);
printf("02:%x\n", c<<=2);
printf("03:%x\n", c<<=2);

为什么程序打印:

01:fffffeac
02:ffffffac
03:ffffffb0

我期望打印出来的,也就是我在纸上得到的是:

01:fffffeac
02:fffffeac
03:fffffab0

我显然意识到我不知道操作员<<=在做什么,我以为c = c << 2

如果有人能澄清这一点,我将不胜感激。

你的想法是对的

c <<= 2

相当于

c = c << 2

但是你要记住c是一个单字节 (在几乎所有系统上),它只能包含八位,而像 0xeac 这样的值需要 12 位。

当值 0xeac 被分配回 c 时,该值将被 截断 并且最高位将被简单地忽略,留下您0xac(当提升为 int 时变为 0xffffffac)。

<<=表示shift和assign。它是 c = c << 2;.

复合赋值 版本

这里有几个问题:

  • char c=0xAB; 不能保证给出肯定的结果,因为 char 可能是 8 位有符号类型。参见 Is char signed or unsigned by default?。在这种情况下,0xAB 将以实现定义的方式转换为负数。通过在处理原始二进制字节时始终使用 uint8_t 来避免此错误。

  • c<<2 受制于 - 特别是 c 将升级为已签名的 int。如果之前的问题发生在您的 char 得到负值的情况下,c 现在会得到负值 int

  • C 中的左移负值会调用未定义的行为 - 这始终是一个错误。移动带符号的操作数一般来说几乎是不正确的。

  • %x 不是打印您最终得到的 int 的合适格式说明符,也不适合 char.

至于如何修复代码,就看你想达到什么目的了。建议转换到uint32再移位。