• 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
    ",reg11);         //打印 256
    
             reg11.mode =50;
             printf("reg11=%d
    ",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
    ",reg11);  //打印 256
    
             reg11.en =5;                     //5(b'101) 保留低1位: b'1
             printf("2st:reg11=%d
    ",reg11);  //打印 256
    
             reg11.en =6;                     //5(b'110) 保留低1位: b'0
             printf("3st:reg11=%d
    ",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
    ",sizeof(reg1));
             printf("%d
    ",sizeof(reg2));
             return 0;
    }

    打印:

     

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

    方法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;
              
    
            reg.val=0;
            reg.bit.b = 1;            //bit[4]=1
            printf("val = %d
    ",reg.val);
    
            return 0;
    }

    打印:

     

     方法2-直接定义为unsigned char

    示例:

    struct reg{
             unsigned char a:4;
             unsigned char b:2;
             unsigned char c:1;
    };       //位域总长度只有7位
    
    
    
    int main()
    {      
             printf("%d
    ",sizeof(reg));
             return 0;
    }

    打印:

    6.如果想定义并初始化

    示例:

    typedef struct {
        unsigned OVL     :6;
        unsigned OVOLCN :2;
    }rg11;
    rg11 reg
    = {57,1}; //初始化reg变量 OVL=57 OVOLCN=1
  • 相关阅读:
    Excel对象
    使用C#和Excel进行报表开发(6)
    使用C#和Excel进行报表开发(1)
    c# excel一个小例子
    HDU1226 BFS
    HDU2145 SPFA
    HDU1229
    HDU1535 spfa
    HDU1230
    HDU3986 SPFA
  • 原文地址:https://www.cnblogs.com/lifexy/p/9679963.html
Copyright © 2020-2023  润新知