> For the complete documentation index, see [llms.txt](https://labspc.gitbook.io/cnippets/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://labspc.gitbook.io/cnippets/chap6.-jie-gou-yu-lian-he/6.4-wei-zi-duan-bitfields.md).

# 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 %}
