我建立了这个联合,以便在位和整数之间轻松地来回访问。 (事实上,我找了一种方法来r / w一个有符号int的所有位,很容易,没有可移植性的陷阱,我很好地搞砸了)
typedef union {
struct {
unsigned int b32 : 1;
unsigned int b31 : 1;
unsigned int b30 : 1;
unsigned int b29 : 1;
unsigned int b28 : 1;
unsigned int b27 : 1;
unsigned int b26 : 1;
unsigned int b25 : 1;
unsigned int b24 : 1;
/* etc. */
unsigned int b01 : 1; /* LSB */
} field;
uint32_t word;
int32_t integer;
} Bit32Field_T;
正如预期的那样,每个bxx字段都允许我访问底层32字节整数的位。
但是,此代码仅对sparc(大端)CPU有效。对于little-endian(x86),我必须镜像每个字段,从b01到b32,以获得预期的行为。
typedef union {
struct {
unsigned int b01 : 1; /* LSB */
unsigned int b02 : 1;
unsigned int b03 : 1;
unsigned int b04 : 1;
unsigned int b05 : 1;
unsigned int b06 : 1;
unsigned int b07 : 1;
unsigned int b08 : 1;
unsigned int b09 : 1;
/* etc. */
unsigned int b32 : 1;
} field;
uint32_t word;
int32_t integer;
} Bit32Field_T;
我认为小端是关于反转字节而不是位!我应该如何理解所包装的包装?
(一切都用gcc编译,在solaris下用于BE,debian用于LE)
答案 0 :(得分:0)
我遇到类似问题的方法,即将32位字从小端转换为大端,是:
unsigned char buf[4];
uint32_t word;
fread(buf, sizeof(buf), 1, fp);
word = buf[0] |
(buf[1] << 8) |
(buf[2] << 16) |
(buf[3] << 24);
我同意你的代码有效是奇怪的,我原本预计Pickif建议的方法是必需的
如果它是依赖于编译器而不是与硬件有关并且与联合方法有关,则值得采用M Oehm提取位的建议
答案 1 :(得分:-1)
对于小端,你必须这样做
typedef union {
struct {
unsigned int b24 : 1;
unsigned int b25 : 1;
unsigned int b26 : 1;
unsigned int b27 : 1;
unsigned int b28 : 1;
unsigned int b29 : 1;
unsigned int b30 : 1;
unsigned int b31 : 1;
unsigned int b32 : 1;
unsigned int b16 : 1;
unsigned int b17 : 1;
unsigned int b18 : 1;
unsigned int b19 : 1;
unsigned int b20 : 1;
unsigned int b21 : 1;
unsigned int b22 : 1;
unsigned int b23 : 1;
unsigned int b24 : 1;
/* etc. */
unsigned int b08 : 1; /* LSB */
} field;
uint32_t word;
int32_t integer;
} Bit32Field_T;