Göstericilerin Fonksiyonlarla İlişkisi

Pointer(Gösterici) Fonksiyon İlişkisi

Referans ile Fonksiyon Çağırma

     Bir fonksiyonuna argüman geçirmenin iki yolu vardır: 

  • Değere göre argüman geçirme
  • Referansa göre argüman geçirme

Bundan önce gördüklerimiz değere göre argüman geçirme işlemiydi, referansa göre argüman geçirme işlemini aşağıdaki programda inceleyelim.

  1. #include <stdio.h>
  2.  
  3. /* prototip */
  4. void referansaGoreKup ( int * );
  5.  
  6. int main( )
  7. {
  8. int sayi = 5;
  9.  
  10. printf( "Sayinin esas degeri %d\n", sayi);
  11. /* Referansa göre argüman gönderme*/
  12. referansaGoreKup( &sayi);
  13. printf( "\nSayinin yeni degeri %d\n", sayi);
  14.  
  15. return 0;
  16. }
  17. void referansaGoreKup( int *nPtr )
  18. {
  19. /* main’deki sayi’nın küpü alındı */
  20. *nPtr = *nPtr * *nPtr * *nPtr;
  21. }

referansaGoreKup( &sayi);

Daha önceki programlarda argüman yollarken operatörünü kullanmadan 

referansaGoreKup( sayi); şeklinde sayını değerini yollamıştık yukarıdaki 12. kod satırında değişkenin adresi fonksiyona yollanmış ve fonksiyon argüman alırken 17. kod satırında

void referansaGoreKup( int *nPtr );

&sayi ifadesi  gönderilirken *nPtr ifadesine atanmıştır, bu ifade değeri taşımaktadır ve değer üzerinde fonksiyonda işlem yapılmıştır. Yapılan işlemler adrese yansıdığından tekrar bu adreste olan sayi değeri çağrıldığında yapılan işlemler yansımış şekilde çıktı verir.

Referansa göre fonksiyona argüman gönderilirken fonksiyon prototipinde  referan geleceğini bildirmek gerekir.

void referansaGoreKup( int * );

Fonksiyonları Gösteren Göstericiler

     Bir fonksiyonu gösteren gösterici, fonksiyonun hafızadaki adresini tutar. Daha önce, dizi isminin, gerçekte dizinin ilk elemanının hafızadaki adresi olduğunu görmüştük. Benzer olarak, bir fonksiyon ismi, fonksiyonun görevini yapan kodun hafızadaki başlangıç adresidir.

     Fonksiyonları gösteren göstericiler, fonksiyonlara geçirilebilir, fonksiyonlardan geri döndürülebilir ve fonksiyonları gösteren diğer göstericilere atanabilir.

  1. #include <stdio.h>
  2. #define BOYUT 10
  3.  
  4. void kabarcik ( int [ ], const int, int (*)( int, int ) );
  5.  
  6. int artan( int, int );
  7. int azalan( int, int );
  8.  
  9. int main( )
  10. {
  11.  
  12. int secim, sayici, a[ BOYUT ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
  13.  
  14. printf( "Artan siralama icin 1 girin,\n""Azalan siralama icin 2 girin: " );
  15. scanf( "%d", &secim);
  16. printf( "\nVeriler orijinal sirasinda \n" );
  17.  
  18. for ( sayici = 0; sayici < BOYUT; sayici++ )
  19. printf( "%5d", a[ sayici] );
  20.  
  21. if ( secim == 1 )
  22. {
  23. kabarcik( a, BOYUT, artan);
  24. printf( "\nVeriler artan sirada \n" );
  25. }
  26. else {
  27. kabarcik( a, BOYUT, azalan);
  28. printf( "\nVeriler azalan sirada \n" );
  29. }
  30.  
  31. for ( sayici = 0; sayici < BOYUT; sayici++ )
  32. printf( "%5d", a[ sayici ] );
  33. printf( "\n" );
  34.  
  35. return 0;
  36. }
  37. void kabarcik ( int is[ ], const int boyut, int (*karsilastir)( int, int ) )
  38. {
  39. int tur, sayici;
  40.  
  41. void yerDegistir( int *, int * );
  42.  
  43. for ( tur = 1; tur < boyut; tur++ )
  44. for ( sayici = 0; sayici < boyut - 1; sayici++ )
  45. if ( (*karsilastir)( is[ sayici ], is[ sayici + 1 ] ) )
  46. yerDegistir( &is[ sayici ], &is[ sayici + 1 ] );
  47. }
  48. void yerDegistir( int *eleman1Ptr, int *eleman2Ptr )
  49. {
  50. int temp;
  51.  
  52. temp = *eleman1Ptr;
  53. *eleman1Ptr = *eleman2Ptr;
  54. *eleman2Ptr = temp;
  55. }
  56. int artan( int a, int b )
  57. {
  58. return b < a; /* b, a dan kücükse yer degiştir*/
  59. }
  60. int azalan( int a, int b )
  61. {
  62. return b > a; /* b, a dan büyükse yer degiştir */
  63. }

Aşağıdaki parametreler kabarcik fonksiyonunun ( satır 37) başlığında yer almaktadır.

int(*karsilastir)(int,int)

Bu, kabarcik fonksiyonuna iki tamsayı parametresi alan ve bir tamsayı sonucu döndüren bir fonksiyonu gösteren bir gösterici alacağını söyler. *karsilastir etrafındaki parantezler gereklidir, çünkü * fonksiyon parametrelerini içine alan parantezlere göre daha düşük önceliğe sahiptir.
Eğer parantezleri dahil etmeseydik, bildirim

int *karsilastir(int,int)

biçiminde olacaktı ve iki tamsayı parametresi alan ve bir tamsayıyı gösteren bir gösterici döndüren bir fonksiyon bildirilmiş olacaktı.

kabarcik fonksiyonunun prototipindeki ilgili parametre(satır 4)

int(*)(int,int)

biçimindedir. Yalnızca tiplerin kullanıldığına dikkat ediniz. Ancak programcı, dokümantasyon amacıyla derleyici tarafından ihmal edilecek isimler ekleyebilir.
kabarcik fonksiyonuna geçirilen fonksiyon, if ifadesi içinden(45.satır) aşağıdaki biçimde çağrılmıştır:

if ( ( * karsilastir ) ( is [sayici] , is [sayici+1] ) )

Bir değişkenin değerine erişmek için değişkeni gösteren göstericileri kullanılması gibi, fonksiyonu kullanmak içinde fonksiyonu gösteren göstericiler ele alınmalıdır.

Fonksiyon çağrısı, göstericinin gösterdiği nesneye erişilmeden aşağıdaki biçimde yapılabilirdi.

if ( karsilastir ) ( is [sayici] , is [sayici+1] ) )

Burada gösterici, fonksiyon ismi gibi doğrudan kullanılmıştır. Bir fonksiyonu gösterici ile çağırmak için ilk yöntemi tercih ederiz çünkü bu, fonksiyonu çağırmak için kullanılan karsilastir’ın, bir fonksiyonu gösteren gösterici olduğunu vurgular.

Kimler Neler Demiş?

  Abone ol  
Bildir