08.11.2014 Views

c_kitap

c_kitap

c_kitap

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

C ve Sistem Programcıları Derneği - C Ders Notları - Necati Ergin<br />

int cmp_person_no(const void *vp1, const void *vp2)<br />

{<br />

return ((const Person *)vp1)->no - ((const Person *)vp2)->no;<br />

}<br />

int main()<br />

{<br />

int a[10] = {3, 8, 4, 7, 6, 9, 12, 1, 9, 10};<br />

Person per[10] = { {"Ali Serce", 123}, {"Kaan Aslan", 563}, {"Ahmet<br />

Adlori", 312},{"Necati Ergin", 197}, {"Guray Sonmez", 297}, {"Erdem<br />

Eker", 144}, {"Nuri Yilmaz", 765}, {"Tayfun Tan", 117}, {"Demir Kerim",<br />

222},{"Can Mercan", 12}};<br />

Person *p_person;<br />

int *iptr;<br />

iptr = (int *)get_max(a, 10, sizeof(int), cmp_int);<br />

printf("int dizinin en buyuk elemani %d\n", *iptr);<br />

p_person = (Person *) get_max(per, 10, sizeof(Person),<br />

cmp_person_name);<br />

printf("per dizisinin en buyuk elemani (isme gore) %s %d\n",<br />

p_person->name, p_person->no);<br />

p_person = (Person *) get_max(per, 10, sizeof(Person), cmp_person_no);<br />

printf("per dizisinin en buyuk elemani (numaraya gore) %s %d\n",<br />

p_person->name, p_person->no);<br />

}<br />

return 0;<br />

Yukarıdaki programda get_max isimli işlev bir dizinin başlangıç adresini, boyutunu,<br />

dizinin bir elemanının uzunluğu ile dizinin elemanlarını karşılaştırma işleminde<br />

kullanılacak işlevin adresini alıyor. İşlev çağrısıyla dizi adresi void türden bir göstericiye<br />

alınıyor. Ancak işlev içinde gösterici aritmetiğinden faydalanmak amacıyla bu adres char<br />

türden bir göstericiye aktarılıyor. Bir elemanın boyutu bilindiğine göre bu değer dizinin<br />

başlangıç adresine eklenerek dizinin bir sonraki elemanının adresi bulunabilir değil mi?<br />

Karşılaştırma işlevi, karşılaştırma işlemini yapabilmek için iki nesnenin adresini alıyor.<br />

Böylece get_max işlevi içinde, karşılaştırma işlevi, parametre olan işlev göstericisi ile<br />

doğru argümanlarla çağırılabiliyor. Dizinin en büyük elemanının adresini bulmak için yine<br />

bilinen algoritma kullanılıyor. Ancak dizinin iki elemanının değerini karşılaştırmak için<br />

dışarıdan adresi alınan işlev çağrılıyor.<br />

Daha sonra üç ayrı karşılaştırma işlevinin tanımlanmış olduğunu görüyorsunuz. Tüm<br />

karşılaştırma işlevlerinin parametre değişkenleri (const void *, const void *) dır. Böylece,<br />

bu karşılaştırma işlevlerine get_max işlevi iki adres gönderdiğinde bir tür uyumsuzluğu<br />

sorunu ortaya çıkmaz.<br />

main işlevi içinde bir int türden bir de Person türünden dizi tanımlanıyor. Bu dizilere<br />

ilkdeğer verilmiş olduğunu görüyorsunuz. Daha sonra get_max işlevi çağrılarak dizilerin<br />

en büyük elemanlarının adresleri bulunuyor. cmp_person_name işlevi Person türünden iki<br />

nesneyi isimlerine göre karşılaştırırken, cmp_person_no işlevi ise Person türünden iki<br />

nesneyi, numaralarına göre karşılaştırıyor.<br />

Türden Bağımsız Sıralama<br />

Her türlü sıralama algoritmasında karşılaştırma ve değer takas etme söz konusudur. Bir<br />

dizinin türü bilinmese bile dizinin iki elemanı takas edilebilir. Karşılaştırma işleminini<br />

yapacak işlevin adresi çağıran kod parçasından alınırsa, türden bağımsız sıralama işlemi<br />

gerçekleştirilebilir. Aşağıdaki örneği inceleyin:<br />

512

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!