[软件资料] 位域

[复制链接]
 楼主| LOVEEVER 发表于 2024-4-7 13:00 | 显示全部楼层 |阅读模式


C语言除了开发桌面应用等,还有一个很重要的领域,那就是「单片机」开发。单片机上的硬件资源十分有限,容不得我们去肆意挥洒。单片机使一种集成电路芯片,使采用超大规模集成电路技术把具有数据处理能力的CPU、RAM、ROM、I/O、中断系统、定时器/计数器等功能(有的还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工控领域使用广泛。

对于这样的设备,通常内存只有256B,那么能够给我们利用的资源就十分珍贵了。在这种情况下,如果我们只需要定义一个变量来存放布尔值,一般就申请一个整型变量,通过1和0来间接存储。但是,显然1和0只用1个bit就能够放完,而一个整型却是4个字节,也就是32bit。这就造成了内存的浪费。

好在,C语言为我们提供了一种数据结构,称为「位域」(也叫位端、位字段)。也就是把一个字节中的二进制位划分,并且你能够指定每个区域的位数。每个域有一个域名,并允许程序中按域名进行单独操作。

使用位域的做法是在结构体定义的时候,在结构体成员后面使用冒号(:)和数字来表示该成员所占的位数。

  1. //Example 08
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5. struct Test
  6. {
  7.   unsigned int a : 1;
  8.   unsigned int b : 1;
  9.   unsigned int c : 2;
  10. } test;

  11. test.a = 0;
  12. test.b = 1;
  13. test.c = 2;

  14. printf("a = %d, b = %d, c = %d\n", test.a, test.b, test.c);
  15. printf("size of test = %d\n", sizeof(test));

  16. return 0;
  17. }

运行结果如下:

  1. //Consequence 08
  2. a = 0, b = 1, c = 2
  3. size of test = 4

如此一来,结构体test只用了4bit,却存放下了0、1、2三个整数。但是由于2在二进制中是10,因此占了2个bit。如果把test.b赋值为2,那么:

  1. //Consequence 08 V2
  2. a = 0, b = 0, c = 2
  3. size of test = 4

可以看到,b中的10溢出了,只剩下0。

当然,位域的宽度不能够超过本身类型的长度,比如:

  1. unsigned int a : 100;

那么就会报错:

错误        C2034        “main::test::a”: 位域类型对位数太小
位域成员也可以没有名称,只要给出类型和宽度即可:

  1. struct Test
  2. {
  3.     unsigned int x : 1;
  4.     unsigned int y : 2;
  5.     unsigned int z : 3;
  6.     unsigned int : 26;
  7. };


无名位域一般用来作为填充或者调整成员的位置,因为没有名称,所以无名位域并不能够拿来使用。

评论

arm compiler v6编译器,好像支持不了位域操作?  发表于 2024-8-23 14:14
szt1993 发表于 2024-4-10 12:25 | 显示全部楼层
每个域有一个域名,并允许程序中按域名进行单独操作。
中国龙芯CDX 发表于 2024-4-10 14:25 | 显示全部楼层
无名位域并不能够拿来使用,只能填充或者调整成员的位置
小夏天的大西瓜 发表于 2024-4-11 13:52 | 显示全部楼层
单片机上的硬件资源十分有限,容不得我们去肆意挥洒,所以节省空间就显得尤为重要
jf101 发表于 2024-4-14 14:46 | 显示全部楼层
使用位域的做法是在结构体定义的时候,在结构体成员后面使用冒号(:)和数字来表示该成员所占的位数
小小蚂蚁举千斤 发表于 2024-4-15 09:55 | 显示全部楼层
把一个字节中的二进制位划分,并且你能够指定每个区域的位数。每个域有一个域名,并允许程序中按域名进行单独操作。
OKAKAKO 发表于 2024-4-19 18:46 | 显示全部楼层
每个域有一个域名,并允许程序中按域名进行单独操作。
星辰大海不退缩 发表于 2024-4-21 12:20 | 显示全部楼层
C语言在「单片机」开发上应用还是比较多的。
AdaMaYun 发表于 2024-9-7 15:57 | 显示全部楼层
位域的宽度不能够超过本身类型的长度
您需要登录后才可以回帖 登录 | 注册

本版积分规则

342

主题

2619

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部