# 6.4 位字段 Bit-fields

### 6.4.1 《krc-2e》对 bit-field 的解释 <a href="#h99cb" id="h99cb"></a>

<img src="https://img.imotao.com/i/2024/01/31/65ba256f190c3.png" alt="" width="1530">

### 6.4.2 位域/位字段/位段 demo <a href="#mktju" id="mktju"></a>

形如：

```c
struct bits {
    unsigned a:1;
    unsigned b:3;
    unsigned c:5;
}
```

这里 `a` 定义为 1 位,`b` 定义为 3 位,`c` 定义为 5 位。

**使用位段的好处是可以大大节省内存空间,因为多个小的字段可以联合起来装进一个字节中。**&#x5E76;且位段也可以用于**二进制表示、状态标志、寄存器等需要精细控制每一位的场景**。

然而位段也有其缺点,主要体现在不便操作,不能寻址,并且具体实现依赖于编译器。需要慎重使用。

总的来说,位段是C语言结构体的一项高级功能,允许精细化控制内存布局和利用率。使用得当可以发挥很好的作用。

### 6.4.3 位字段大小 <a href="#t7y9y" id="t7y9y"></a>

结论：**位域的大小不能超过其类型的大小。**&#x4F8B;如，如果你的位域是 int 类型的，那么它的大小不能超过 int 类型的大小。在大多数平台上，int 类型的大小是 32 位。

<img src="https://img.imotao.com/i/2024/01/31/65ba55eebb0fe.png" alt="" width="1168">

在大多数平台上，int 类型的大小是 32 位。

{% code title="6.4.1 bit-fields.c" lineNumbers="true" %}

```c
#include <stdio.h>

struct bits // total: 9 bits
{
    // unsigned a : 1;
    // unsigned b : 3;
    // unsigned c : 5;
    int a : 1;
    int b : 3;
    int c : 28;
};
int main()
{
    printf("Sizeof bits_var is: %lu", sizeof(struct bits)); 
}

/* 
  ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ 输出：Sizeof bits_var is: 4                                                                                        │
  └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 */
```

{% endcode %}

{% code title="" lineNumbers="true" %}

```c
#include <stdio.h>

struct bits // total: 9 bits
{
    // unsigned a : 1;
    // unsigned b : 3;
    // unsigned c : 5;
    int a : 1;
    int b : 3;
    int c : 29;
};
int main()
{
    printf("Sizeof bits_var is: %lu", sizeof(struct bits)); 
}

/* 
  ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ 输出：Sizeof bits_var is: 8                                                                                        │
  └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 */
```

{% endcode %}

### 6.4.4 特殊情况：0 位段 <a href="#lvxp8" id="lvxp8"></a>

在 C 语言中，位域的大小可以为 0。一个大小为 0 的位域用于强制下一个位域开始于下一个整数类型的存储单元。这通常用于对齐目的。在这个例子中，a 是一个 4 位的位域，然后是一个大小为 0 的位域，然后是 b，也是一个 4 位的位域。

**大小为 0 的位域将导致 b 开始于下一个存储单元，这样 a 和 b 就不会在同一个字节中。**&#x9700;要注意的是，大小为 0 的位域不能有名称，因为它们实际上不存储任何信息。

{% code title="6.4.4 zero-field.c" lineNumbers="true" %}

```c
#include <stdio.h>

// struct bits // total: 9 bits
// {
//     // unsigned a : 1;
//     // unsigned b : 3;
//     // unsigned c : 5;
//     int a : 1;
//     int b : 3;
//     int c : 29;
// };
struct bits
{
    unsigned a : 4;
    unsigned : 0;
    unsigned b : 4;
};
int main()
{
    printf("Sizeof bits_var is: %lu", sizeof(struct bits));
}

/*
  ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ 输出：Sizeof bits_var is: 8                                                                                        │
  └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 */
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://labspc.gitbook.io/cnippets/chap6.-jie-gou-yu-lian-he/6.4-wei-zi-duan-bitfields.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
