Cprogramming 简明教程

Bit Fields in C

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

When we declare a struct or a union type, the size of the struct/union type variable depends on the individual size of its elements. Instead of the default memory size, you can set the size the bits to restrict the size. The specified size is called bit fields.

这是用于声明位域的 syntax

This is the syntax you would use to declare a bit field −

struct {
   data_type elem : width;
};

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

Let’s suppose your C program contains a number of TRUE/FALSE variables grouped in a structure called status, as follows −

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

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

This structure requires 8 bytes of memory space but in actual, we are going to store either "0" or "1" in each of the variables. The C programming language offers a better way to utilize the memory space in such situations.

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

If you are using such variables inside a structure, then you can define the width of the variables which tells the C compiler that you are going to use only those many number of bytes. For example, the above structure can be re-written as follows −

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

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

The above structure requires 4 bytes of memory space for the status variable, but only 2 bits will be used to store the values.

Example

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

If you will use up to 32 variables, each one with a width of 1 bit, then also the status structure will use 4 bytes. However, as soon as you have 33 variables, it will allocate the next slot of the memory and it will start using 8 bytes.

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

Let us check the following example to understand the concept −

#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

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

When the above code is compiled and executed, it produces the following Output −

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

Bit Field Declaration

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

The declaration of a bit-field has the following form inside a structure −

struct {
   type [member_name] : width ;
};

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

The following table describes the variable elements of a bit field −

Element

Description

type

An integer type that determines how a bit-field’s value is interpreted. The type may be int, signed int, or unsigned int.

member_name

The name of the bit-field.

width

Number of bits in the bit-field. "width" must be less than or equal to bit width of specified type.

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

The variables defined with a predefined width are called bit fields. A bit field can hold more than a single bit; for example, if you need a variable to store a value from 0 to 7, then you can define a bit field with a width of 3 bits, as follows −

struct {
   unsigned int age : 3;
} Age;

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

The above structure definition instructs the C compiler that the variable "Age" is going to use only 3 bits to store the value. If you try to use more than 3 bits, then it will not allow you to do so.

Example

我们尝试以下示例 −

Let us try the following 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;
}

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

When the above code is compiled, it will compile with a warning −

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

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

And, when executed, it will produce the following output −

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

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

You can use Bit Fields in situations where the available storage is limited. Bit Fields also prove efficient when devices transmit status or information encoded into multiple bits. Whenever certain encryption programs need to access the bits within a byte, bit fields are used to define the data structure.