| 
                
             | 
        
        
            
                
                    
                        | 
                            C' de Birliklerin (Unions) Kullanılması | 
                        
                             | 
                                
                     
                    
                        
                            
	
    
		
            | Gönderiliyor lütfen bekleyin... |   
        
	 
    
 
                         | 
                     
                 
             | 
        
        
            
                
                Birlikler, genel haliyle yapılara benzeyen, ancak elemanlarının bellekteki 
yerleşimi açısından yapılardan farklılık gösteren kullanıcı tanımlı veri 
türleridir. Yapılara göre 
daha az kullanılırlar. Ancak uygulamada, birlik kullanarak programcının bir çok 
avantaj sağlayacağı bazı durumlar vardır. Önce birliklerin yapılarla ortak olan 
özelliklerini inceleyelim : Birlikler de yapılar gibi üye veri elemanlarına 
sahiptirler. Bu veri elemanları C dilinin doğal türleri tipinde veya kullanıcı 
tanımlı türleri tipinde olabilir. Hatta bir birliğin elemanı başka bir birlik 
olabilir. Birlik nesnesinin elemanlarına nokta (.) operatörü ile erişilir. Eğer 
birlik türünden bir gösterici kullanılıyorsa birliğin elemanlarına ok (->) 
operatörü ile erişilir. Derleyici birlik veya yapı bildirimi gördüğü zaman 
bellekte herhangi bir yer ayırma işlemi yapmaz. Yer ayırma işlemi, sadece o 
türden bir nesne tanımlandığı zaman gerçekleştirilir. Dilerseniz buraya kadar 
anlattıklarımı aşağıdaki kod örneği ile inceleyelim;
  
	
		typedef union _test 
{ 
    int i; 
    double d; 
}test; 
 
// Buraya kadar henüz bellekte yer ayırma işlemi yapılmadı. 
// ... 
 
test t; // birlik türünden nesne tanımlanması (bellekte yer ayırma işlemi 
yapıldı). 
t.i = 4; // birlik elemanlarına nokta operatörü ile erişilmesi ve elemana değer 
atanması. 
t.d = 4.0;  
 
test *pt; // birlik türünden gösterici tanımlanması. 
pt->i = 2; // birlik elemanlarına ok operatörü ile erişilmesi ve elemana değer 
atanması. 
pt->d = 2.0; 
 
// ...   | 
	 
 
Şimdi de birliklerin yapılardan farklılıklarını inceleyelim: Birliklerin 
yapılarla farklılık gösterdiği nokta, veri elemanlarının bellekteki 
yerleşimidir. Derleyici bir birlik nesnesi tanımlandığı zaman, bu nesne için 
bellekte birliğin en uzun elemanı kadar yer ayırır. Bilindiği gibi yapı 
nesnelerinin bellekte kapladığı yer (hizalama seçenekleri 
de göz önünde bulundurularak) tüm yapı elemanlarının uzunluklarının toplamı 
kadardır. Önce yapılardaki durumu aşağıdaki örnek kod ile incelemeye çalışalım.
  
	
		struct _stest 
{ 
    int i; 
    double d; 
}stest; 
 
// ... 
stest test; 
printf("%d\n",sizeof(test)); //Ekrana (4 + 8) 12 yazacaktır. (Hizalama seçeneği
byte-alignment ise ve 32 bitlik sistemde) 
 
// ... | 
	 
 
Şimdi de birliklerdeki durumu inceleyelim :
  
	
		union _utest 
{ 
    int i; 
    double d; 
}utest; 
 
// ... 
utest test; 
printf("%d\n",sizeof(test)); //Ekrana 8 yazacaktır. 
// ... | 
	 
 
Görüldüğü üzere derleyici bir birlik nesnesi için bellekte, birliğin en fazla 
yer kaplayan elemanı kadar yer ayırmaktadır. Birliğin elemanlarına atanan 
değerler birliğin bellekteki adresinden başlayarak yazılmaktadır. Yani birliğin 
tüm veri elemanları aynı adresten başlayarak yazılır. Birliğin en uzun veri 
elemanı kadar yer ayrıldığı için herhangi bir taşma hatası da olmamaktadır. Bu 
durumda bir elemana değer atadığımızda diğer bir elemandaki değerin üzerine 
yazılacağı için bu elemanın değeri de kaybedilmiş olur. Ancak bu durum, birliğin 
dezavantajı olarak görülmemelidir. Çünkü birliklerin varlık nedeni de zaten bu 
özellikleridir. 
 
Birliklerin bu özelliklerinden nasıl bir avantaj sağlayabiliriz? Uygulamada 
birkaç şekilde birlik veri türüne ihtiyaç duyulabilir. Şimdi bir örnek üzerinde 
ilerleyerek bu durumlardan birisini inceleyelim. Bir fabrikada bir malzemenin iki 
farklı işlemde kullanıldığını düşünelim. Diyelim ki A malzemesi, hem op1 
işleminde hem de op2 işleminde kullanılıyor. Biz bu iki işleme ilişkin bilgileri 
tutmak istiyoruz. op1 işleminde A malzemesinin nitel özellikleri, op2 işleminde 
ise nicel özellikleri önem taşısın. Malzemenin bu özelliklerini iki yapı 
bildiriminde toplayabiliriz. Sistemde cins, renk ve şekil özelliklerinin 
tamsayılar ile ifade edildiğini düşünelim :
  
	
		typedef struct _nitelOzellikler 
{ 
    int cins; 
    int renk; 
    int sekil; 
}nitelOzellikler; // 12 byte 
 
typedef struct _nicelOzellikler 
{ 
    double agirlik; 
    double yogunluk; 
    double miktar; 
}nicelOzellikler; // 24 byte | 
	 
 
op1 işlemine ilişkin bilgileri tutarken malzemenin nicel özelliklerine 
ihtiyacımız yoktur. Benzer şekilde op2 işlemine ilişkin bilgileri tutarken de 
malzemenin nitel özelliklerine 
ihtiyacımız yoktur. Bu durumda bu iki tür özelliği veri elemanı olarak alan bir 
birlik bildirelim :
  
	
		typedef union _ozellikler  
{ 
    nitelOzellikler nitel; 
    nicelOzellikler nicel; 
}ozellikler; // 24 byte | 
	 
 
Görüldüğü gibi birlik, bellekte en uzun veri elemanı kadar, yani 24 byte yer 
kaplayacaktır. Bu özelliklerin haricinde malzemenin bir de genel özellikleri 
olsun, bu özellikler hem op1 işleminde hem de op2 işleminde girdi olarak 
alınsın. Genel özellikleri malzeme yapısının içerisinde bildirebiliriz. Malzeme 
yapısında yukarıda bildirimini yaptığımız birlik türünden bir veri elemanını da 
ekleriz. Yapılan işleme göre birliğin ilgili elemanını kullanırız.
  
	
		typedef struct _malzeme  
{ 
    char *firmaAdi; 
    char *markasi; 
    double stokMiktari; 
    ozellikler ozellik; 
}malzeme; //40 byte | 
	 
 
Bu bildirim ile, op1 işlemine ait bir işlemin bilgilerini tutarken gereksiz yere 
malzemenin nicel özellikleri için bellek kullanılmayacaktır. op2 işlemi için de 
gereksiz yere 
malzemenin nitel özellikleri için bellek kullanılmayacaktır. Bu durumda 
bellekten, op1 işlemi için 24 byte, op2 işlemi için ise 12 byte kazanç 
sağlanacaktır. Malzeme yapısı türünden bir nesne bu haliyle bellekte 40 byte yer 
kaplayacaktır. Eğer birlik kullanmayıp da tüm özellikleri aynı yapı nesnesi 
içerisinde bildirmiş olsaydık bu yapı türünden bir nesne bellekte 52 byte yer 
kaplayacaktır. Bu yapı nesnesi içerisindeki bilgileri op1 ve op2 işlemleri için 
ekranda gösterecek iki fonksiyon yazalım :
  
	
		void DisplayOp1(const malzeme *malz) 
{ 
    printf("%s\n",malz->firmaAdi); 
    printf("%s\n",malz->markasi); 
    printf("%lf\n",malz->stokMiktari); 
    printf("%d\n",malz->ozellik.nitel.cins); 
    printf("%d\n",malz->ozellik.nitel.renk); 
    printf("%d\n",malz->ozellik.nitel.sekil); 
} 
 
void DisplayOp2(const malzeme *malz) 
{ 
    printf("%s\n",malz->firmaAdi); 
    printf("%s\n",malz->markasi); 
    printf("%lf\n",malz->stokMiktari); 
    printf("%lf\n",malz->ozellik.nicel.agirlik); 
    printf("%lf\n",malz->ozellik.nicel.miktar); 
    printf("%lf\n",malz->ozellik.nicel.yogunluk); 
} | 
	 
 
Şimdi bildirdiğimiz yapıyı ve fonksiyonları kullanarak ana bloğu oluşturalım 
:
  
	
		int main() 
{ 
   
malzeme m1; 
   
malzeme m2; 
 
   
//op1 işlemi yapılıyor... 
   
m1.firmaAdi = "fabrika1"; 
   
m1.markasi = "marka1"; 
   
m1.stokMiktari = 10.0; 
   
m1.ozellik.nitel.cins = 1; 
   
m1.ozellik.nitel.renk = 2; 
   
m1.ozellik.nitel.sekil = 3; 
 
   
//op2 işlemi yapılıyor... 
   
m2.firmaAdi = "fabrika2"; 
   
m2.markasi = "marka2"; 
   
m2.stokMiktari = 20.0; 
   
m2.ozellik.nicel.agirlik = 10.5; 
   
m2.ozellik.nicel.miktar = 12.5; 
   
m2.ozellik.nicel.yogunluk = 0.02; 
 
   
DisplayOp1(&m1); 
   
DisplayOp2(&m2); 
 
   
return 0; 
} | 
	 
 
Birliklerin bellek kazancı açısından yararını bu örnekle açıklamış olduk. Geniş 
çaplı bir 
uygulamada yer alabilecek daha karmaşık yapılar düşünüldüğünde ve özellikle 
bellek 
kullanımının kritik bir rol oynadığı uygulamalar göz önünde bulundurulduğunda 
birlikler 
kullanılarak ciddi bellek kazançları sağlanabilir. Bellek kazancının yanı sıra 
kodun 
okunabilirliği de birlik kullanımı sayesinde artmaktadır. Bir sonraki yazımızda 
görüşmek dileğiyle hoşçakalın.
  
Kaynak kod için tıklayın.
  
                
                Makale: 
                C' de Birliklerin (Unions) Kullanılması C ve Sistem Programlama Çiğdem Çavdaroğlu 
             | 
        
        
            | 
             | 
        
        
            | 
                 
             | 
        
        
            
                
                
                    
                        - 
                            
                        
 
                        - 
                            
Eklenen Son 10  
                         
                        - 
                            
Bu Konuda Geçmiş 10 
                         
                     
                    
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                        
                            Son Eklenen 10 Makale Yükleniyor
                         
                        
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         
                     
                 
                
                
             | 
        
        
            | 
                
             |