Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Sefer Algan
Sefer Algan
http://www.seferalgan.com
İletişme geçmek için tıklayın.
71 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler:  C / Sys Prog. Sefer Algan
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : C / Sys Prog.
Yayınlanma Tarihi : 30.9.2002
Okunma Sayısı : 38018
Yorum Sayısı : 4     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 26.12.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 26.12.2024
Turhal Temizer
Conda install environment.yml Package 26.12.2024
Turhal Temizer
Mac OS/X Removing CUDA 26.12.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Fonksiyon Göstericileri ve Uygulamaları
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
C dilinde yazdığımız br fonksiyonu çağırdığımızda şimdilik neler  olup bittiğini tam olarak bilmesek de bildiğimiz bir şey var ki; o da fonksiyonlara ait kodların da bellekte tutulmasıdır. Fonksiyonlarda normal veri tipleri gibi bellekte bulunurlar ve bellekte bulunduğu bölgenin başlangıç adresi mevcuttur. Bu makalemizde fonksiyon göstericilerini tanımlama, fonksyion göstericilerinin uygulama alanlarını ve basit bir "Komut Yorumlayıcı" programıyla fonksyion göstericilerinin kullanımını göreceğiz. Aşağıdaki kod parçasında olan bitene bir göz atalım;

int islev()
{
int x;
x= 2 ;
return x;
}
int main(void)
{
int y ;
y=islev();
return 0;
}

Programımızın akışı main işlevi içinde y= islev(); satırına geldiğindemain işlevinin akışı durdurulur ve "islev" fonksiyonunun bulunduğu adrese gidilir, ve o adresten işlemler yapılmaya devam edilir.İşlev fonksiyonu icra edildikten sonra main işlevi kaldığı yerden devam ediyor. Evet gördüğünüz gibi her şey bildiğimiz gibi normal bir şekilde işledi. Peki bu mekanizma nasıl işledi? Main işlevi içinden islev() fonksiyonuna nasıl atladık?Bütün bunların cevabı fonksiyon göstericileridir, şöyle ki, aslında biz farkına varmasak da y=islev(); dediğimizde "islev" adresindeki kodu icra etmek istediğimizi bildiriyoruz. Kısacası bir fonksiyonun ismi o fonksiyonun kodlarının bulunduğu bellek bölgesinin başlangıç adresidir."islev" bir adres "()" ise fonksiyon çağırma operatörüdür.Fonksiyon çağırma operatörü fonksiyonun geri dönüş değerini üretir.

islev=> geri dönüş değeri int türünden olan bir fonksiyonun adresini tutan sabit bir bilgidir.

Fonksiyon göstericileri de bir nesne olduğuna göre tanımlanmaları ve onlara değer atamak son derece legal bir durumdur. Mesela bir fonksiyonun başlangıç adresi, bir fonksiyon göstericisine atanabilir.
Bir fonksiyon gösterici aşağıdaki gibi tanımlanır:

<geri dönüş değeri türü> (* gösterici ismi)([parametreler])

Aşağıda tanımlamaları verilmiş fonksiyon göstericilerini dikkatlice izleyin.

int (*p)(void);
void (*t)(int t,int m);
void (*k)(void);

Bir fonksiyon göstericisine her tür fonksiyon göstericisi atayamayız. Değerini atadığımız fonksiyon göstericisinin adresini tuttuğu fonksiyonun parametrik yapısı ve geri dönüş değeri, atama yapılacak göstericinin türüne uygun olmalıdır. Mesela yukarıda tanımlanan p fonksiyon göstericisine ancak ve ancak geri dönüş değeri int ve parametresi olmayan bir fonksiyonun adresi atanabilir.Aşağıdaki atamaların tamamı yanlış ve geçersiz atamalardır.

p=t; t=k; k=p; // yanlış

Fonksiyon gösterici tanımlarken kullandığımız ilk parantezler mutlaka kullanılmalıdır.Aksi halde tanımlamamız anlam değiştirip fonksiyon prototip tanımlamasına dönecektir. Aşağıda bu iki duruma örnek verilmiştir.

void (*pFunc)(int,int) // pFunc, geri dönüş değeri void ve parametrik yapısı int,int olan bir fonksiyon gösterici türüdür.

void *pFunc(int,int) // pFunc, geri dönüş değeri void türden bir gösterici olan ve parametrik yapısı int,int olan bir fonksiyon adıdır.Ve aynı zamanda bir adres sabitidir.

C dilinde fonksiyon isimleri tıpkı dizi isimlerinde olduğu gibi fonksiyonların bellekteki adres bilgilerini tutar ve bir sabit olarak ele alınırlar. Fonksiyon isimleri nesne olmadıkları için onlara herhangi bir fonksiyon göstericisinin değeri atanamaz.Aşağıdaki örnekte basit bir fonksiyon göstericisi kullanımı göreceksiniz.

void func(int a,int b)
{
printf("Ben adım func\n");
}

int main(void)
{
void (*pFunc)(int,int); // func’ın adresini atamak için bir gösterici tanımlıyoruz.
pFunc=func(); // uygun bir gösterici ataması yaptık.
return 0;
}

Fonksiyon göstericisi ile fonksiyon çağırma, () operatörü ile yapılır. Bu durumda () operatörünün operandı fonksiyon adresi olabileceği gibi bir fonksiyon göstericisi de olabilmektedir.Operand fonksiyon göstericisi olması durumunda programın akışı gösterici içindeki adrese gidecektir. Fonksiyon göstericiler de diğer türler gibi fonksiyonlara paremetre olarak geçirilebilirler.Mesela aşağıdaki "func" fonksiyonu parametresi bir fonksiyon gösterici olan fonksiyondur.

void normalfunc(void)
{
printf("Normal Fonksiyon");
}

void func(void (*p)(void))
{
p();
}

int main(void)
{
func(normalfunc);
return 0;
}

Yukarıdaki kodda main işlevi içinde "func" fonksiyonuna "normalfunc" fonksiyonunun adresi geçiliyor ve "func" da kendisine gelen adresteki koda akışı sağlıyor.Bu kodda fonksiyonların çağrılma sırası aşağıdaki gibi olacaktır.

main() -> func() -> normalfunc() -> main()

Fonksiyon göstericileri genellikle, bir fonksiyonun parametresi olarak kullnanılırlar.Bu şekilde ana fonksiyonun işlevi genelleştirilerek belli durumlarda parametre olarak aldığı fonksiyon göstericisinin tutuğu adresteki fonksiyonu çalıştırır.Bu şekilde ana fonksiyonu hiç değiştirmeksizin programımıza yeni modüller ekleyebiliriz.Makalemizin sonunda fonksiyon göstericilerinin bu şekilde kullanımına örnek olması için basit bir komut yorumlayıcısı yazacağız.

Önemli Not:void (*p)(); ifadesinde p’ye geri dönüş değeri void olan ve herhangi bir paremetrik yapıya sahip olan fonksiyon gösterici atanabilir. void (*p)(void); ifadesindeki p’ ye ise sadece geri dönüş değeri void ve parametresi void olan bir fonksiyon göstericisi atanabilir.

Fonksiyon göstericilerininde diğer türler gibi dizileri olabilir.Mesela void (*a[10])(void); tanımlaması a nın ,10 elamanlı bir fonksiyon gösterici dizisi olduğunu gösterir.Bu tür tanımlamalar okunabilirliği zorlaştırdığı için typedef edilmesi okunabilirlik açısından daha uygun olabilir.Örneğin;

typedef void (*pF)(void);
pF p; ile void (*p)(void); // yukarıdaki typedef işleminden sonra bu iki tanımlama aynı anlama gelir.

Buna benzer olarak,

typedef void (*a[10])(void); // burda a 10 elemanlı fonksiyon gösterici dizisidir.

Normal türler de olduğu gibi fonksiyon göstericilerine de tür dönüştürme işlemi ugulanabilir. Mesela,

int func(void)
{
...
}
int (*p)(int,int);
p=func; //hata
p=( int(*)(int,int) ) func; //yukarıdaki hata tür dönüştürme ile legal getirilebilir. En dıştaki parantezler tür dönüştürme operatörüdür.

Uygulama

Fonksiyon göstericilerine örnek olması açısından aşağıdaki basit komut yorumlayıcısını inceleyelim.Bir prompt çıkararak kullanıcıdan komutlar alarak bunları yorumlayıp çeşitli işlemler yapan programlara "komut yorumlayıcısı" denir.Komut yorumlayıcı programların algoritması bir döngü içinde bir string almak, bunu komut listesinde taramak ve uygun işlemleri yapmaktır.Bu tür prgramlar genellikle fonksiyon göstericileri kullanırlar.Biz bu uygulamamızda komut yorumlayıcısının ana çatısını yazacağız fakat komutların anlamsal işlevlerini yapmak başka derslerin konusu olduğu için komutların işlevi boş bırakılacaktır.

#include <stdio.h>
#define CMD_SIZE 120

//Aşağıdaki komut yapısında, her komut için bir ad, ve her komutun yapılması için o komuta ait fonksiyonun adresi tutulur

typedef struct _KOMUT{
char *komutAdi;
void (*proc)(void);
}KOMUT;

//Komutlarımız.Dikkat ederseniz bütün fonksiyonların parametrik yapısı ve geri dönüş değeri özdeştir.

void Edit(void)
{
printf("Edit\n");
}


void Copy(void)
{
printf("Copy\n");
}


void Format(void)
{
printf("Format\n");
}


void Dir(Exit)
{
printf("Exit\n");
}

//KOMUT yapısı türünde bir global dizi oluşturup komutlarımızın adlarını ve komutlara ait fonksiyonları yerleştirelim

KOMUT komutlarim[]={ {"Edit",Edit},{"copy",Copy},{"Format",Format},{"exit",Exit} } ;


//Ana işlevimiz



int main()void
{
char KOMUTADI[CMD_SIZE];
int i;

for(; ;){
printf("CS>");
gets(KOMUTADI);
for (i=0 ; komutlarim[i].komutAdi !=NULL ; ++i)
if(!(strcmp(KOMUTADI,komutlarim[i].komutAdi))){
komutlarim[i].proc();
break;
}
if (komutlarim[i].komutAdi == NULL)
printf("Komut bulunmadı:\n") ;
}
return 0;
}

Makale:
Fonksiyon Göstericileri ve Uygulamaları C ve Sistem Programlama Sefer Algan
  • Yazılan Yorumlar
  • Yorum Yaz
EYL
29
2003
aslında bu uygulamanın ekran görüntüsü çok basit olduğu için boyle bir gereklilik görmedim..yani makaleyi az çok iyi okuyan birisi ekran görüntüsünü kafasında rahatlıkla canlandırabilir diye düşünüyorum..
EYL
28
2003
abi iyi hoşta;biraz görüntü gelse daha iyi olmaz mı? Yani yapılan uygulamaya ait ekran görüntüsü felan...
OCA
15
2003
bu konuda kesinlikle haklı olduğunuzu belirtmek isterim.. bundan sonra gereken özen gösterilecektir.. ilginize teşekkür ederim
OCA
15
2003
Yazılan örnek kodlarda okunabilirlik kurallarına dikkat edilmesi, ayrıca yararlanılan kaynakların referanse edilmeleri gerekir.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • 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