#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) }