【问题标题】:To understand a C code about endianness了解有关字节序的 C 代码
【发布时间】:2009-07-21 00:13:46
【问题描述】:

我正在学习big and little-endianness

1.下面代码中| \的作用是什么?

...

#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)

  #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
                    (((uint16_t)(A) & 0x00ff) << 8))
...

2。代码中(A)的作用是什么?

【问题讨论】:

  • 您不需要 mask & 0xff00 或 & 0x00ff - 在第一种情况下,底部 8 位被屏蔽,因为它们从底部移开。在第二种情况下,位溢出并丢失。 (uint16_t)(((uint16_t)(A) >> 8) | ((uint16_t)(A)
  • @Tom Leys 不同意第二种情况。 (( (uint16_t)(A) ) &lt;&lt; 8))A 被转换为 uint16_t 保留其 16 个 LSbits。然后考虑通常的整数提升,例如可能是 32 位 int。然后将该值移动 8。不太可能是 OP 想要的。

标签: c endianness


【解决方案1】:

'|'是按位或运算符。它基本上结合了价值观。 'A' 是来自#define htons 的参数。它用括号括起来,这样表达式就不会混淆程序员或编译器。 '\' 将宏继续到下一行。 (宏通常在行尾结束。)

此宏获取 A 中的 16 位值并屏蔽前 8 位。然后它获取该值并将其右移 8 位。这意味着前 8 位现在位于 16 位值的底部。接下来,它会屏蔽掉 A 中原始值的前 8 位,并将剩下的 8 位移位。这意味着底部的 8 位现在位于顶部。最后,它将两个值重新组合为一个值。

最终结果是顶部和底部字节交换了位置。

【讨论】:

    【解决方案2】:

    这段代码只不过是标准的 C 预处理器宏。

    | 是按位或运算符。 \ 转义换行符,以便 #define 可以继续到下一行。 (A) 是宏的参数。

    【讨论】:

      【解决方案3】:

      |对两个整数执行按位“或” \ 是一个转义字符,允许 #define 继续到下一行

      【讨论】:

      • 我似乎晚了 30 秒才回答这个问题。 :P
      【解决方案4】:

      它是一个宏,当你使用它时它会被扩展。

      如果你例如使用(“调用”)宏作为

      uint16_t i = htons(0x1234);
      

      它将扩展为:

      uint16_t i =  ((((uint16_t)(0x1234) & 0xff00) >> 8) |(((uint16_t)(0x1234) & 0x00ff) << 8));
      

      这与函数中的变量并没有什么不同,例如

      uint16_t htons(uint16_t A) 
      {
         return (A & 0xff00) >> 8) | (A & 0x00ff) << 8);
      }
      

      【讨论】:

      • 对于 C/C++ 程序员最重要的启示之一,请考虑 uint16_t i = 0x1233; uint16_t j = htons(i++); 的结果。
      猜你喜欢
      • 1970-01-01
      • 2012-12-09
      • 2023-03-09
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多