日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

联合体的用法与特点

發布時間:2025/1/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 联合体的用法与特点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.聯合體union的基本特性——和struct的同與不同

union,中文名“聯合體、共用體”,在某種程度上類似結構體struct的一種數據結構,共用體(union)和結構體(struct)同樣可以包含很多種數據類型和變量。

不過區別也挺明顯:

結構體(struct)中所有變量是“共存”的——優點是“有容乃大”,全面;缺點是struct內存空間的分配是粗放的,不管用不用,全分配。

而聯合體(union)中是各變量是“互斥”的——缺點就是不夠“包容”;但優點是內存使用更為精細靈活,也節省了內存空間。

?

?

2.雙刃劍——多種訪問內存途徑共存

一個例子了然:

?

  • //example??
  • #include<stdio.h>??
  • 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);??
  • }??
  • 結果:??
  • v.l?is?5??
  • now?v.l?is?6!?the?address?is?0xbfad1e2c??
  • now?v.i?is?6!?the?address?is?0xbfad1e2c??
  • ?

    所以說,管union的叫共用體還真是貼切——完全就是共用一個內存首地址,并且各種變量名都可以同時使用,操作也是共同生效。如此多的access內存手段,確實好用,不過這些“手段”之間卻沒法互相屏蔽——就好像數組+下標和指針+偏移一樣。

    上例中我改了v.i的值,結果v.l也能讀取,那么也許我還以為v.l是我想要的值呢,因為上邊提到了union的內存首地址肯定是相同的,那么還有一種情況和上邊類似:

    一個int數組變量a,一個long int(32位機中,long int占4字節,與int相同)變量b,我即使沒給int變量b賦值,因為數據類型相同,我使用int變量b也完全會拿出int數組a中的a[0]來,一些時候一不小心用上,還以為用的就是變量b呢~

    這種邏輯上的錯誤是很難找出來的(只有當數據類型相去甚遠的時候稍好,出個亂碼什么的很容易發現錯誤)。

    ?

    PS:感謝熱心網友的提醒“在union定義結束時加分號”,其實是可以不加的,因為他不在主函數內,不是執行的語句,如果是主函數內聲明的union就必須加分號了,在主函數內不加分號就涉及到基礎常識了——沒有分號隔開怎能叫一句。

    ?

    3.聯合體union和大小端(big-endian、little-endian):

  • #include<stdio.h>??
  • union?var{??
  • ????????char?c[4];??
  • ????????int?i;??
  • };??
  • ??
  • int?main(){??
  • ????????union?var?data;??
  • ????????data.c[0]?=?0x04;//因為是char類型,數字不要太大,算算ascii的范圍~??
  • ????????data.c[1]?=?0x03;//寫成16進制為了方便直接打印內存中的值對比??
  • ????????data.c[2]?=?0x02;??
  • ????????data.c[3]?=?0x11;??
  • //數組中下標低的,地址也低,按地址從低到高,內存內容依次為:04,03,02,11。總共四字節!??
  • //而把四個字節作為一個整體(不分類型,直接打印十六進制),應該從內存高地址到低地址看,0x11020304,低位04放在低地址上。??
  • ????????printf("%x\n",data.i);??
  • }??

  • 結果:
    11020304
    證明我的32位Linux是小端(little-endian)

    ?

    ?


    4.聯合體union所占內存空間大小:

    前邊說了,首先,union的首地址是固定的,那么,union到底總共有多大?根據一些小常識,做個不嚴謹不高深的基礎版驗證吧。

    根據:分配??臻g的時候內存地址基本上是連續的,至少同類型能保證在一起,連續就說明,我如果弄三個結構體出來,他們三個地址應該連著,看一下三個地址的間隔就知道了。

  • #include<stdio.h>??
  • 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);??
  • }??


  • 打印,可以看到結果:

    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字節,按double走的。

    怕不保險,再改一下,把int改成數組,其他不變:

  • 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進制0x。那么0x28就是40個字節,正好是數組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.聯合體union適用場合:

    有了前邊那個驗證,基本可以確認,union的內存是照著里邊占地兒最大的那個變量分的。

    也就可以大膽的推測一下,這種union的使用場合,是各數據類型各變量占用空間差不多并且對各變量同時使用要求不高的場合(單從內存使用上,我覺得沒錯)。

    像上邊做的第二個測試,一個數組(或者更大的數組int a[100]),和一個或者幾個小變量寫在一個union里,實在沒什么必要,節省的空間太有限了,還增加了一些風險(最少有前邊提到的邏輯上的風險)。所以,從內存占用分析,這種情況不如直接struct。

    ?

    不過話說回來,某些情況下雖然不是很節約內存空間,但是union的復用性優勢依然存在啊,比如方便多命名,這種“二義性”,從某些方面也可能是優勢。這種方法還有個好處,就是某些寄存器或通道大小有限制的情況下,可以分多次搬運。

    ?

    ?

    6.本質&進階:

    ?

    根據union固定首地址union按最大需求開辟一段內存空間兩個特征,可以發現,所有表面的定義都是虛的,所謂聯合體union,就是在內存給你劃了一個足夠用的空間,至于你怎么玩~它不管~!(何止是union和struct,C不就是玩地址么,所以使用C靈活,也容易犯錯)

    ?

    沒錯,union的成員變量是相當于開辟了幾個接口(即union包含的變量)!但是,沒開辟就不能用了?當然也能用!

    寫個小測試:

  • #include<stdio.h>??
  • union?u{??
  • ????????int?i;??
  • ????????double?d;//這個union有8字節大小??
  • };??
  • main(){??
  • ????????union?u?uu;??
  • ????????uu.i?=?10;??
  • ????????printf("%d\n",uu.i);??
  • ??
  • ????????char?*?c;??
  • ????????c?=?(char?*)&uu;//把union的首地址賦值、強轉成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);//利用結束符'\0'打印字符串"abc"??
  • ????????printf("%c?%c?%c?%c?%c?%c\n",c[0],c[1],c[2],c[3],c[4],c[5]);??
  • }??
  • 一個例子了然,我的結構體只定義了int和double“接口”,只要我獲得地址,往里邊扔什么數據誰管得到?這就是C語言的強大,這就是union的本質——只管開辟一段空間。

    有些東西,熟悉編譯原理和編譯器工作過程的話,解決會更容易點,雖然我現在這方面技能不太強,不過一般問題也足夠分析了。

    總結

    以上是生活随笔為你收集整理的联合体的用法与特点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 香蕉手机网 | 午夜视频入口 | 国产精品-区区久久久狼 | 国产精品51 | av激情久久 | 香蕉网在线观看 | 国产精品亚洲一区二区无码 | 久久艹伊人 | 亚洲激情第一页 | 在线观看你懂的网址 | 亚洲欧美国产一区二区三区 | 久久久久久影视 | 国产免费大片 | 日本免费网站在线观看 | 2019av视频| 福利资源在线观看 | 日韩精品一区二区三区在线 | 亚洲日本三级 | 国产激情视频一区二区 | 成人欧美一区二区三区 | 成人免费毛片网 | 人妻精品无码一区二区三区 | 欧美青青草 | 日韩高清国产一区在线 | 日日舔夜夜摸 | 欧美精品色哟哟 | 高清一区二区三区视频 | 国产精品桃色 | 天天做天天摸天天爽天天爱 | 欧美视频| 久久这里只有精品8 | 精品黑人一区二区三区观看时间 | 国产一区亚洲一区 | 午夜一区 | 中文在线观看免费网站 | 亚洲精品乱码久久久久久蜜桃欧美 | 久久久一二三区 | 欧美性生交xxxxx久久久缅北 | av女人的天堂| 色呦呦呦呦 | 在线免费日韩av | 午夜视频网 | 喷水av| 成人入口| 国产亚洲性欧美日韩在线观看软件 | 2019狠狠干 | 一区二区小说 | 一区二区麻豆 | 欧美老熟妇乱xxxxx | 玉足调教丨vk24分钟 | 久久男人av | 韩国一二三区 | 在线观看日本网站 | 亚洲国产一区二区三区四区 | 欧美一级二级视频 | 午夜精品久久久久久久无码 | 国产福利视频一区二区 | 精品福利一区 | 久久潮 | 日韩激情片 | 国产综合第一页 | 成人免费视频国产免费 | 青青草综合视频 | 日本涩涩网 | 美女被猛网站 | 高h喷水荡肉少妇爽多p视频 | 亚洲一卡二卡在线观看 | 日韩国产一级 | 综合人人| 欧美com | 韩日产理伦片在线观看 | 亚洲伦理一区二区 | 羞羞动漫免费观看 | 欧美精品一卡 | 亚洲av无一区二区三区怡春院 | 男女透逼视频 | 国产精品久久无码一三区 | 一本久道视频一本久道 | 自拍偷拍免费 | 毛片基地在线观看 | 国产蜜臀av一区二区 | 日韩三级视频在线 | 国产性av| 亚洲国产成人精品一区二区三区 | 在线观看黄色的网站 | 极品91尤物被啪到呻吟喷水 | 国产精品一区一区三区 | 不卡国产在线 | 国产主播第一页 | 亚洲黄色激情视频 | 欧美一区二区三区国产 | 久久一| 狠狠撸狠狠干 | 狠狠躁夜夜躁人人爽视频 | 91亚洲精品乱码久久久久久蜜桃 | 色中文字幕 | 国产色视频一区二区三区qq号 | 变态另类ts人妖一区二区 | 香蕉视频一级片 |