Fonksiyonlar
Fonksiyonlar
Fonksiyon Tanımlama
Kullanımı:
VeriTipi fonksiyonAdı (değişken listesi)
{ ………….
}
// fonksiyon başlığı=> int main( ), int main () // int=> veri tipi main=> Fonksiyon adı { // fonksiyon gövdesi başlangıcı cout<< "Merhaba C++!"; return 0;, } // fonksiyon gövdesi bitişi
Daha önce bahsetmiş olduğumuz return komutu fonksiyon kullanıldığında istenilen değeri çağrılan programa gönderme işlevini üstlenendir.
#include<iostream> using namespace std; int faktoriyel (int x) // "faktoriyel" adında fonksiyon tanımlanmış { //"int x" adından integer bir" x" değişkeni alıyor .............. ......... return f; // "int faktoriyel" olarak tanımlandığı için çağrıldığı yere integer "f" değerini yollar } main () { ....... ...... cout<<sayi<<"!="<<faktoriyel(sayi)<<endl; .... // faktoriyel (sayi) fonksiyon içine "sayi" değişkeni gönderilerek çağırılmış }
Aşıdaki programda Fonksiyon Başlığı yazan kısım fonksiyonun bir değişken gibi tanımlandığı kısımdır.(int x gibi)
int faktoriyel (int x)
Fonksiyon Prototipi
- Fonksiyonlar sekmesinde bahsettiğimiz fonksiyonun programda tanımlama işlemidir.
- Kullandığımız her ismin (değişken, sabit, fonksiyon vs.) kullanmadan önce tanımlanması gerekmektedir.
- Fonksiyonları önceden tanıtıp fonksiyon içeriğini istediğimiz yere, hatta başka bir dosyaya bile yazmamız fonksiyon prototipi ile mümkündür.
int fakt( int x); // veya int fakt (int);
şeklinde tanımlanır. İlk tanımlamada değişkenin fonksiyonun içerisinde x olarak işlem yapacağını ikincisinde gönderilen programın kendi değişkenin kullanılacağı anlatılmıştır.
#include<iostream> using namespace std; int fakt(int); //fonksiyon prototipi(tanımlanması) int main() { int n,sonuc; cout<<“Bir sayi giriniz: “; cin>>n;//girilen n kullanılarak 4 kez çağrılmıştır sonuc=(fakt(n)/4)*(6/fakt(n-1))+(fakt(n-2)/2)*(7/fakt(n-3)); cout<<“Sonuc= “<<sonuc<<endl; return 0; } int fakt(int x) //n değeri gönderilmiştir ve artık x olmuştur { int f=1; for(int i=1;i<=x;i++) f*=i; return f; // fonksiyon çağrıldığında f değeri gönderilmiştir }
Değişken Döndürmeyen Fonksiyonlar
Bir fonksiyon çağrılan fonksiyona değer döndürmüyorsa veya değişken içermiyorsa bu durum void yazarak belirtilir.
- Void fonksiyonları değer döndürmeyeceğinden return komutu içermeyebilir.
#include<iostream> using namespace std; void fonk1(); // değişken döndürmeyen fonksiyon int main() { int a=6; cout<<“a=”<<a<<endl; fonk1(); // a değeri 7 olur fonk1 den çağırılmış çağrıldığından fonk fonksiyonunun içinde a yazdırılmış system(“pause”); return 0; } void fonk1() { int a=7; cout<<“a=”<<a<<endl; }
Programda void mesaj (void) yazan kısımda “(void)” programın içinde bir değişken dönmediği anlamına gelir.
baştaki void kısmında ise programın çağrıldığı fonksiyona bir değişken göndermediği anlamına gelir.
#include <iostream> using namespace std; void buyuk(float ,float) // fonksiyon prototipi int main() { float x, y; cout << “Ikideger giriniz:”; cin >> x >> y; // iki sayı girilir buyuk(x, y); // ikisayı fonksiyona yollanır return 0; } void buyuk(float a, float b)// iki sayının büyüğünü bulan fonksiyon { cout << “Sayilarin buyugu :”; if (a>b) // iki sayı karşılaştırılır cout << a << endl; else cout << b << endl; } /*///////////////////////////////////////////////////////////////////// main buyuk x y a b 3.4 2.1 3.4 2.1 //////////////////////////////////////////////////////////////////////*/
Yukarıdaki programda alt fonksiyonda değişkenle işlem yapılmış fakat değişken çağrılan programa değer gönderilmemiştir. Aşağıda alan hesaplayan programda alan fonksiyonu parametre almamış ve parametre göndermiştir.
#include<iostream> using namespace std; double alan(void); // fonsiyon prototipi(tanımlanması) int main() { double sonuc; sonuc=alan(); // alan() fonksiyonu çağrılır döndürdüğü değer sonuc’a atanır cout<<“Alan= “<<sonuc<<endl; return 0; } double alan (void) // en ve boyu okuyup digdörtgenin alanını hesaplar { double en,boy; cout<<“Digdortgenin en ve boyunu giriniz: “; cin>>en>>boy; return en*boy; // en ile boy çarpılıp çağırıldığ fonksiyona döndürülür }
Parametreli Fonksiyonlar
- Çağrılan fonksiyonla çağıran fonksiyon arasında veri alışverişi parametre kullanılarak yapılır.
- Çağıran fonksiyonda yer alan parametreler gerçek parametre, çağrılan fonksiyonda yer alan parametrelere formal parametre ismi verilir.
- Bu parametrelerin sayısının ve veri tipinin uyumlu olaması gerekir.
void fon (int, float); int main() { int x=5; float y=3.6; fon (x,v); // gerçek parametre } void fon ( int a,float b) { // " ( int a,float b)" Formal parametre ......... }
Referans Değişkeni
- Referans değişkenleri bir değişkene farklı bir isim vermek için kullanılır.
- Referans değişkenleri & (referans) operatörü ile tanımlanır.
deger değişkenin int 32 bitlik adresine 5 değeri kayıt edilmiştir.
&ref değişkenin direk adresi dir. & değişkenin adresine erişme operatörüdür. Bu adrese erişilmiş ve 5 değeri atanmıştır.
Referans değişkenlerini tanımladığımızda mutlaka ilk değer atamasını yapmamız gerektiğini, hangi değişkenin referansı olacağını belirtmemiz gerektiğini unutmayalım.
int &ref; // Geçersiz tanımlama
Bir referans değişkeni tek bir değişkenin referansı olabilir ve bu ilk atama sırasında belirlenir. Daha sonra bu referans değişkeni farklı bir değişkenle ilişkilendirilmez.
int x=5,y=6; int &ref=x; ref=y; // geçersiz atama
Göstergeler kısmında bu kısım daha iyi anlaşılacaktır.
Fonksiyon Parametreleri
- Değer Parametresi: Çağrılan fonksiyona gerçek parametre değerinin bir kopyası yollanır.Fonksiyonda formal parametre için bellekte bir yer açılır ve yollana değer bu yere kopyalanır. Fonksiyon bitiminde yeni açılan yer yok olur ve gerçek parametrenin değeri etkilenmez.
- Referans Parametresi: Fonksiyona gerçek parametrenin referansı yollanır. Böylece fonksiyon başlığında yer alan formal parametre ve yollanan gerçek parametre parametreye yapılan herhangi bir değişiklik gerçek parametreye de yansır.
Aşağıda bulunan programı inceleyelim
#include<iostream> using namespace std; void supriz(int a, int & b); // fonsiyon prototipi(tanımlanması) { a=5; b=6; cout<<“a=”<<a<<“b=”<<b<<endl; } int main() { int i=10;,j=20; supriz(i,j); cout<<“i=”<<i<<“j=”<<j<<endl; return 0; }
Burada ana fonksiyonda (main) supriz(i,j) gönderilen i ve j değerleri supriz alt programında a ve &b değerlerine karşılık gelmiştir. Çıktıda görüleceği üzere i değeri a‘ya atanmış ve a‘nın değerini değiştirmiş 10 yapmıştır, &b‘ye atanan j değeri adrese atandığı için değeri değişmemiş &b adresinde bulunan değeri değiştirmemiş, ekrana o adresteki değeri 6 olarak yazdırmıştır.
Varsayılan Parametreler
- Çağrılan fonksiyonda ki formal parametreler ile fonksiyon çağrılmasında yer alan gerçek parametrelerin sayı ve tip olarak uyuşması gerekir.
- Çağıran fonksiyon, çağrıldığı fonksiyona gerçek parametre yollamayacaksa, varsayılan parametreler (default parameter) kullanılır.
Gerçek parametre yollanmadığında daha önce tanımlanmış değeri alan parametreler varsayılan parametre denir.
#include<iostream> using namespace std; void fon (int x=1,int y=20) // Varsayılan değerlerle 2 formal parametre { cout<<x<<” “<<y<<endl; } int main() { fon(5,10); // 2 gerçek parametre ile çağrılmış fon(5); // 1 gerçek parametre ile çağrılmış fon(); // gerçek parametresiz return 0; }
- Varsayılan parametreler parametre listesini sonunda yer almalıdır.
void fon(int x=5, int y) // hata
- Varsayılan parametreleri fonksiyon prototipinde veya fonksiyon başlığında belirtebiliriz, ancak ikisinde birden belirtmemiz gerekir.
void fon (int, int=5); // fonksiyon prototipi ….. void fon ( int y, int x=5) // fonksiyon başlığı {……}
Fonksiyon Yükleme (Over Load)
Aynı isimde birden fazla fonksiyonu, farklı parametrelerle tanımlayabiliriz. Bu yönteme, Fonksiyon Yükleme ismi verilir.
Programda gönderilen değerler değerler iki fonksiyonda da aynı işlemi yapmaktadır.
#include <iostream> using namespace std; int topla(int, int); double topla(double, double); int main() { cout << “1. topla fonksiyonu: ” << topla(2,3)<< endl; cout << “2. topla fonksiyonu: ” << topla(4.3, 5.6) << endl; return 0; } int topla(int x, int y) { return x + y; } double topla(double x, double y) { return x + y; } /*////////////////////////////////////////////////////////////////////// Çıktı: 1.topla fonksiyonu:5 2.topla fonksiyonu:9.9 ///////////////////////////////////////////////////////////////////////*
Satıriçi Fonksiyonlar
Satıriçi (inline) fonksiyonlar, fonksiyonun kullanıldığı yerlere doğrudan yapıştırılır, böylece fonksiyon çağırma işleminin yapılmasına gerek kalmaz.
inline VeriTipi fonksiyonAdı() { // tanımlar } // örnek inline double alan() { return a*a; }
Recursive (Özyinelemeli) Fonksiyonlar
- Bir fonksiyon doğrudan veya dolaylı olarak kendini çağırıyorsa recursive fonksiyon olarak adlandırılır.
- Recursive fonksiyonlar bir kontrol deyimiyle iki duruma ayrılırlar.
Genel Durum (Recursive)
Temel Durum (Non- Recursive)
- Tekrarlı (İterative) fonksiyonların hepsi recursive olarak çözülebilir
Recursive fonksiyonların hafıza kullanımı daha yüksektir.
Recursive kod yazımı daha kolaydır. Bazı algoritmalar yapıları gereği recursive yazıma daha uygundur
Sürekli kendini çağıran fonksiyonlar sonsuz döngüye girer.
#include<iostream> using namespace std; int faktoriyel (int n) { if(n<=1) return 1; else return (n*faktoriyel(n-1)); } int main() { int n; cout<<“Bir sayi giriniz: “; cin>>n; cout<<n<<“!= “<<faktoriyel(n)<<endl; return 0; }