6bingame 发表于 2024-12-25 15:31:31

每日一学26

位域

C语言可以在一个结构体中以二进制位为单位来指定其成员所占用内存长度,这种以位单位的成员就称为位域(bit field)。如何以位作为单位来访问数据呢?这样可以更高效的使用存储空间,方法就是使用位域,这样就可以在一个字节中分别存放多个信息。


struct data   //定义结构体
{
    unsigned n1:6;//n1占6个位
    unsigned n2:4;//n2占4个位
    unsigned n3:4;//n3占4个位
    unsigned n4:2;//n4占2个位
}mydata;

在使用位域时,需要注意以下情况

(1)一个位域必须存储在同一个存储单元中,不能跨两个单元。我们可以闲置没有使用的存储单元,但是对那种一个剩余存储单元放不下的,就要从下一个单元开始存放。而且定义的每一个位域长度不能超过存储单元。

(2)位域名默认时称作无名位域。例如:

struct date   //定义结构体
{
    unsigned a:2;   //a占2个位
    unsigned:2;   //空2个位
    unsigned b:1;   //b占1个位
}mydate;

第2次申请的2个空间的位域是闲置不用的,因为没有位域名称。

需要注意的是,同样是无名的位域,它的存储空间是0,有特殊的含义,它指的是这个字节剩余的部分不再使用,从下个新字节开始存储。
例如:

struct date   //定义结构体
{
    unsigned a:2;   //a占2个位
    unsigned:0    //从下一个新字节开始存储
    unsigned b:1;   //b占1个位
}mydate;

(3)一个结构体中既可以定义位域成员,也可以同时定义一般的结构体成员。例如:

struct date   //定义结构体
{
    unsigned a:2;   //a占2个位
    unsigned:0;   //从下一个新字节开始存储
    unsigned b:1;   //b占1个位
}mydate;

(4)不能定义以位域结构为元素的数组。位域的引用与结构体相同。例如:

mydata.a=2;   //赋值
mydata.b=1;   //赋值

需要注意的是,a只占两位,我们在上面的结构体中有声明,也就是说,a最大存储的二进制数是11,转换为十进制就是3,如果写成mydata.a=10,这并不错,但是结果就不是期望的10了,变成了2,因为10的二进制码是1010,只截取右边两位10,故结果是2。

(5)位域也可以参与算术表达式的运算,这时系统会自动将其转换为整型数。位域可以用整型格式符输出。例如:

printf("%d\n",mydata.a);    //a以有符号整数形式输出
printf("%u\n",mydata.a);    //a以无符号整数形式输出


FishC 发表于 2024-12-25 15:38:29


每日一学26
位域

C语言可以在一个结构体中以二进制位为单位来指定其成员所占用内存长度,这种以位单位的成员就称为位域(bit field)。如何以位作为单位来访问数据呢?这样可以更高效的使用存储空间,方法就是使用位域,这样就可以在一个字节中分别存放多个信息。


struct data   //定义结构体
{
    unsigned n1:6;// n1 占 6 个位
    unsigned n2:4;// n2 占 4 个位
    unsigned n3:4;// n3 占 4 个位
    unsigned n4:2;// n4 占 2 个位
} mydata;


在使用位域时,需要注意以下情况:

(1)一个位域必须存储在同一个存储单元中,不能跨两个单元。我们可以闲置没有使用的存储单元,但是当剩余存储单元放不下时,就要从下一个单元开始存放。而且定义的每一个位域长度不能超过存储单元。

(2)位域名为无名位域时,空间会被闲置。例如:

struct date   //定义结构体
{
    unsigned a:2;   // a 占 2 个位
    unsigned:2;   // 空 2 个位
    unsigned b:1;   // b 占 1 个位
} mydate;

第 2 次申请的 2 个空间的位域是闲置不用的,因为没有位域名称。

需要注意的是,无名位域长度为 0 时,它指的是这个字节剩余的部分不再使用,从下个新字节开始存储。例如:

struct date   //定义结构体
{
    unsigned a:2;   // a 占 2 个位
    unsigned:0;   // 从下一个新字节开始存储
    unsigned b:1;   // b 占 1 个位
} mydate;


(3)一个结构体中既可以定义位域成员,也可以同时定义一般的结构体成员。例如:

struct date   //定义结构体
{
    unsigned a:2;   // a 占 2 个位
    unsigned:0;   // 从下一个新字节开始存储
    unsigned b:1;   // b 占 1 个位
} mydate;


(4)不能定义以位域结构为元素的数组。位域的引用与结构体相同。例如:

mydata.a=2;   // 赋值
mydata.b=1;   // 赋值

需要注意的是,a 只占两位,我们在上面的结构体中有声明,也就是说,a 最大存储的二进制数是 11,转换为十进制就是 3。如果赋值如 mydata.a=10,这并不会报错,但结果就不是期望的 10 了,而是 2,因为 10 的二进制码是 1010,只截取右边两位 10,故结果是 2。

(5)位域也可以参与算术表达式的运算,这时系统会自动将其转换为整型数。位域可以用整型格式符输出。例如:

printf("%d\n",mydata.a);    // a 以有符号整数形式输出
printf("%u\n",mydata.a);    // a 以无符号整数形式输出



以上就是关于C语言位域的基本介绍及用法示例。希望对你有帮助!如果有其他问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 每日一学26