在 C 語(yǔ)言中,有一種叫做union
的變量,是用來(lái)在不同的情況下,存放不同類型和大小的對(duì)象的變量。這與結(jié)構(gòu)體struct
很相似:結(jié)構(gòu)體是一個(gè)或多個(gè)變量的集合。
union 的聲明方式非常簡(jiǎn)單,也與struct
一模一樣,如下:
union u_tag {
int ival;
char *sval;
} u;
可以看到,唯一的不同就是結(jié)構(gòu)體中的struct
變成了union
。
使用方法也一模一樣:
//一般變量
union_name.val
//指針
union_pointer->val
二者這么像,那么二者的區(qū)別在哪里呢?或者說(shuō),為什么要弄兩個(gè)這么像的東西呢?C 又不是 C++,一些功能是由不同的小組開(kāi)發(fā)的,一些功能上會(huì)重疊。
首先是表面的不同,struct
和union
在使用目的上完全不一樣,union
并不像struct
會(huì)同時(shí)存放大括號(hào)中列出的每個(gè)變量,如果你嘗試下面的代碼
union u_tag {
int a;
int b;
} u;
int main()
{
u.a=1;
u.b=2;
printf("u_tag: %d\n", u.a);
return 0;
}
那么輸出的結(jié)果為:
u_tag: 2
這里的結(jié)果不是出錯(cuò)了,是因?yàn)?code>union并不會(huì)像結(jié)構(gòu)體一樣,去根據(jù)前面的u.a=1
輸出1
,由于只能存放一種數(shù)據(jù),所以后面的u.b=2
覆蓋了原本u
存放的值。
所以說(shuō),union
內(nèi)部聲明的變量可以理解成是一種可能,而不是實(shí)際的對(duì)象或成員變量。
并且由于union
內(nèi)部只有一個(gè)值,所以一般不會(huì)使用相同的數(shù)據(jù)類型。至于目前包含什么數(shù)據(jù)類型,這是編程的時(shí)候需要程序員注意的。一般是用一個(gè)變量u_type
,然后再用判斷語(yǔ)句來(lái)判斷當(dāng)前包含的類型。
但是struct
和union
最核心的不同,也是union
誕生的理由是:分配空間的機(jī)制。
如果你用sizeof()
測(cè)量下面兩個(gè)數(shù)據(jù)的尺寸
union u_tag {
int ival;
float fval;
char *sval;
} u;
struct s_tag {
int ival;
float fval;
char *sval;
} s;
會(huì)發(fā)現(xiàn),u_tag
的尺寸是 8 個(gè)字節(jié),但是s_tag
的尺寸是 16 個(gè)字節(jié) 。這是因?yàn)?code>union相當(dāng)于給內(nèi)部聲明的數(shù)據(jù)類型留了一個(gè)最大空間,而struct
是給每個(gè)數(shù)據(jù)類型都留了各自的空間。
在現(xiàn)在的絕大部分機(jī)器上,int
類型為 4 字節(jié),float
類型為 4 字節(jié),cahr *
類型為 8 個(gè)字節(jié)。所以u
就占據(jù)了最大空間,也就是 8 個(gè)字節(jié),而s
則每個(gè)都留了各自的空間,也就是 4+4+8=16 字節(jié)。
那么需要在什么時(shí)候使用union
呢?
首先根據(jù)其存放一種數(shù)據(jù)的特點(diǎn),可以用來(lái)做一些通用計(jì)算,比如說(shuō)浮點(diǎn)數(shù)和整數(shù)的切換等。
其次上面的使用目的下,節(jié)省空間了。雖然這種情況下也可以使用結(jié)構(gòu)體,但是上面三種數(shù)據(jù)類型就差一倍大小的情況算好的。因?yàn)閮?nèi)存地址分配機(jī)制,一些類型的數(shù)據(jù)的地址是由特殊要求的,比如說(shuō)在一些機(jī)器上,int
需要在偶數(shù)位的地址。
下面就是一個(gè)例子,但是整數(shù)的地址限制并不是在偶數(shù),而是 4 的倍數(shù)。
struct s_tag {
int ival;
char a;
} s;
這個(gè)結(jié)構(gòu)體的大小為 8 個(gè)字節(jié),你可以自己試試看是不是這個(gè)大小。
并且由于編譯器是順序讀取的,所以如果你寫成下面這樣
struct s_tag {
int a;
char b;
int c;
char d;
} s;
那么這個(gè)結(jié)構(gòu)體的大小為 16 字節(jié)。這種情況下可以將同一類的數(shù)據(jù)寫在一起,可以節(jié)約一些空間,如下:
struct s_tag {
int a;
int c;
char b;
char d;
} s;
這樣這個(gè)結(jié)構(gòu)體所占用的空間大小就為 12 字節(jié)了。而如果使用union
,那么無(wú)論什么順序,大小一直為 4 字節(jié)。隨著數(shù)據(jù)類型的可能性越來(lái)越多,節(jié)約空間的必要性就凸顯出來(lái)了。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-438762.html
希望能幫到有需要的人~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-438762.html
到了這里,關(guān)于C——Union是什么?Union和Struct這么像,區(qū)別在哪?為什么還要?jiǎng)?chuàng)造出union呢?需要在哪里使用呢?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!