聯合體與結構體的區別
- 聯合體(union),與結構體(struct)有極為相似的語法結構,跟struct一樣可以有多種數據類型和成員
- 結構體(struct)中所有變量是“共存”的——優點是“有容乃?”,全?;缺點是struct內存空間的分配是粗放的,不管?不?,全分配。
- 聯合體(union)中是各變量是“互斥”的——缺點就是不夠“包容”; 但優點是內存使?更為精細靈活,也節省了內存空間
union { // 聯合體
int I;
double x;
char str[16];
} myUnion;
struct { // 結構體
int I;
double x;
char str[16];
} myStruct;
位域 bit fields
位域是指信息在存儲時,并不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,并使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位劃分為幾個不同的區域, 并說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個字節的二進制位域來表示。
驗證
- 例如定義一個類,car,為這個car定義四個屬性,前進,后退,左轉,右轉。每一個屬性需要一個int來表示。打印初始化后占用的內存。
@interface LGCar : NSObject
@property (nonatomic,assign) int front;
@property (nonatomic,assign) int back;
@property (nonatomic,assign) int left;
@property (nonatomic,assign) int right;
@end
LGCar *p1 = [LGCar alloc];
NSLog(@"對象類型占用的內存大小:%lu",sizeof(p1));
NSLog(@"對象實際占用的內存大小:%lu",class_getInstanceSize([p1 class]));
NSLog(@"對象實際分配的內存大小:%lu",malloc_size((__bridge const void*)(p1)));
int
一共分配了32字節的內存
@interface LGCar : NSObject
@property (nonatomic,assign) BOOL back;
@property (nonatomic,assign) BOOL left;
@property (nonatomic,assign) BOOL right;
@end
反正也是只是表示是否的屬性,那用BOOL來表示不是可以減少內存這樣下來的,換成BOOL屬性再輸出一下
BOOL
明顯占用字節小了好多,因為每一個屬性都用一個字節表示
- 那還有優化的空間么,我們知道,一個字節是8位。那如果用一位來表示一個屬性呢。這就是聯合體位域,8個屬性就可以在同一個字節里表示了
在這里放一個 struct 和union做比較
struct {
char front;
char back ;
char left ;
char right ;
char front1 ;
char back2 ;
char left3 ;
char right4 ;
}Mystruct;
union {
char bits;
struct {
char front : 1;
char back : 1;
char left : 1;
char right : 1;
char front1 : 1;
char back2 : 1;
char left3 : 1;
char right4 : 1;
};
} Myunion;
//輸入結果
2021-05-09 18:07:08.581506+0800 alloc流程分析[23821:2383485] 結構體占用內存‘8’;,聯合體占用內存‘1’。
由打印看出,聯合體把一個char類型的1 字節8位,每一位都利用起來了。
總結
- 聯合體更加節省內存
位運算
a,b為整數類型
-
& 位與
兩位同時為1,結果才為1,否則結果為0。 -
| 位或
兩位只要有一個為1,其值為1,否則結果為0。 -
~ 取反
~1 = 0 ;~0 = 1; -
<< 左移
各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0 ) -
>> 右移
各二進制位右移若干位,左補0或者左補1得看被移數是正還是負。