C Union - 显示一个字节的所有 8 位
C Union - displaying all 8 bits of a byte
我必须创建联合,让我能够从特定字节中获取(并显示)每一位。
这有意义吗?我想我知道如何使用按位运算符来做到这一点,但不知道如何使用联合来达到同样的效果。
您可以使用包含 8 个一位位域的 unit8_t
和 struct
的并集。然而,即使这会让您访问各个位,您也不知道它们是哪些位!这将取决于您的编译器如何将位字段分配给底层字节,这可能取决于您的目标机器的字节顺序。
参见this SO Q&A。
推荐使用位运算。您也可以结合联合和位字段来提取位,但请注意,这是依赖于字节顺序的,这就是为什么不推荐这样做的原因,不过这里有一个示例供您学习:
#include <stdio.h>
#include <string.h>
union Bits {
char b;
struct bits {
#ifdef LITTLE_ENDIAN
unsigned int b0: 1;
unsigned int b1: 1;
unsigned int b2: 1;
unsigned int b3: 1;
unsigned int b4: 1;
unsigned int b5: 1;
unsigned int b6: 1;
unsigned int b7: 1;
#else
// reverse the order of the bit fields.
#endif
} bits;
};
int main(void) {
char a = 'A';
union Bits b;
b.b = a;
printf("0x%x\n", a);
printf("%d%d%d%d%d%d%d%d\n", b.bits.b7, b.bits.b6, b.bits.b5, b.bits.b4, b.bits.b3, b.bits.b2, b.bits.b1, b.bits.b0);
return 0;
}
这应该输出
0x41
01000001
从 C99 开始,我们有了匿名结构和联合,让事情变得更简单:
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
union disByte
{
uint8_t byte;
// Assuming little endian
struct {
bool b0: 1;
bool b1: 1;
bool b2: 1;
bool b3: 1;
bool b4: 1;
bool b5: 1;
bool b6: 1;
bool b7: 1;
};
};
int main()
{
union disByte foo;
foo.byte = 42;
printf("%d %d %d %d %d %d %d %d\n", foo.b0, foo.b1, foo.b2, foo.b3, foo.b4, foo.b5, foo.b6, foo.b7);
}
然而,通常首选位操作(您的问题已被标记 "bit-manipulation")。
#define XTH_BIT_OF(NUM, X) (bool)(NUM & (1U << X))
使用位操作的优点是:
- 您无需担心字节序问题。
- 看起来更短更清晰。
您可以使用位域和联合来执行此操作:
#include <stdio.h>
typedef union {
struct {
unsigned int:0;
unsigned int firstBit : 1;
unsigned int secondBit : 1;
unsigned int thirdBit : 1;
unsigned int fourthBit : 1;
unsigned int fifthBit : 1;
unsigned int sixthBit : 1;
unsigned int seventhBit : 1;
unsigned int eigthBit : 1;
};
int raw;
} bitsOfByte;
int main()
{
bitsOfByte dt;
dt.raw = 254;
printf("Bits are %d/%d/%d/%d/%d/%d/%d/%d", dt.firstBit, dt.secondBit, dt.thirdBit, dt.fourthBit, dt.fifthBit, dt.sixthBit, dt.seventhBit, dt.eigthBit);
return 0;
}
注意在这个实现中,第一位是低位
我必须创建联合,让我能够从特定字节中获取(并显示)每一位。 这有意义吗?我想我知道如何使用按位运算符来做到这一点,但不知道如何使用联合来达到同样的效果。
您可以使用包含 8 个一位位域的 unit8_t
和 struct
的并集。然而,即使这会让您访问各个位,您也不知道它们是哪些位!这将取决于您的编译器如何将位字段分配给底层字节,这可能取决于您的目标机器的字节顺序。
参见this SO Q&A。
推荐使用位运算。您也可以结合联合和位字段来提取位,但请注意,这是依赖于字节顺序的,这就是为什么不推荐这样做的原因,不过这里有一个示例供您学习:
#include <stdio.h>
#include <string.h>
union Bits {
char b;
struct bits {
#ifdef LITTLE_ENDIAN
unsigned int b0: 1;
unsigned int b1: 1;
unsigned int b2: 1;
unsigned int b3: 1;
unsigned int b4: 1;
unsigned int b5: 1;
unsigned int b6: 1;
unsigned int b7: 1;
#else
// reverse the order of the bit fields.
#endif
} bits;
};
int main(void) {
char a = 'A';
union Bits b;
b.b = a;
printf("0x%x\n", a);
printf("%d%d%d%d%d%d%d%d\n", b.bits.b7, b.bits.b6, b.bits.b5, b.bits.b4, b.bits.b3, b.bits.b2, b.bits.b1, b.bits.b0);
return 0;
}
这应该输出
0x41
01000001
从 C99 开始,我们有了匿名结构和联合,让事情变得更简单:
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
union disByte
{
uint8_t byte;
// Assuming little endian
struct {
bool b0: 1;
bool b1: 1;
bool b2: 1;
bool b3: 1;
bool b4: 1;
bool b5: 1;
bool b6: 1;
bool b7: 1;
};
};
int main()
{
union disByte foo;
foo.byte = 42;
printf("%d %d %d %d %d %d %d %d\n", foo.b0, foo.b1, foo.b2, foo.b3, foo.b4, foo.b5, foo.b6, foo.b7);
}
然而,通常首选位操作(您的问题已被标记 "bit-manipulation")。
#define XTH_BIT_OF(NUM, X) (bool)(NUM & (1U << X))
使用位操作的优点是:
- 您无需担心字节序问题。
- 看起来更短更清晰。
您可以使用位域和联合来执行此操作:
#include <stdio.h>
typedef union {
struct {
unsigned int:0;
unsigned int firstBit : 1;
unsigned int secondBit : 1;
unsigned int thirdBit : 1;
unsigned int fourthBit : 1;
unsigned int fifthBit : 1;
unsigned int sixthBit : 1;
unsigned int seventhBit : 1;
unsigned int eigthBit : 1;
};
int raw;
} bitsOfByte;
int main()
{
bitsOfByte dt;
dt.raw = 254;
printf("Bits are %d/%d/%d/%d/%d/%d/%d/%d", dt.firstBit, dt.secondBit, dt.thirdBit, dt.fourthBit, dt.fifthBit, dt.sixthBit, dt.seventhBit, dt.eigthBit);
return 0;
}
注意在这个实现中,第一位是低位