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 中国大陆许可协议进行许可。

posted @   seekwhale13  阅读(191)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起