5.5. Birlikler
Birlikler bir sözdizimsel, bir de
anlambilimsel fark dışında yapılara çok benzerler. Bir birliğin sözdizimi
aynıdır, sadece struct
yerine
union
anahtar
sözcüğünü kullanırız. Yapılarda, üyeler belleğe birbiri ardınca
yerleştirilirler (yani bir üyenin diğerinin üstüne sarkması söz konusu
değildir), böylece her üyeyi diğerlerinden bağımsız işleyebiliriz. Birliklerde
üyeler aynı bellek bölgesini paylaşırlar. Böylece, herhangi bir zamanda,
üyelerden sadece bir tanesi ile ilgilenebiliriz. Derleyici, en büyük üyeyi
içine alabilecek kadar geniş bellek ayırır. Örneğin,
union cifdg { char c; int i; float f; double d; int * g; } bd = { 'A' };
5 adet yerpaylaşımlı üyeden oluşan bd
birlik değişkenini tanımlar. sizeof bd
8’dir,
bu da en büyük üye olan double
(veya
int *
) değişkeninin
boyudur. Üyelere yapılarda olduğu gibi aynı yolla ulaşılır (yani
veya .
işlecini kullanarak). Örneğin,->
bd . d = 9.8696044011; printf("%c\n", bd.c);
Bu şekilde bu iki deyimi arka arkaya
kullanmanın yanlış olduğuna dikkat edin, çünkü bir taraftan
double
bir değer koyup, diğer taraftan bir
char
almaya çalışmaktayız. Ayrıca, her üye için
bir ilkleyenin bulunduğu yapılara karşılık, birliklerde en fazla bir
tane ilkleyenin olabildiğine dikkat edin. İlkleyen ilk üyeye uygulanır.
Örneğin, yukarıdaki tanımda bd.c
’ye 'A'
atanmaktadır; daha sonra, yukarıdaki iki deyim yerine getirildikten
sonra, E
çıktısını elde ederiz, bu
da anlamsız bir değerdir, çünkü bd.d
’ye atanan
değer bd.c
’deki değeri bozar.
Herhangi bir zamanda üyelerinden en fazla bir tanesinin bir değer tutacağını bildiğimiz zamanlarda, bellekten tasarruf etmek amacıyla genelde birlikler kullanılır. Bu özellik, daha önce verilmiş olan bir örneğin genişletilmiş uyarlaması olan, aşağıdaki örnekte kullanılmıştır:
struct kisi { char *isim; int dogumtarihi; enum cinsiyet_tipi { erkek, kadin } cinsiyet; union { int ahbtarihi; char *ksoyadi; } cbil; struct kisi *baba, *ana, *es, *cocuklar[MAKSCCK]; } kisiler[MAKSKS];
Burada kişinin cinsiyetine bağlı olan iki adet
bilgi vardır: Erkekler için askerlik hizmetini bitirme, yani terhis tarihi
(ahbtarihi
), kadınlar için
ise kızlık, yani evlenmeden önceki soyadı (ksoyadi
).
Aynı zamanda her iki üyenin anlamlı
bir değer saklamayacaklarını bildiğimiz için, bellekten tasarruf etmek
amacıyla, bunları bir birliğin içine alıyoruz. Hangi üyeyi
(kisiler[birisi].cbil.ahbtarihi
veya
kisiler[birisi].cbil.ksoyadi
) kullanmamız
gerektiğini belirlemek için kisiler[birisi].cinsiyet
içindeki bilgiyi kullanabiliriz.