位域


#include <stdio.h>
#include <stdlib.h>
//位字段:嵌入式的物聯網設備開發,需要節約內存,可以使用位字段,用來限定某個結構如變量的二進制位
struct dateE{
    unsigned int day;  // day只有1-31的取值,無需用到4個字節,浪費了內存  2^5=32  5個二進制位就足夠了
    unsigned int month; // month只有1-12的取值,無需用到4個字節,浪費了內存  2^4=32  4個二進制位就足夠了
    unsigned int year;  // 只有0000-9999 的取值,無需用到4個字節,浪費了內存  2^14=16384  14個二進制位就足夠了
};

struct date{   //相比上面的定義,date結構體只有4個字節,大大節約了內存空間
    unsigned int day : 5;  // day只有1-31的取值,無需用到4個字節,浪費了內存  2^5=32  5個二進制位就足夠了
    unsigned int month : 4; // month只有1-12的取值,無需用到4個字節,浪費了內存  2^4=32  4個二進制位就足夠了
    unsigned int year :14;  // 只有0000-9999 的取值,無需用到4個字節,浪費了內存  2^14=16384  14個二進制位就足夠了
};
//為什么是4個字節呢?因為考慮到內存字節對齊的問題
// 占用5位  1111 1 000     1個字節,不足補0
// 占用4位  1111 0000      1個字節,不足補0
// 占用14位 1111 1111 | 1111 11 00 |  兩個字節合並到一起,2個字節,不足補0
// 在結構體中:CPU是按照字節尋址的,字節是CPU訪問的最小單位,總共4個字節
//在限定位數的結構體——位域中,CPU是按位運算尋址的,不是按字節
void main1(){
    printf("%d\n", sizeof(struct dateE));  //12
    printf("%d\n", sizeof(struct date));  //4  結構體對齊
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//位字段的注意事項
//如果兩個字符之和小於8位,會自動填充一個字節,通位操作操作位字段
//1(1位) 11111(5位) 00 1代表其占用的位,一個字節存儲兩個位域變量ch1,ch2
//int占用4個字節,雖然只有一位使用,后面的會默認為0,且無法使用這些0
//結構體前面的char類型為了和int字節對齊,后面補0,也對應四個字節,總共8個字節
//1 11111 00     00000000    00000000    00000000   4個字節
//1 00000000    00000000    00000000    00000000    4個字節
struct data{
    unsigned char ch1 : 1;  //結構體限定了位數,越界會溢出
    unsigned char ch2 : 2;
   // unsigned char ch3 : 10; 位字段不能超過類型的大小8個位
   // unsigned char ch4 : 0; 位字段不能為0
    int num : 1;

};
void main(){
    printf("%d\n", sizeof(struct data)); //8個字節
    struct data data1;
    data1.ch1 =2;
    data1.num =2;
    printf("%d\n",data1.ch1);  //0  2的二進制位10,而ch1只能處理以為,溢出,輸出0
    printf("%d\n",data1.num);  //0 雖然num占用4個字節,但是后面的0無法利用, 2的二進制位10,而ch1只能處理以為,溢出,輸出0


    //取地址
    printf("%p\n",data1); //可以去結構體的地址
    printf("%p\n",data1.ch1); //錯誤,不可以取位域的地址
    //位域是通過位運算來實現,無法取出位域的地址(一個字節存儲兩個位域變量ch1,ch2)

}

 


免責聲明!

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



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