【问题标题】:Bit order from low to high / Mapping structs with bitfields in C从低到高的位顺序/在 C 中使用位域映射结构
【发布时间】:2015-12-05 17:47:02
【问题描述】:

我最近在玩 C 中的位域,显然,位是从低到高排序的,尽管 Google 不支持这个论点(例如 Wikipedia。)

获取以下代码(http://ideone.com/UwWfJM):

#include <stdio.h>

struct bits {
    unsigned char a : 1;
    unsigned char b : 1;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
    unsigned char f : 1;
    unsigned char g : 1;
    unsigned char h : 1;
};

int main(int argc, char **argv)
{
    unsigned char c = 33;
    struct bits *b = (struct bits *) &c;

    printf("dec: %u\n", c);
    printf("bits: %x", b->a);
    printf("%x", b->b);
    printf("%x", b->c);
    printf("%x", b->d);
    printf("%x", b->e);
    printf("%x", b->f);
    printf("%x", b->g);
    printf("%x\n", b->h);

    return 0;
}

输出是

dec: 33
bits: 10000100

...虽然我曾预计位顺序是相反的(即00100001,MSB 在第一位,LSB 在最后一位)。

有人可以解释这种行为吗?
此外,我可以假设映射总是在这个方向吗?

注意:不是询问字节顺序,这是关于字节顺序的。我的问题的背景是我试图将缓冲区映射到结构。缓冲区包含一个 UDP 消息,由一个“位映射”组成(即“位置 x 的位意味着这个,位置 yz的位> 意思是,等等)。

谢谢!

【问题讨论】:

  • 00100001, with the MSB in the first place and the LSB in the last place 我无法理解这句话,因为您的firstlast 非常模棱两可。你能更详细地解释你的期望吗?顺便说一句,注意你的打印顺序,你先打印a,这会产生第一个1。也许你误会了。
  • 顺便说一句,由于您的示例使用 char 和 8 位长的位字段组合,它确实与字节序无关。在结构中,a 代表最低位,这是正确的。再次,可能您对打印有误解。
  • 好吧,firstlast 我指的是输出中以从左到右的阅读顺序显示的位。我很清楚,例如b-&gt;a 首先打印并输出1。这是我问题的核心(@andrew-henle 已经回答了)。

标签: c struct bit-manipulation bit-fields


【解决方案1】:

C standard 的每个 6.7.2.1:

一个单元内位域的分配顺序(高位到 低阶或低阶到高阶)是实现定义的。

【讨论】:

  • 谢谢,完美答案!
  • 虽然 C 标准没有定义位域的顺序,但它不是随机的。编译器将以明确定义的方式为该编译器和体系结构分配位。但是,为了获得最佳的跨平台兼容性,最好完全避免位字段,而改用“移位和屏蔽”宏。
【解决方案2】:

位域的内存布局没有定义,所以它依赖于编译器。可以通过enter link description here

【讨论】:

  • 谢谢!确实,在我问这个问题之前我没有找到那个帖子!
【解决方案3】:

我相信您的困惑在于您呈现结果的方式。您希望它像正常数字一样在右侧打印 LSB,但您的代码打印了一串以左侧 LSB 开始并打印到右侧的位。

您的结果显示位 a 与预期的一样位于最低(第一个,最低有效)内存位中。

【讨论】:

    猜你喜欢
    • 2013-11-11
    • 2013-10-22
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多