Cprogramming 简明教程

Bit Fields in C

当我们声明结构或联合类型时,结构/联合类型变量的大小取决于其元素的个别大小。你可以设置位大小来限制大小,而不是默认内存大小。指定的大小称为 bit fields

这是用于声明位域的 syntax

struct {
   data_type elem : width;
};

假设你的 C 程序包含一个名为 status 的结构中分组的多个 TRUE/FALSE 变量,如下所示:

struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status;

此结构需要 8 字节的内存空间,但实际上,我们将在每个变量中存储“0”或“1”。C 编程语言提供了一种更好的方法来在这样的情况下利用内存空间。

如果你在结构内使用这样的变量,则可以定义这些变量的宽度,它告诉 C 编译器你只使用那么多的字节数。例如,上面的结构可以重写如下:

struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status;

上面的结构为 status 变量需要 4 字节的内存空间,但仅使用 2 位来存储值。

Example

如果你将最多使用 32 个变量,每个变量的宽度为 1 位,则 status 结构也将使用 4 字节。但是,只要你有 33 个变量,它就会分配内存的下一个槽,并且它将开始使用 8 个字节。

让我们检查下面的示例以了解这个概念 −

#include <stdio.h>

/* define simple structure */
struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status1;

/* define a structure with bit fields */
struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status2;

int main() {

   printf("Memory size occupied by status1: %d\n", sizeof(status1));
   printf("Memory size occupied by status2: %d\n", sizeof(status2));

   return 0;
}

Output

当编译和执行上面的代码时,它会生成以下输出 −

Memory size occupied by status1: 8
Memory size occupied by status2: 4

Bit Field Declaration

在结构内部,对位域的声明有以下形式 −

struct {
   type [member_name] : width ;
};

下表描述了位域的可变元素 −

Element

Description

type

确定如何解释位域值的整型。类型可以是 int, signed intunsigned int

member_name

位域的名称。

width

位域中的位数。“宽度”必须小于或等于指定类型的位宽。

使用预定义宽度定义的变量被称为 bit fields 。位域可以容纳超过一个位;例如,如果您需要一个变量来储存从 0 到 7 的值,那么您可以定义一个位宽为 3 位的位域,如下所示 −

struct {
   unsigned int age : 3;
} Age;

上面的结构定义指示 C 编译器变量“ Age ”将仅使用 3 位来存储值。如果您尝试使用超过 3 位,它将不允许您这样做。

Example

我们尝试以下示例 −

#include <stdio.h>

struct {
   unsigned int age : 3;
} Age;

int main() {

   Age.age = 4;
   printf("Sizeof(Age): %d\n", sizeof(Age));
   printf("Age.age: %d\n", Age.age);

   Age.age = 7;
   printf("Age.age : %d\n", Age.age);

   Age.age = 8;
   printf("Age.age : %d\n", Age.age);

   return 0;
}

当编译上面的代码时,它将编译出一个带有警告的代码 −

warning: unsigned conversion from 'int' to 'unsigned char:3' changes value from '8' to '0' [-Woverflow]|

并且在执行时,它将产生下面的输出 −

Sizeof(Age): 4
Age.age: 4
Age.age: 7
Age.age: 0

在可用存储有限的情况下,您可以使用位域。当设备传输状态或信息编码为多位时,位域也同样有效。每当某些加密程序需要访问字节内的位时,都会使用位域来定义数据结构。