C語言 共用體(Union)詳解及範例程式碼_C 語言

來源:互聯網
上載者:User

通過前面的講解,我們知道結構體(Struct)是一種構造類型或複雜類型,它可以包含多個類型不同的成員。在C語言中,還有另外一種和結構體非常類似的文法,叫做共用體(Union),它的定義格式為:

union 共用體名{
    成員列表
};

共用體有時也被稱為聯合或者聯合體,這也是 Union 這個單詞的本意。

結構體和共用體的區別在於:結構體的各個成員會佔用不同的記憶體,互相之間沒有影響;而共用體的所有成員佔用同一段記憶體,修改一個成員會影響其餘所有成員。

結構體佔用的記憶體大於等於所有成員佔用的記憶體的總和(成員之間可能會存在縫隙),共用體佔用的記憶體等於最長的成員佔用的記憶體。共用體使用了記憶體覆蓋技術,同一時刻只能儲存一個成員的值,如果對新的成員賦值,就會把原來成員的值覆蓋掉。

共用體也是一種自訂類型,可以通過它來建立變數,例如:

union data{ int n; char ch; double f;};union data a, b, c;

上面是先定義共用體,再建立變數,也可以在定義共用體的同時建立變數:

union data{ int n; char ch; double f;} a, b, c;

如果不再定義新的變數,也可以將共用體的名字省略:

union data{ int n; char ch; double f;} a, b, c;

共用體 data 中,成員 f 佔用的記憶體最多,為 8 個位元組,所以 data 類型的變數(也就是 a、b、c)也佔用 8 個位元組的記憶體,請看下面的示範:

#include <stdio.h>union data{ int n; char ch; short m;};int main(){ union data a; printf("%d, %d\n", sizeof(a), sizeof(union data) ); a.n = 0x40; printf("%X, %c, %hX\n", a.n, a.ch, a.m); a.ch = '9'; printf("%X, %c, %hX\n", a.n, a.ch, a.m); a.m = 0x2059; printf("%X, %c, %hX\n", a.n, a.ch, a.m); a.n = 0x3E25AD54; printf("%X, %c, %hX\n", a.n, a.ch, a.m);  return 0;}

運行結果:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

這段代碼不但驗證了共用體的長度,還說明共用體成員之間會相互影響,修改一個成員的值會影響其他成員。

要想理解上面的輸出結果,弄清成員之間究竟是如何相互影響的,就得瞭解各個成員在記憶體中的分布。以上面的 data 為例,各個成員在記憶體中的分布如下:

成員 n、ch、m 在記憶體中“對齊”到一頭,對 ch 賦值修改的是前一個位元組,對 m 賦值修改的是前兩個位元組,對 n 賦值修改的是全部位元組。也就是說,ch、m 會影響到 n 的一部分資料,而 n 會影響到 ch、m 的全部資料。

上圖是在絕大多數 PC 機上的記憶體分布情況,如果是 51 單片機,情況就會有所不同:

為什麼不同的機器會有不同的分布情況呢?這跟機器的儲存模式有關,我們將在VIP教程《大端小端以及判別方式》一節中展開探討。

共用體的應用

共用體在一般的編程中應用較少,在單片機中應用較多。對於 PC 機,經常使用到的一個執行個體是: 現有一張關於學生資訊和教師資訊的表格。學生資訊包括姓名、編號、性別、職業、分數,教師的資訊包括姓名、編號、性別、職業、教學科目。請看下面的表格:


Name
Num
Sex
Profession
Score / Course
HanXiaoXiao
501
f
s
89.5
YanWeiMin
1011
m
t
math
LiuZhenTao
109
f
t
English
ZhaoFeiYan
982
m
s
95.0

f 和 m 分別表示女性和男性,s 表示學生,t 表示教師。可以看出,學生和教師所包含的資料是不同的。現在要求把這些資訊放在同一個表格中,並設計程式輸入人員資訊然後輸出。

如果把每個人的資訊都看作一個結構體變數的話,那麼教師和學生的前 4 個成員變數是一樣的,第 5 個成員變數可能是 score 或者 course。當第 4 個成員變數的值是 s 的時候,第 5 個成員變數就是 score;當第 4 個成員變數的值是 t 的時候,第 5 個成員變數就是 course。

經過上面的分析,我們可以設計一個包含共用體的結構體,請看下面的代碼:

#include <stdio.h>#include <stdlib.h>#define TOTAL 4 //人員總數struct{ char name[20]; int num; char sex; char profession; union{  float score;  char course[20]; } sc;} bodys[TOTAL];int main(){ int i; //輸入人員資訊 for(i=0; i<TOTAL; i++){  printf("Input info: ");  scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex), &(bodys[i].profession));  if(bodys[i].profession == 's'){ //如果是學生   scanf("%f", &bodys[i].sc.score);  }else{ //如果是老師   scanf("%s", bodys[i].sc.course);  }  fflush(stdin); } //輸出人員資訊 printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n"); for(i=0; i<TOTAL; i++){  if(bodys[i].profession == 's'){ //如果是學生   printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);  }else{ //如果是老師   printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);  } } return 0;}

運行結果:

Input info: HanXiaoXiao 501 f s 89.5
Input info: YanWeiMin 1011 m t math
Input info: LiuZhenTao 109 f t English
Input info: ZhaoFeiYan 982 m s 95.0

Name                Num       Sex     Profession       Score / Course
HanXiaoXiao     501         f               s                   89.500000
YanWeiMin       1011       m              t                    math
LiuZhenTao      109         f                t                    English
ZhaoFeiYan      982        m              s                   95.000000

 以上就是對 C語言共用體 的資料整理,後續繼續補充相關資料,謝謝大家對本站的支援!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.