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字節),該如何使用位域處理?

方法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\n",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\n",sizeof(reg));
         return 0;
}

打印:

 

6.如果想定義並初始化

示例:

typedef struct {
    unsigned OVL     :6;
    unsigned OVOLCN :2;
}rg11;
rg11 reg
= {57,1}; //初始化reg變量 OVL=57 OVOLCN=1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM