C語言結構體中冒號(位域)用法
位域出現的原因是由於某些資訊的儲存表示只需要幾個bit位就可以表示而不需要一個完整的位元組,同時也是為了節省儲存空間和方便處理。
typedef struct bit_struct
{
int bit1:3;
int bit2:5;
int bit3:7;
}data;
bit1、bit2、bit3表示對應的位域
整個位域結構體佔用2個位元組
bit1佔3位,bit2佔5位,bit1和bit2共用一個位元組
bit3佔7位,獨佔一個位元組。
說明:
1、位域必須儲存在同一個型別中,不能跨型別,同時也說明位域的長度不會超過所定義型別的長度。如果一個定義型別單元裡所剩空間無法存放下一個域,則下一個域應該從下一單元開始存放。例如:所定義的型別是int型別,一共32為,目前用掉了25位還剩下7位,這時要儲存一個8位的位域元素,那麼這個元素就只能從下一個int型別的單元開始而不會在前面一個int型別中佔7為後面的int型別中佔1位。
2、如果位域的位域長度為0表示是個空域,同時下一個域應當從下一個位元組單元開始存放。
3、使用無名的位域來作為填充和調整位置,切記該位域是不能被使用的。
4、位域的本質上就是一種結構體型別,不同的是其成員是按二進位制位來分配的。
好,說到這裡可能理解起來有點抽象,那下面通過一個例子來說明說有問題吧(注意:int是分正負的)!
1 /***********************************************************
2 * Function : 驗證位域
3 *
4 * Result : a = 1, b = -2, c = 3, d = -2, e = -4
5 * a = 3, b = 0, c = 7, d = -1, e = -3
6 *
7 * Result Analysis : 之所以出現負數的原因是由於int型預設是有符號型的,所以兩位的位域賦值2時就會溢位,
8 * 成為10,高位是表示符號,1表示負號。10取反加1之後就是10,也就是2,所以值是-2
9 *
10 * Create Data : 2015-12-16
11 *
12 * Author : ***
13 *
14 * Others :
15 *
16 * Modified Data :
17 *
18 * Modifier :
19 *
20 * Modify Reason :
21 *
22 * *******************************************************/
23 #include <stdio.h>
24
25 #define SYS_OK 0
26 #define SYS_FAILED 1
27 typedef int SYS_TYPE;
28
29 SYS_TYPE main()
30 {
31 struct bit_st
32 {
33 int a:3; //第一個位元組的0~2位
34 int :0; //這裡是說明的第二點,空域。下一個位域b將會從下一個位元組開始,位3~7為全0。
35 int b:2; //下一個位元組也就是第二個位元組的0~1位
36 int c:5; //第二個位元組緊接b之後的2~6位
37 int d:2; //這裡是說明的第一點,d佔用第三個位元組的0~1位,因為前面一個位元組只剩下一位不能存放d,所以另起一個位元組存放。
38 int :2; //這裡說明的是第三點,d域後的兩個位2~3不能使用。
39 int e:3; //存放在第三個位元組的第4~6位
40 }data, *pData;
41
42 data.a = 1;
43 data.b = 2; //注意此處b只佔2位,所以取值範圍為-2~1,超過-2或者1就出現錯誤,所以賦值時注意位域的範圍
44 data.c = 3;
45 data.d = 2;
46 data.e = 4;
47 printf("a = %d, b = %d, c = %d, d = %d, e = %d\r\n",
48 data.a, data.b, data.c, data.d, data.e); //結構體操作
49
50 pData = &data;
51 pData->a = 3;
52 pData->b &= 1;
53 pData->c |= 5;
54 pData->d ^= 1;
55 pData->e = 5;
56 printf("a = %d, b = %d, c = %d, d = %d, e = %d\r\n",
57 pData->a, pData->b, pData->c, pData->d, pData->e); //結構體指標操作
58
59 return SYS_OK;
60 }
第一次賦值之後存放的形式如下:
第二次賦值運算之後存放的形式如下: