C语言-位域操作
我们在使用单片机时经常会用到某些某些变量来表示某些状态,例如Led_Flag的1或0表示开与关,我们可以定义一个结构体来进行操作:
struct LEDS{ uchar Led_Green; uchar Led_Red; uchar Led_Blue; }leds;
当我们需要控制LED灯开关状态时,只需要:
leds->LED_Green=0/1;
这种方法是可行的,但在大部分时候,某个变量只有两个状态,或者三个等,这样定义了一个八位的变量却只用到了其中的两位,浪费了很多资源,特别对于大部分片上资源紧缺单片机来说,这是需要避免的。因此,除了结构体,C语言还提供了另一种定义方式--位域,位域的定义方式与结构体类似,例子如下:
struct BITTYPE{ uchar bit0:1; uchar bit1:1; uchar bit2:1; uchar bit3:1; uchar bit4:1; uchar bit5:1; uchar bit6:1; uchar bit7:1; }bittype;
位域与结构体很像,主要形式:
struct 位域结构名 { 位域列表 };
其中位域列表结构位:
type [member_name] : width ;
各名称定义为:
元素 | 描述 |
---|---|
type | 只能为 int(整型),unsigned int(无符号整型),signed int(有符号整型) 三种类型,决定了如何解释位域的值。 |
member_name | 位域的名称。 |
width | 位域中位的数量。宽度必须小于或等于指定类型的位宽度。 |
对于位域还有一些需要注意的点:
- 一个位域存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct bs{ unsigned a:4; unsigned :4; /* 空域 */ unsigned b:4; /* 从下一单元开始存放 */ unsigned c:4 }
在这个位域定义中,a 占第一字节的 4 位,后 4 位填 0 表示不使用,b 从第二字节开始,占用 4 位,c 占用 4 位。
-
位域的宽度不能超过它所依附的数据类型的长度,成员变量都是有类型的,这个类型限制了成员变量的最大长度,: 后面的数字不能超过这个长度。
-
位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k{ int a:1; int :2; /* 该 2 位不能使用 */ int b:3; int c:2; };
位域的使用与结构体一致
位域变量名.位域名 位域变量名->位域名
实例
#include <stdio.h> int main(){ struct bs{ unsigned a:1; unsigned b:3; unsigned c:4; } bit,*pbit; bit.a=1; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */ bit.b=7; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */ bit.c=15; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */ printf("%d,%d,%d\n",bit.a,bit.b,bit.c); /* 以整型量格式输出三个域的内容 */ pbit=&bit; /* 把位域变量 bit 的地址送给指针变量 pbit */ pbit->a=0; /* 用指针方式给位域 a 重新赋值,赋为 0 */ pbit->b&=3; /* 使用了复合的位运算符 "&=",相当于:pbit->b=pbit->b&3,位域 b 中原有值为 7,与 3 作按位与运算的结果为 3(111&011=011,十进制值为 3) */ pbit->c|=1; /* 使用了复合位运算符"|=",相当于:pbit->c=pbit->c|1,其结果为 15 */ printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c); /* 用指针方式输出了这三个域的值 */ }
本文作者:seekwhale13
本文链接:https://www.cnblogs.com/seekwhale13/p/17167586.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步