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