C語言中文網 目錄

C語言聯合(union)的定義和初始化

當定義結構對象時,如果沒有顯式地初始化它們,則會采用一般初始化規則:如果該結構對象屬于動態存儲類型,那么其成員具有不確定的初始值。另一方面,如果結構對象具有靜態存儲周期,那么其非指針成員初始值是 0,其指針成員初始值是空指針。

不同于結構成員——它們在結構中都具有單獨的內存位置,聯合成員則共享同一個內存位置。也就是說,聯合中的所有成員都是從相同的內存地址開始。因此,可以定義一個擁有許多成員的聯合,但是同一時刻只能有一個成員允許含有一個值。聯合讓程序員可以方便地通過不同方式使用同一個內存位置。

定義聯合(union)

聯合的定義方式與結構是一樣的,只是把關鍵字 struct 改成 union

union [標簽名稱]{成員聲明列表};


下面的例子定義了一個名為Data的聯合類型,它有 3 個成員:i、x 和 str:
union Data { int i; double x; char str[16]; };

這種類型的對象可以存儲一個整數、一個浮點數或一個短字符串。下面的聲明定義了一個 union Data 類型的對象 var 和一個 unionData 類型的數組 myData,它有 100 個元素(聯合的空間大小為它最大成員的空間大小):
union Data var, myData[100];

如果想獲得聯合的空間大小,可以使用 sizeof 運算符。對上例來說,sizeof(var)會返回 16,而 sizeof(myData)則返回 1600。

如圖 1 所示,聯合中所有成員都是從內存中同一個地址開始的。


圖 1

為展示聯合和結構的差異,看看下面定義的 struct Record,它具有成員 i、x 和 str:
struct Record { int i; double x; char str[16]; };


圖 2
如圖 2 所示,結構對象中每個成員使用內存中的不同位置。

獲取聯合成員的方式和獲取結構成員的方式一樣。唯一的差異在于,當改變一個聯合成員的值時,實際上修改了該聯合所有成員的值。下面的一些例子使用聯合對象 var 和 myData:
var.x = 3.21;
var.x += 0.5;
strcpy( var.str, "Jim" );                       // 占用了var.x的內存位置
myData[0].i = 50;
for ( int i = 0; i < 50; ++i )
  myData[i].i = 2 * i;

與結構一樣,每個聯合類型的成員都擁有各自的命名空間。所以在上例最后的語句中,索引變量 i 和聯合成員 i 代表兩個不同的對象。

程序員要確保聯合對象的內存內容被正確地解釋和使用。聯合內成員的類型不同,允許程序員采用不同的方式解釋內存中的同一組字節值。例如,下面的循環使用聯合來展示一個 double 值在內存中的存儲形式:
var.x = 1.25;
for ( int i = sizeof(double) - 1; i >= 0; --i )
  printf( "%02X ", (unsigned char)var.str[i] );

該循環從 var.x 的最高位字節開始,生成下面的輸出:

3F F4 00 00 00 00 00 00

初始化聯合(union)

與結構類似,通過初始化列表(initialization list)來初始化聯合對象。但是,對聯合來說,列表只有一個初始化器(initializer)。

與結構一樣,C99 允許在初始化器中使用成員指示符來指示哪個成員被初始化。而且,如果初始化器沒有成員指示符,那么就與聯合內的第一個成員關聯。具有自動存儲類的聯合對象也可以使用已有的同類型對象來初始化。下面是一些初始化例子:
union Data var1 = { 77 },
           var2 = { .str = "Mary" },
           var3 = var1,
           myData[100] = { {.x= 0.5}, { 1 }, var2 };

數組 myData 中的元素如果沒有指定初始化器,會被隱式地初始化為 0 值。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo