聯合(union)用法

    聯合(union)在C裏面見得並不多,但是在一些對內存要求特別嚴格的地方,聯合又是頻繁出現,那麼究竟什麼是聯合?怎麼去用?有什麼需要注意的地方呢?
(1)什麼是聯合?一種構造類型的數據結構。在一個“聯合”內可以定義多種不同的數據類型, 一個被說明爲該“聯合”類型的變量中,允許裝入該“聯合”所定義的任何一種數據,這些數據共享同一段內存,已達到節省空間的目的。這是一個特殊的地方,也是聯合的特徵。
(2)聯合與結構的區別?“聯合”與“結構”有一些相似之處,但兩者有本質上的不同。在結構中各成員有各自的內存空間, 一個結構變量的總長度是各成員長度之和(空結構除外,同時不考慮邊界調整)。而在“聯合”中,各成員共享一段內存空間, 一個聯合變量的長度等於各成員中最長的長度。應該說明的是, 這裏所謂的共享不是指把多個成員同時裝入一個聯合變量內, 而是指該聯合變量可被賦予任一成員值,但每次只能賦一種值, 賦入新值則衝去舊值。下面舉一個例了來加對深聯合的理解。
int _tmain(int argc, _TCHAR* argv[])
{
      union number
      {
            int i;
            struct  
            {
                   char first;
                   char second;   //由最右邊開始排,即second  first
             }half;
       }num;
       num.i=0x4241;
       printf("%c %c /n",num.half.first,num.half.second);
       num.half.first='a';
       num.half.second='b';
       printf("%x /n",num.i);
       getchar();
}
輸出結果爲:      AB      6261 
(3)如何說明?聯合變量的說明有三種形式:先定義再說明、定義同時說明和直接說明。以test類型爲例,說明如下:
    1) union test
       {
             int office;
             char teacher[5];
       }; 
       union test a,b;    /*說明a,b爲test類型*/
    2) union test
       {
             int office;
             char teacher[5];
       } a,b;
    3) union 
       {
             int office;
             char teacher[5];
       } a,b; 
      經說明後的a,b變量均爲test類型。a,b變量的長度應等於test的成員中最長的長度,即等於teacher數組的長度,共5個字節。a,b變量如賦予整型值時,只使用了4個字節,而賦予字符數組時,可用5個字節。

(4)需要討論的地方。聯合裏面那些東西不能存放?我們知道,聯合裏面的東西共享內存,所以靜態、引用都不能用,因爲他們不可能共享內存。

(5)關於聯合類型的子數據沒有具體大小的現象。

typedef union DAY_REGISTER 
{
    UINT32 value;
    struct
    {
        unsigned seconds    : 6;
        unsigned minutes    : 6;
        unsigned hours      : 5;
        unsigned dayOfWeek  : 3;
        unsigned weekOfMonth: 3;
        unsigned reserved   : 9;       //注意以上這些定義沒有具體類似INT的類型符號
    };
} DayRegister;

DayRegister  dayReg;

 

typedef struct _SYSTEMTIME {
    WORD wDayOfWeek;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME, *LPSYSTEMTIME;
LPSYSTEMTIME pTime;

 

結果,以下的賦值操作是有效的:

    dayReg.dayOfWeek    = pTime->wDayOfWeek + 1;   

    dayReg.hours        = pTime->wHour;
    dayReg.minutes      = pTime->wMinute;
    dayReg.seconds      = pTime->wSecond;

發佈了22 篇原創文章 · 獲贊 14 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章