经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C- unsigned :1之位域分析
来源:cnblogs  作者:LifeYx  时间:2018/9/25 20:33:11  对本文有异议

1.首先回忆结构体

我们都知道定义一个结构体可以这样的方式定义:

  1. struct Point {
  2. float x;
  3. float y;
  4. } point; //等价于: struct Point point;

除此之外,如果不想声明结构体,只想定义结构体的话,还可以这样:

  1. struct {
  2. float x;
  3. float y;
  4. } point; //等价于: struct Point point;

 

2.位域之简单应用

做低层时,经常会读写寄存器,比如操作某位,设置为0或1,而在C语言中便为我们提供一种数据结构”位域”,使得我们通过读写”位域”来实现操作某位.

例如一个常见的位域的结构体,操作如下所示:

  1. #include <stdio.h>
  2.  
  3. struct {
  4. unsigned mode:8; //bit[0,7]:模式选择
  5. unsigned en:1; //bit[8] :使能选择
  6. unsigned reserved:1; //bit[9] :保留reserved (也可以写成unsigned reserved:1;)
  7. unsigned clk_select:4; //bit[10,13]:时钟选择
  8. unsigned ch_select:3; //bit[14,15]:通道选择
  9. }reg11; //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性
  10.  
  11. int main()
  12. {
  13. reg11.en =1; //bit8=1 --> 256
  14. printf("reg11=%d\n",reg11); //打印 256
  15. reg11.mode =50;
  16. printf("reg11=%d\n",reg11); //打印 256+50
  17. return 0;
  18. }

打印:

 

 

 

3.位域之越界处理

比如,我们定义的某个位域只有固定1位,如果向该位写入超过1位的值.会自动保留最低1位.

示例:

  1. #include <stdio.h>
  2. struct {
  3. unsigned mode:8; //bit[0,7]:模式选择
  4. unsigned en:1; //bit[8] :使能选择
  5. unsigned reserved:1; //bit[9] :保留reserved(也可以写成unsigned reserved:1;)
  6. unsigned clk_select:4; //bit[10,13]:时钟选择
  7. unsigned ch_select:3; //bit[14,15]:通道选择
  8. }reg11; //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性
  9.  
  10. int main()
  11. {
  12. reg11.en =1; //bit8=1 --> 256
  13. printf("1st:reg11=%d\n",reg11); //打印 256
  14. reg11.en =5; //5(b'101) 保留低1位: b'1
  15. printf("2st:reg11=%d\n",reg11); //打印 256
  16. reg11.en =6; //5(b'110) 保留低1位: b'0
  17. printf("3st:reg11=%d\n",reg11); //打印 0
  18.  
  19. return 0;
  20. }

打印:

 

  

4.注意, 使用位域的结构体的长度默认最小值为int型(4字节),如果超过4字节(32位),则会是64

示例:

  1. #include <stdio.h>
  2.  
  3. struct {
  4. unsigned a:4;
  5. unsigned b:2;
  6. unsigned c:1;
  7. }reg1;        //位域总长度只有7位
  8. struct reg{
  9. unsigned a:4;
  10. unsigned b:2;
  11. unsigned c:32;
  12. }reg2;
  13. int main()
  14. {
  15. printf("%d\n",sizeof(reg1));
  16. printf("%d\n",sizeof(reg2));
  17. return 0;
  18. }

打印:

 

 

5.如果某个寄存器只有8位(1字节),该如何使用位域处理?

使用union联合体,使各字段共享一块内存,通过读写union结构体里的char变量即可.

示例:

  1. #include <stdio.h>
  2. typedef union{
  3. unsigned char val;
  4. struct {
  5. unsigned a:4;
  6. unsigned b:1;
  7. unsigned c:2;
  8. unsigned d:1;
  9. }bit;
  10. }reg11; //使用typedef ,告诉编译器,reg11是个声明类型
  11.  
  12. int main()
  13. {
  14. reg11 reg;
  15. printf("sizeof=%d\n",sizeof(reg.val));
  16. reg.val=0;
  17. reg.bit.b = 1; //bit[4]=1
  18. printf("val = %d\n",reg.val);
  19. return 0;
  20. }

打印:

 

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号