java c语言union转换_C语言联合体(union)的使用方法及其本质-union
轉(zhuǎn)載自:https://blog.csdn.net/sizhouqun_84342712/article/details/53187106
1.聯(lián)合體union的基本特性——和struct的同與不同
union,中文名“聯(lián)合體、共用體”,在某種程度上類似結(jié)構(gòu)體struct的一種數(shù)據(jù)結(jié)構(gòu),共用體(union)和結(jié)構(gòu)體(struct)同樣可以包含很多種數(shù)據(jù)類型和變量。不過區(qū)別也挺明顯:結(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)存空間。
2.雙刃劍——多種訪問內(nèi)存途徑共存
//example
#include
union var{
long int l;
int i;
};
main(){
union var v;
v.l = 5;
printf("v.l is %d\n",v.i);
v.i = 6;
printf("now v.l is %ld! the address is %p\n",v.l,&v.l);
printf("now v.i is %d! the address is %p\n",v.i,&v.i);
}
結(jié)果:
v.l is 5
now v.l is 6! the address is 0xbfad1e2c
now v.i is 6! the address is 0xbfad1e2c
3.聯(lián)合體union和大小端(big-endian、little-endian)
#include
union var{
char c[4];
int i;
};
int main(){
union var data;
data.c[0] = 0x04;//因?yàn)槭莄har類型,數(shù)字不要太大,算算ascii的范圍~
data.c[1] = 0x03;//寫成16進(jìn)制為了方便直接打印內(nèi)存中的值對比
data.c[2] = 0x02;
data.c[3] = 0x11;
//數(shù)組中下標(biāo)低的,地址也低,按地址從低到高,內(nèi)存內(nèi)容依次為:04,03,02,11。總共四字節(jié)!
//而把四個字節(jié)作為一個整體(不分類型,直接打印十六進(jìn)制),應(yīng)該從內(nèi)存高地址到低地址看,0x11020304,低位04放在低地址上。
printf("%x\n",data.i);
}
結(jié)果:
11020304
證明我的32位linux是小端(little-endian)
4.聯(lián)合體union所占內(nèi)存空間大小
#include
union sizeTest{
int a;
double b;
};
main(){
union sizeTest unionA;
union sizeTest unionB;
union sizeTest unionC;
printf("the initial address of unionA is %p\n",&unionA);
printf("the initial address of unionB is %p\n",&unionB);
printf("the initial address of unionC is %p\n",&unionC);
}
打印,可以看到結(jié)果:
the initial address of unionA is 0xbf9b8df8
the initial address of unionB is 0xbf9b8e00
the initial address of unionC is 0xbf9b8e08
很容易看出,8,0,8,這間隔是8字節(jié),按double走的。
怕不保險,再改一下,把int改成數(shù)組,其他不變:
union sizeTest{
int a[10];
double b;
};
打印
the initial address of unionA is 0xbfbb7738
the initial address of unionB is 0xbfbb7760
the initial address of unionC is 0xbfbb7788
88-60=28
60-38=28
算錯了?我說的可是16進(jìn)制0x。那么0x28就是40個字節(jié),正好是數(shù)組a的大小。
似乎忘了一個功能——sizeof() ??用sizeof直接看,就知道union的大小了
printf("the sizeof of unionA is %d\n",sizeof(unionA));
printf("the sizeof of unionB is %d\n",sizeof(unionB));
printf("the sizeof of unionC is %d\n",sizeof(unionC));
printf("the sizeof of union is %d\n",sizeof(union sizeTest));
5.聯(lián)合體union適用場合
有了前邊那個驗(yàn)證,基本可以確認(rèn),union的內(nèi)存是照著里邊占地兒最大的那個變量分的。
也就可以大膽的推測一下,這種union的使用場合,是各數(shù)據(jù)類型各變量占用空間差不多并且對各變量同時使用要求不高的場合(單從內(nèi)存使用上,我覺得沒錯)。
像上邊做的第二個測試,一個數(shù)組(或者更大的數(shù)組int a[100]),和一個或者幾個小變量寫在一個union里,實(shí)在沒什么必要,節(jié)省的空間太有限了,還增加了一些風(fēng)險(最少有前邊提到的邏輯上的風(fēng)險)。所以,從內(nèi)存占用分析,這種情況不如直接struct。
不過話說回來,某些情況下雖然不是很節(jié)約內(nèi)存空間,但是union的復(fù)用性優(yōu)勢依然存在啊,比如方便多命名,這種“二義性”,從某些方面也可能是優(yōu)勢。這種方法還有個好處,就是某些寄存器或通道大小有限制的情況下,可以分多次搬運(yùn)。
6.本質(zhì)&進(jìn)階
沒錯,union的成員變量是相當(dāng)于開辟了幾個接口(即union包含的變量)!但是,沒開辟就不能用了?當(dāng)然也能用!??寫個小測試:
#include
union u{
int i;
double d;//這個union有8字節(jié)大小
};
main(){
union u uu;
uu.i = 10;
printf("%d\n",uu.i);
char * c;
c = (char *)&uu;//把union的首地址賦值、強(qiáng)轉(zhuǎn)成char類型
c[0] = 'a';
c[1] = 'b';
c[2] = 'c';
c[3] = '\0';
c[4] = 'd';
c[5] = 'e';
//最多能到c[7]
printf("%s\n",c);//利用結(jié)束符'\0'打印字符串"abc"
printf("%c %c %c %c %c %c\n",c[0],c[1],c[2],c[3],c[4],c[5]);
}
總結(jié)
以上是生活随笔為你收集整理的java c语言union转换_C语言联合体(union)的使用方法及其本质-union的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 求交集 算法_Java计算交集
- 下一篇: java 默认焦点_按钮活动焦点阴影默认