【问题标题】:Operator "<<= " : What does it it mean?运算符“<<=”:这是什么意思?
【发布时间】:2021-12-18 16:07:04
【问题描述】:

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

这是我的代码:

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

我显然意识到我不知道运营商&lt;&lt;=在做什么,我以为c = c &lt;&lt; 2。

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

【问题讨论】:

  • 我查看了它,但对我没有帮助:(
  • 我们如何获得第二个 printf: ffffffac ?那么第一次打印和第二次打印有什么不同呢?
  • 我相信这与第一个被提升为int 并打印为int,第二个被提升为int(用于轮班)然后返回@ 987654329@(存储在c)然后再次返回int进行打印。
  • 是的,很有可能,现在我也注意到了
  • 从技术上讲,您的代码中有 undefined behavior:格式说明符 %x 用于 unsigned 整数,而您的操作结果将是有符号整数。格式说明符和参数类型之间的这种不匹配是 UB。

标签: c operators


【解决方案1】:

你的想法是对的

c <<= 2

等价于

c = c << 2

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

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

【讨论】:

  • C 标准没有定义负值的左移,将超出范围的值分配给有符号的char 是实现定义的。 char 是 C 中定义的一个字节;它在几乎所有系统上都是 8 位。
【解决方案2】:

&lt;&lt;= 表示移位和分配。这是c = c &lt;&lt; 2; 的复合赋值版本。

这里有几个问题:

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

  • c&lt;&lt;2 受制于Implicit type promotion rules - 特别是c 将被提升为已签名的int。如果上一个问题发生在您的 char 为负值的情况下,c 现在持有负值 int。

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

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

至于如何修复代码,这取决于您希望实现的目标。建议转换前投到uint32。

【讨论】:

    猜你喜欢
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2013-05-07
    • 2013-07-03
    相关资源
    最近更新 更多