现在我很好奇,[是标志]实际使用位域的唯一方法吗?
不,标志不是使用位域的唯一方式。它们也可用于存储大于一位的值,尽管标志更常见。例如:
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 个字节,您的用户可能不会注意到。对于某些平台,大小确实更重要,您可以使用占用更少空间的其他数据类型(char、short、uint8_t 等)。
据我了解,内存中只占用了 1 位,而不是整个 unsigned int 值。对吗?
不,这是不正确的。整个unsigned int 将存在,即使您只使用其中的 8 个位。