Standart C Programlama Dili


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.