c語言 union
意思?英文直譯就是聯合體,就是一個多個變數的結構同時使用一塊記憶體地區,地區的取值大小為該結構中長度最大的變數的值。
union myunion{
char charvar;
int intvar;
float floatvar;
}
int main()
{
union myunion uni;
printf("請輸入一個字元");
scanf("%c", &uni.charvar);
printf("聯合myunion中當前存的是字元%c/n", uni.charvar);
printf("請輸入一個整數");
scanf("%d", &uni.intvar);
printf("聯合myunion中當前存的是整數%d/n", uni.intvar);
printf("請輸入一個浮點數")
scanf("%f", &uni.floatvar);
printf("聯合myunion中當前存的是浮點數%f/n", uni.floatvar);
}
聯合”與“結構”有一些相似之處。但兩者有本質上的不同。在結構中各成員有各自的記憶體空間,
一個結構變數的總長度是各成員長度之和。而在“聯合”中,各成員共用一段記憶體空間,
一個聯合變數的長度等於各成員中最長的長度。應該說明的是, 這裡所謂的共用不是指把多個成員同時裝入一個聯合變數內,
而是指該聯合變數可被賦予任一成員值,但每次只能賦一種值, 賦入新值則衝去舊值。如前面介紹的“單位”變數,
如定義為一個可裝入“班級”或“教研室”的聯合後,就允許賦予整型值(班級)或字串(教研室)。要麼賦予整型值,要麼賦予字串,不能把兩者同時賦予它。等位型別的定義和聯合變數的說明一個等位型別必須經過定義之後,
才能把變數說明為該等位型別。
一、聯合的定義
定義一個等位型別的一般形式為:
union 聯合名
{
成員表
};
成員表中含有若干成員,成員的一般形式為: 類型說明符 成員名 成員名的命名應符合標識符的規定。
例如:
union perdata
{
int
class;
char
office;
};
定義了一個名為perdata的等位型別,它含有兩個成員,一個為整型,成員名為class;另一個為字元數組,數組名為office。聯合定義之後,即可進行聯合變數說明,被說明為perdata類型的變數,可以存放整型量class或存放字元數組office。
二、聯合變數的說明
聯合變數的說明和結構變數的說明方式相同,
也有三種形式。即先定義,再說明;定義同時說明和直接說明。以perdata類型為例,說明如下:
union perdata
{
int
class;
char
officae;
};
union perdata a,b;
或者可同時說明為:
union perdata
{
int class;
char office;
}a,b;
或直接說明為:
union
{
int class;
char office;
}a,b
經說明後的a,b變數均為perdata類型。 它們的記憶體配置7—8所示。a,b變數的長度應等於 perdata
的成員中最長的長度, 即等於
office數組的長度,共10個位元組。可見,a,b變數如賦予整型值時,只使用了2個位元組,而賦予字元數組時,可用10個位元組。
聯合變數的賦值和使用
對聯合變數的賦值,使用都只能是對變數的成員進行。 聯合變數的成員表示為: 聯合變數名.成員名
例如,a被說明為perdata類型的變數之後,可使用 a.class a.office 不允許只用聯合變數名作賦值或其它操作。
也不允許對聯合變數作初始化賦值,賦值只能在程式中進行?掛 僨康魎得韉氖?一個聯合變數,
每次只能賦予一個成員值?瘓浠八?一個聯合變數的值就是聯合變員的某一個成員值。
[例7.15]設有一個教師與學生通用的表格,教師資料有姓名,年齡,職業,教研室四項。學生有姓名,年齡,職業,班級四項。
編程輸入人員資料, 再以表格輸出。
[code:1:8d8ee8c82c]
main()
{
struct
{
char name[10];
int age;
char job;
union
{
int class;
char office[10];
} depa;
}body[2];
int n,i;
for(i=0;i<2;i++)
{
printf("input name,age,job and department/n");
scanf("%s %d
%c",body[i].name,&body[i].age,&body[i].job);
if(body[i].job=='s')
scanf("%d",&body[i].depa.class);
else
scanf("%s",body[i].depa.office);
}
printf("name/tage job class/office/n");
for(i=0;i<2;i++)
{
if(body[i].job=='s')
printf("%s/t%3d %3c %d/n",body[i].name,body[i].age
,body[i].job,body[i].depa.class);
else
printf("%s/t%3d %3c %s/n",body[i].name,body[i].age,
body[i].job,body[i].depa.office);
}
}
[/code:1:8d8ee8c82c]
本常式序用一個結構數組body來存放人員資料, 該結構共有四個成員。其中成員項depa是一個等位型別,
這個聯合又由兩個成員組成,一個為整型量class,一個為字元數組office。在程式的第一個for語句中,輸入人員的各項資料,先輸入結構的前三個
成員name,age和job,然後判別job成員項,如為"s"則對聯合depa·class輸入(對學生賦班級編號)否則對depa·office輸
入(對教師賦教研組名)。
在用scanf語句輸入時要注意,凡為數群組類型的成員,無論是結構成員還是聯合成員,在該項前不能再加"&"運算子。如程式第18行中
body[i].name是一個數群組類型,第22行中的body[i].depa.office也是數群組類型,因此在這兩項之間不能加"&"運算子。程式中的第二個for語句用於輸出各成員項的值:
本章小結
1.
結構和聯合是兩種構造類型資料,是使用者定義新資料類型的重要手段。結構和聯合有很多的相似之處,它們都由成員組成。成員可以具有不同的資料類型。成員的表示方法相同。都可用三種方式作變數說明。
2.
在結構中,各成員都佔有自己的記憶體空間,它們是同時存在的。一個結構變數的總長度等於所有成員長度之和。在聯合中,所有成員不能同時佔用它的記憶體空間,它們不能同時存在。聯合變數的長度等於最長的成員的長度。
3. “.”是成員運算子,可用它表示成員項,成員還可用“->”運算子來表示。
4.
結構變數可以作為函數參數,函數也可返回指向結構的指標變數。而聯合變數不能作為函數參數,函數也不能返回指向聯合的指標變數。但可以使用指向聯合變數的指標,也可使用聯合數組。
5. 結構定義允許嵌套,結構中也可用聯合作為成員,形成結構和聯合的嵌套。
//----------------------------------------------------------------------------
#include
union myun
{
struct
{
int x;
int y;
int z;
}u;
int k;
}a;
int main()
{
a.u.x =4;
a.u.y =5;
a.u.z =6;
a.k = 0;
printf("%d %d %d/n",a.u.x,a.u.y,a.u.z);
return 0;
}
聯合變數的說明和結構變數的說明方式相同,
也有三種形式。即先定義
,
再說明
;
定義同時說明和直接說明。以
perdata
類型為例
,
說明如下
:
union perdata
{
int class;
char officae;
};
union perdata a,b;
或者可同時說明為
:
union perdata
{
int class;
char office;
}a,b;
或直接說明為
:
union
{
int class;
char office;
}a,b;
union類型是共用記憶體的,以size最大的結構作為自己的大小
,這樣的話,myun這個結構就包含u這個結構體,而大小也等於u這個結構體的大小,在記憶體中的排列為聲明的順序x,y,z從低到高
,然後賦值的時候,在記憶體中,就是x的位置放置4,y的位置放置5,z的位置放置6,現在對k賦值,對k的賦值因為是union,要共用記憶體,所以從union的首地址開始放置
,首地址開始的位置其實是x的位置
,這樣原來記憶體中x的位置就被k所賦的值代替了,就變為0了,這個時候要進行列印,就直接看記憶體裡就行了,x的位置也就是k的位置是0,而y,z的位置的值沒有改變,所以應該是0,5,6