何时在 C 中使用位域

新手上路,请多包涵

关于“为什么我们需要使用位域?”这个问题,在谷歌上搜索我发现位域用于标志。

现在很好奇,

  1. 它是实际使用位域的唯一方法吗?
  2. 我们是否需要使用位域来节省空间?

一种从书中定义位域的方法:

 struct {
    unsigned int is_keyword : 1;
    unsigned int is_extern :  1;
    unsigned int is_static : 1;
} flags;

  1. 为什么我们使用int?
  2. 占用了多少空间?

我很困惑为什么我们使用 int ,而不是 short 或小于 int 的东西。

  1. 据我了解,内存中只占用了 1 位,而不是整个 unsigned int 值。这是对的吗?

原文由 YohanRoth 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 973
2 个回答

现在我很好奇,[是标志]实际使用位域的唯一方法吗?

不,标志不是使用位域的唯一方式。它们也可用于存储大于一位的值,尽管标志更常见。例如:

 typedef enum {
    NORTH = 0,
    EAST = 1,
    SOUTH = 2,
    WEST = 3
} directionValues;

struct {
    unsigned int alice_dir : 2;
    unsigned int bob_dir : 2;
} directions;

我们是否需要使用位域来节省空间?

位域确实节省了空间。它们还允许以更简单的方式设置非字节对齐的值。我们可以使用与在 struct 中设置字段相同的语法,而不是移位和使用按位运算。这提高了可读性。使用位域,您可以编写

directions.alice_dir = WEST;
directions.bob_dir = SOUTH;

但是,要将多个独立值存储在一个 int (或其他类型)的空间中而没有位域,您需要编写如下内容:

 #define ALICE_OFFSET 0
#define BOB_OFFSET 2
directions &= ~(3<<ALICE_OFFSET); // clear Alice's bits
directions |= WEST<<ALICE_OFFSET; // set Alice's bits to WEST
directions &= ~(3<<BOB_OFFSET);   // clear Bob's bits
directions |= SOUTH<<BOB_OFFSET;  // set Bob's bits to SOUTH

提高位域的可读性可以说比在这里和那里节省几个字节更重要。

为什么我们使用int?占用了多少空间?

整个 int 的空间都被占用了。我们使用 int 因为在很多情况下,这并不重要。如果对于单个值,您使用 4 个字节而不是 1 或 2 个字节,您的用户可能不会注意到。对于某些平台,大小确实更重要,您可以使用占用更少空间的其他数据类型( charshortuint8_t 等)。

据我了解,内存中只占用了 1 位,而不是整个 unsigned int 值。这是对的吗?

不,这是不正确的。整个 unsigned int 将存在,即使您只使用其中的 8 个位。

原文由 Eric Finn 发布,翻译遵循 CC BY-SA 4.0 许可协议

如今, 微控制器(MCU) 与处理器一起在芯片上具有外围设备,例如 I/O 端口、 ADCDAC

在 MCU 提供所需的外围设备之前,我们将通过连接到微处理器的缓冲地址和数据总线来访问我们的一些硬件。一个指针将被设置到设备的内存地址,如果设备看到它的地址以及 R/W 信号和可能的芯片选择,它将被访问。

通常,我们希望访问设备上的单个或一小组位。

原文由 user2579721 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题