C- unsigned :1之位域分析

1.首先回忆结构体

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

struct Point {
    float x;
    float y;
} point;                      //等价于: struct  Point  point;

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

struct  {
    float x;
    float y;
} point;                      //等价于:  struct  Point  point;

2.位域之简单应用

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

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

#include <stdio.h>

struct {                                                  
         unsigned mode:8;          //bit[0,7]:模式选择
         unsigned en:1;            //bit[8]   :使能选择
         unsigned reserved:1;      //bit[9]    :保留reserved  (也可以写成unsigned reserved:1;)
         unsigned clk_select:4;    //bit[10,13]:时钟选择
         unsigned ch_select:3;     //bit[14,15]:通道选择
}reg11;            //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性

int main()
{      
         reg11.en =1;                     //bit8=1 --> 256
         printf("reg11=%d\n",reg11);         //打印 256

         reg11.mode =50;
         printf("reg11=%d\n",reg11);         //打印 256+50
         return 0;
}

打印:

3.位域之越界处理

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

示例:

#include <stdio.h>
struct {                                                  
         unsigned mode:8;          //bit[0,7]:模式选择
         unsigned en:1;            //bit[8]   :使能选择
         unsigned reserved:1;      //bit[9]    :保留reserved(也可以写成unsigned reserved:1;)
         unsigned clk_select:4;    //bit[10,13]:时钟选择
         unsigned ch_select:3;     //bit[14,15]:通道选择
}reg11;     //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性

int main()
{     
         reg11.en =1;                     //bit8=1 --> 256
         printf("1st:reg11=%d\n",reg11);  //打印 256

         reg11.en =5;                     //5(b'101) 保留低1位: b'1
         printf("2st:reg11=%d\n",reg11);  //打印 256

         reg11.en =6;                     //5(b'110) 保留低1位: b'0
         printf("3st:reg11=%d\n",reg11);  //打印 0

         return 0;
}

打印:

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

示例:

#include <stdio.h>

struct {
         unsigned a:4;
         unsigned b:2;
         unsigned c:1;
}reg1;        //位域总长度只有7位

struct reg{
         unsigned a:4;
         unsigned b:2;
         unsigned c:32;
}reg2;

int main()
{      
         printf("%d\n",sizeof(reg1));
         printf("%d\n",sizeof(reg2));
         return 0;
}

打印:

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

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

示例:

#include <stdio.h>

typedef union{
unsigned char val;

struct {                                                  
         unsigned a:4; 
         unsigned b:1; 
         unsigned c:2;
         unsigned d:1;
       }bit;       

}reg11;             //使用typedef ,告诉编译器,reg11是个声明类型

int main()
{      
        reg11 reg;
        printf("sizeof=%d\n",sizeof(reg.val));

        reg.val=0;
        reg.bit.b = 1;            //bit[4]=1
        printf("val = %d\n",reg.val);

        return 0;
}

打印:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java一日一条

50个常见的 Java 错误及避免方法(第一部分)

在开发Java软件时可能会遇到许多类型的错误,但大多数是可以避免的。为此我们罗列了50个最常见的Java编码错误,其中包含代码示例和教程,以帮助大家解决常见的编...

1233
来自专栏杨建荣的学习笔记

关于正则表达式第一篇(r3笔记第29天)

正则表达式在编程语言中,数据库中,linux中都有着广泛的应用,一说起正则表达式就有些高深晦涩的味道,正则表达式精炼而重要,在Linux中有着举足轻重的作用,也...

3234
来自专栏JavaQ

99%的高级程序员都这样使用null

如果使用某个对象或对象里属性前先判断是否为null,那就需要思考一下你的代码是否已经烂掉了。 null是什么意思,你能说清楚它的意图吗?方法返回了null,是出...

3456
来自专栏爱撒谎的男孩

Springmvc之接受请求参数

3526
来自专栏博岩Java大讲堂

Java虚拟机--你的对象有多大如何计算对象大小

4515
来自专栏云霄雨霁

SpringMVC--参数绑定笔记

2200
来自专栏程序员宝库

这些 Java 面试题必须会---鲁迅

写在前面 春天来了,万物复苏的季节到了. 许多程序猿安奈不住生理需求,我要涨工资,我要跳槽. 毕竟金三银四嘛. 那么要从众多的面试者中获得求职机会,我们就要面对...

30910
来自专栏Java后端技术栈

如何在你的项目中使用JSR 303 - Bean Validation进行数值校验?

JSR-303 是 Java EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是hibernate Validator。

2114
来自专栏aCloudDeveloper

string 之 strrev函数

Author: bakari  Date: 2012/8/9 继上篇。。。。。 下面是我写的代码与源码作的一些比较,均已严格测试通过,分别以“string 之”...

1939
来自专栏PHP实战技术

PHP垃圾回收机制

1、每一个变量定义时都保存在一个叫zval的容器里面,这里面包含了数量的类型和和值,还包含了一个refcount(理解为存在几个变量个数)和is_ref(理解为...

45210

扫码关注云+社区

领取腾讯云代金券