int faktoriyel(int sayi) { int sonuc = 1; for(int i=sayi;i>0;i--) sonuc*=i; return sonuc; } int main() { int sayi = faktoriyel(5); }

Benzer belgeler
BMT 101 Algoritma ve Programlama I 11. Hafta. Yük. Müh. Köksal Gündoğdu 1

PROGRAMLAMAYA GİRİŞ FONKSİYONLAR

ELN1001 BİLGİSAYAR PROGRAMLAMA I

ALGORİTMA VE PROGRAMLAMA I

ALGORİTMA VE PROGRAMLAMA I

C Programlama Dilininin Basit Yapıları

Sunum İçeriği. Programlamaya Giriş

Örnek: İki fonksiyondan oluşan bir program. Fonksiyon Tanımı

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) {

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Dr. Fatih AY Tel: fatihay@fatihay.net

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler

BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN

Sınav tarihi : Süre : 60 dak. a) ABCDE b) BCDE c) ABCD d) kod hatalı e) BCD

C#(Sharp) Programlama Dili

HSancak Nesne Tabanlı Programlama I Ders Notları

Özyineleme (Recursion)

BM102 BİLGİSAYAR PROGRAMLAMA II LABORATUVAR UYGULAMALARI. 3Hafta

WebInstaller. 1. Kurulum Đçin Gereksinimler

Üst düzey dillerden biri ile yazılmış olan bir programı, makine diline çeviren programa derleyici denir. C++ da böyle bir derleyicidir.

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Sınav tarihi : Süre : 60 dak.

Ders 8: Metotlar. barisgokce.com

HSancak Nesne Tabanlı Programlama I Ders Notları

C PROGRAMLAMA DİLİNE GİRİŞ

Internet Programming II

C# Programlama Dili. İlk programımız Tür dönüşümü Yorum ekleme Operatörler

Programlama Dili Prensipleri. Lab Notları 4

Microsoft Excel. Çalışma Alanı. Hızlı Erişim Çubuğu Sekmeler Başlık Formül Çubuğu. Ad Kutusu. Sütunlar. Satırlar. Hücre. Kaydırma Çubukları

Javascript. 1) Notepad++ aşağıdaki kodları yazıp deneme.html olarak kaydedelim. 2) Biraz önceki sayfa sadece html kodların içeriyordu.

Genel Kullanılış 1: [değişken ismi] = [değişken ismi] [işlem] [sayı veya string ifade veya değişken]

Yrd. Doç. Dr. Caner ÖZCAN

INTEGER OVERFLOW ***************************************************************/

PROGRAMLAMAYA GİRİŞ DERS 2

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

FONKSİYONLAR. Gerçek hayattaki problemlerin çözümü için geliştirilen programlar çok büyük boyutlardadır.

Fonksiyonlar (Altprogram)

Bilgisayar Teknolojileri Bölümü Bilgisayar Programcılığı Programı. Öğr. Gör. Cansu AYVAZ GÜVEN

HSancak Nesne Tabanlı Programlama I Ders Notları

B02.6 Karar Verme, Eşitlik ve Bağıntı Operatörleri

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0

Döngü (Loop) Deyimleri / Veri Belirleyicileri / Matematiksel Fonksiyonlar

8. İŞARETCİLER (POINTERS)

MTK467 Nesneye Yönelik Programlama. Hafta 4 - Döngüler Zümra Kavafoğlu

Bigisayar Programlama

BİLGİSAYAR TEMELLERİ VE PROGRAMLAMAYA GİRİŞ

Ders Tanıtım Sunumu. Internet Programming II. Elbistan Meslek Yüksek Okulu Bahar Yarıyılı. Öğr. Gör. Murat KEÇECİOĞLU 1

Yrd. Doç. Dr. Caner ÖZCAN

Diziler (Arrays) Çok Boyutlu Diziler

Dr. Fatih AY Tel:

/ C Bilgisayar Programlama Yıliçi Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

GENEL GĐRĐŞ-ÇIKIŞ FONKSĐYONLARI. ENF102 Jeoloji 1. #include <stdio.h> printf Fonksiyonu ÖRNEK. printf

NESNEYE YÖNELİK PROGRAMLAMA

Önemli noktalar. Paradigma Nesnelere Giriş Mesajlar / Ara bağlantılar Bilgi Gizleme (Information Hiding ) Sınıflar(Classes) Kalıtım/Inheritance

BTEP243 Ders 3. class Yazım Kuralı:

for döngüsü for (başlangıç değeri; şart; artım) ifade; for (başlangıç değeri; şart; artım) { ifadeler; }

Dr. Fatih AY Tel: fatihay@fatihay.net

Toplama işlemi için bir ikili operatör olan artı işareti aynı zamanda tekli operatör olarak da kullanılabilir.

Pointer Kavramı. Veri Yapıları

HSancak Nesne Tabanlı Programlama I Ders Notları

How to ASP Language. Elbistan Meslek Yüksek Okulu Bahar Yarıyılı. Öğr. Gör. Murat KEÇECĠOĞLU. 29 Eki. 1 Kas. 2013

ALGORİTMALAR. Turbo C Bilgisayarda Problem Çözme Adımları. Bilgisayarda Problem Çözme Adımları.

/ C Bilgisayar Programlama Final Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

BİLG Dr. Mustafa T. Babagil 1

Giris {\} /\ Suhap SAHIN Onur GÖK

BMT 101 Algoritma ve Programlama I 3. Hafta. Yük. Müh. Köksal GÜNDOĞDU 1

Bilgisayar Programlama MATLAB

BLM 112- Programlama Dilleri II. Hafta 5 İşaretçiler (Pointers)

Linux Assembly Programlamaya Giriş

Lambda İfadeleri (Lambda Expressions)

Karakter katarları ile ilgili fonksiyonlar içerir Yerel kayan noktalı sayılar tanımlanır

C PROGRAMLAMA D İ L İ

Akış Kontrol Mekanizmaları

Genel Programlama II

11- FONKSİYONLAR (FUNCTIONS)

MAK 1005 Bilgisayar Programlamaya Giriş. Fonksiyonlar. Prof. Dr. Necmettin Kaya

KONTROL YAPILARI JAVADA UC TURLU KONTROL YAPISI VARDIR BUNLAR İF ELSE İF ELSE İF SWİTCH YAPILARIDIR. IF ELSE YAPISI if (deger) { }else {

Algoritmalar ve Programlama. Algoritma

Nesne Tabanlı Programlama Dersi Edirne Kız Teknik ve Meslek Lisesi

void setup() fonksiyonu: Bu fonksiyon program ilk açıldığında bir kere çalışır ve gerekli kalibrasyon, setup komutlarını buraya yazarız.

Pythonda değişkenlerin türlerini tanımlamaya gerek yoktur

ALGORİTMA VE PROGRAMLAMA II

Bilgisayarda Programlama. Temel Kavramlar

Yazılım Kodlama ve İ simlendirme Standartları v1.0

C PROGRAMLAMA D İ L İ

VERİ TABANI ve YÖNETİMİ

C Programlama Dilinde Değişkenler

Print Komutu ile Değişkenleri Yazdırmak

Java 2 Standart Edition SDK Kurulum ve Java ya Giriş

BİL-142 Bilgisayar Programlama II

7- Turbo Pascal Programlamada Alt Programlar (Procedure)

Sınav tarihi : Süre : 60 dak. c) En başta #include<stdio.h> yazılmamıştır. c) zt d) Pi e) X0

Bölüm 2 - C ile Programlamaya Giriş

Temel Giriş/Çıkış Fonksiyonları

LABORATUVAR ÇALIŞMASI 1 - Python a Giriş

Bölüm 9. Altprogramlar ISBN

C++ Dersi: Nesne Tabanlı Programlama

ÜNİTE 9 ÜNİTE 9 MICROSOFT EXCEL - II TEMEL BİLGİ TEKNOLOJİLERİ İÇİNDEKİLER HEDEFLER

Transkript:

FONKSİYONLAR Fonksiyon, programcı tarafından seçilen bir kod bloğuna isim vermek için kullanılan araçtır. Fonksiyon ismi program içerisinde çağrıldığında fonksiyonun temsil ettiği kod çalıştırılır. Örneğin bir sayının faktöriyelini hesaplayan aşağıdaki kod parçasını program içerisinde birçok defa yazmak yerine aynı işlemi gerçekleştiren bir fonksiyon tasarlayıp faktöriyel hesabına ihtiyaç duyulduğunda sadece bu fonksiyonun ismini yazmak çok daha pratik olacaktır. int sayi = 5; int faktoriyel = 1; for(int i=5;i>0;i--) faktoriyel*=i; Faktöriyel Hesabı Faktöriyel Fonksiyonu İlk programımızda main fonksiyonunu yazarak aslında ilk fonksiyonumuzu da tasarlamış olduk. Tabi ki bu fonksiyonu biz değil işletim sisteminin kendisi çağırmaktadır. Yukarıdaki tasarladığımız fonksiyonu ise biz veya fonksiyonumuzu verdiğimiz başka bir programcı çağıracaktır. Aşağıdaki kod bloğunda faktöriyel fonksiyonunun çağrılıp elde edilen değerin bir değişkene atılması gösterilmektedir. int main() int sayi = faktoriyel(5); Faktöriyel fonksiyonu kullanılırken öncelikle çağrılacak olan fonksiyonun ismi yazılır ardından derleyiciye yazılan ismin bir fonksiyona ait olduğunu belirten sol parantez ( karakteri yazılır (Bu karakteri gören derleyici faktoriyel isminin bir değişkene değil de bir fonksiyona ait olduğunu anlamaktadır). Eğer ki fonksiyon yapacağı hesaplama için bir veya birden fazla değeri çağırandan bekliyor ise sol ve sağ parantezler arasına bu değerler girilmelidir. faktoriyel fonksiyonu hangi sayının faktöriyelini alacağını, çağıranın (biz) buraya girdiği değerden almaktadır. Fonksiyonun dışardan aldığı bu değerlere parametre adı verilmektedir. Yukarıdaki örnekte faktöriyel fonksiyonuna parametre olarak 5 değeri girilmiştir.

YAZIM KURALI (SYNTAX) C/C++ dillerinde fonksiyon yazım kuralı aşağıdaki gibidir. Dönüş Türü Fonksiyon İsmi Türü Parametreler int faktoriyel (int sayi) Gövde DÖNÜġ TÜRÜ Fonksiyonları çağıran kişiye çağıran (caller) veya istemci(client) adı verilmektedir. Örneğin aşağıdaki kod parçası ile biz çağıran olarak faktoriyel fonksiyonundan 5 sayısının faktöriyelini hesaplamasını istiyoruz. Fonksiyon çağrıldıktan sonra gerekli işlemleri yapıp faktöriyel işleminin sonucunu bulmaktadır. Bulunan sonuçtan çağıranın da haberdar olması için fonksiyon elde ettiği değeri return komutu ile çağırana getirmektedir. Bu işleme değer döndürmek adı verilir. Fonksiyon tanımlanırken ilk olarak döndüreceği değerin türü belirtilmelidir. Faktöriyel fonksiyonu tam sayı bir sonuç elde edeceğinden fonksiyonun dönüş türü de tam sayı olacaktır. Fonksiyonlar çalışmaya başladıktan sonra işlettiği ilk return komutu ile dönüş yapmaktadır. Aşağıdaki return komutu fonksiyonun son satırında yer almaktadır fakat kimi durumlarda bu komutun yeri değişebilir. int main() int sonuc = faktoriyel(5); int main() int sonuc = 120; Fonksiyon bulduğu sonucu çağırana döndürür

FONKSĠYON ĠSMĠ Fonksiyon ismi yazılırken değişken ismi kuralları aynen geçerlidir. Fonksiyon isimleri içerisinde sadece İngilizce karakterler kullanılmalıdır. Türkçe karakterler farklı derleyici ve sistemlerde problem çıkartabilir. Bu sebeple kesinlikle Türkçe karakter kullanılmamalıdır. Fonksiyon ismi yaptığı iş hakkında bilgi verecek şekilde seçilmelidir. İsmin başlangıç harfi kimi sistemlerde küçük iken Windows gibi sistemlerde büyük harfle başlamaktadır. Bu seçim programcıya aittir. Mühim olan yapılan seçime program boyunca uyulmasıdır. Ayrıca fonksiyon ismindeki her kelimenin ilk harfi büyük diğer harfleri küçük olmalıdır. int F (int sayi) HATALI DOĞRU int s(int sayi) int karekokbul(int sayi) HATALI DOĞRU Fonksiyon ismi ile aynı isme sahip değişken tanımlanmamalıdır. Örneğin aşağıdaki kodda, faktoriyel ismi öncelikle bir fonksiyon olarak tanımlanırken daha sonra bir tam sayı değişkeni için kullanılmıştır. Bu işlemin ardından faktoriyel ismi ile bir fonksiyon çağrısı yapılmıştır. Fakat derleyici isim ezme kurallarını dikkate aldığı için faktoriyel ismini bir tam sayı değişken olarak algılar ve fonksiyon çağrısı yapılamayacağını belirten bir hata verir. İkinci durumda ise tam sayı değişkeni fonksiyon çağrısından sonra tanımlandığı için derleyici faktöriyel isminin bir fonksiyona ait olduğunu bilir ve bir hata görmez ve kodu derler. Sağdaki kod çalışmasına rağmen pratik açıdan büyük problemler doğurabilir. Fonksiyon isimleri ile değişken isimleri asla karıştırılmamalıdır. int main() int faktoriyel = 7; int sayi = faktoriyel(5); int main() int sayi = faktoriyel(5); int faktoriyel = 7;

PARAMETRELER Fonksiyonlar yapacakları işlemler için kullanıcıdan bilgi isteyebilirler. Örneğin faktöriyel fonksiyonu hangi sayının faktöriyelinin alınacağını çağırandan(yani programcıdan) parametre olarak beklemektedir. Fonksiyon tanımlanırken dışarıdan beklenen değerler göz önünde bulundurulmalı ve parametreler buna göre yazılmalıdır. Örneğin bir sayının üstünü alan fonksiyon tasarlamak istersek kullanıcıdan iki değer almamız gerekir. İlk parametre üstü alınacak sayı iken diğer parametre üst değeri olmalıdır. Aşağıda üst alan bir fonksiyon verilmiştir. Fonksiyon iki parametre alacak şekilde tasarlanmıştır. Eğer dikkat ederseniz fonksiyonun gövdesinde alınan parametreler kullanılmaktadır. Fonksiyonu çağıran kişi iki parametre değeri girmek zorundadır yoksa derleyici hata verecektir. Çağrı yapılırken arka planda derleyici fonksiyonun tasarımına bakar ve fonksiyon çağırmak için gereken makine kodlarını oluşturur. Eğer fonksiyonu çağırırken eksik parametre girerseniz iki parametre almak üzere yazılmış olan makine kodları da yanlış sonuçlar verecektir. Bu yüzden derleyici parametre sayısı konusunda hata kabul etmez. int ustal(int taban,int ust) for(int i=0;i<ust;i++) sonuc*=taban; int main(int argc,char** argv) int sayi = ustal(2,4); Doğru Çağrı int ustal(int taban,int ust) for(int i=0;i<ust;i++) sonuc*=taban; int main(int argc,char** argv) int sayi = ustal(2); Hatalı Çağrı Birden fazla parametre alan fonksiyon tasarlanırken parametreleri ayırmak için virgül kullanılmaktadır. Aynı şekilde fonksiyonu çağırırken de yine virgül kullanılır. Ayrıca fonksiyonun alacağı parametreler yazılırken değişken tanımlama kurallarına aynen riayet edilmelidir. Parametreler fonksiyona ait yerel değişkenlerdir. Ömürleri fonksiyon çağrılırken başlar ve fonksiyon geri döndükten sonra sona erer. Parametre değişkenlerin etki alanı sadece tanımlandıkları fonksiyon gövdesi ile sınırlıdır. Örneğin yukarıdaki örnekte taban parametresi main fonksiyonu içerisinde bir anlam ifade etmemektedir. Parametrelere daha önceden tanımlanmış değişkenler girildiğinde değişkenin sadece değeri fonksiyona yollanır. Aşağıdaki örneğe bakacak olursak a ve b değişkenleri fonksiyona parametre olarak verilmektedir. Fonksiyon çağrısı yapılmadan önce değişkenlerin değerleri hafızadan çekilip fonksiyona parametre olarak verilmektedir. int main(int argc,char** argv) int a=2,b=4; int sayi = ustal(a,b); int sayi = ustal(2,4);

GÖVDE Fonksiyon gövdesi simgesinin hemen ardından başlar ve simgesi ile sona erer. Fonksiyonu bitirmenin bir diğer yolu ise return komutunu kullanmaktadır. return komutu fonksiyonun çağrıldığı noktaya geri dönmesini sağlar. Fonksiyon çağrısı işlemcinin izlediği yolu değiştirmesine neden olmaktadır. Fonksiyon bittiğinde ise çağrının yapıldığı noktadan yolunda devam etmesi gerekir. Yazılan bütün programların bir başlangıç noktasına ihtiyacı vardır bizim programımızın ki ise main fonksiyonu dur. Bu fonksiyon işletim sistemi tarafından çağrılır ve işlemci fonksiyon içerisindeki komutları sıra ile işletir. Örneğin aşağıdaki kod bloğunda ilk önce 10. Satır çalıştırılmaktadır. Fakat bu satırdaki işlemin tamamlanabilmesi için ustal fonksiyonunun (2, 4 parametreleri ile) çağrılması gerekmektedir. Bu yüzden işlemci çalışma akışını değiştirip 3.satıra atlar ve buradan sıra ile komut satırlarını işletir. İşlemci 7. Satıra geldiğinde return komutu ile karşılaşır ve fonksiyon çağrılmadan önceki noktaya yani 10. satıra (dönüş değeri sonuc ile) geri döner. sayi değişkenine ustal fonksiyonundan gelen değer (8) atandıktan sonra işlemci 11.satırı işletir ve program sona erer. 1. int ustal(int taban,int ust) 2. 3. 4. for(int i=0;i<ust;i++) 5. sonuc*=taban; 6. 7. 8. int main(int argc,char** argv) 9. 10. int sayi = ustal(2,4); 11. cout<<"sayi...:"<<sayi<<endl; 12. return komutu fonksiyonun son satırından daha öncede kullanılabilir. Örneğin aşağıdaki fonksiyon, parametrelerinden birisinin 0 olması durumunda hemen sonlanıp geriye 0 değeri döndürmektedir. Dikkat edersek bu mantıklı bir istek çünkü 0 sayısının bütün üstleri yine 0 olacaktır. Bu durumda program çalıştırılırsa öncelikle12.satırda ustal fonksiyonu çağrılacak ve işlemci buradan yönünü değiştirip 3. Satırdaki koşulu çalıştıracaktır. Koşul sonucu doğru olduğu için return 0 komutu devreye girer ve işlemci fonksiyonun çağrıldığı noktaya yani 12. Satıra dönüş değeri ile geri döner. 1. int ustal(int taban,int ust) 2. 3. if(taban==0) 4. return 0; 5. 6. for(int i=0;i<ust;i++) 7. sonuc*=taban; 8. 9. 10. int main(int argc,char** argv) 11. 12. int sayi = ustal(0,4); 13. cout<<"sayi...:"<<sayi<<endl; 14.

DÖNÜġ DEĞERĠ OLMAYAN FONKSĠYONLAR Fonksiyonlar işleri bittikten sonra çağrıldıkları noktaya geri dönerler. Fakat kimi fonksiyonlar geri dönerken bir değer getirmezler. Bu fonksiyonların dönüş değerleri void olmalıdır. Örneğin programınız içerisinde ekrana * simgelerinden oluşan bir şekil çizdirmek istiyorsunuz. Bu işlemi gerçekleştirecek kodları sürekli yazmak yerine fonksiyon kullanmak istiyorsunuz. Fonksiyonunuz sadece ekrana yazı çıkartacak ve size bir değer getirmeyecektir. Bu durumda fonksiyonun dönüş değerini void yazmak çok daha mantıklı olacaktır. 1. void yildiz() 2. 3. for(int i=0;i<10;i++) 4. cout<<"*"; 5. 6. int main(int argc,char** argv) 7. 8. yildiz(); 9. 10. Değer getirmemesi fonksiyonun dönmediği anlamına gelmez. Yukarıdaki yildiz fonksiyonunda return ifadesi yer almamaktadır. Bu yüzden fonksiyon, son satırına kadar işletilecek ve ardından (diğer bütün fonksiyonlarda olduğu gibi) çağrıldığı noktaya geri dönecektir. Dönüş değeri olmamasına rağmen void fonksiyonlarda return komutu kullanılabilir. Aşağıdaki fonksiyona dikkat edecek olursanız 3.satır da return komutu kullanılmış fakat sağında bir değer bulunmuyor. Bunun anlamı fonksiyon 3.satırda çağrıldığı noktaya dönüş yapıyor fakat bir değer getirmiyor. Fonksiyonumuz çağrıldığı gibi geri döndüğü için 4 ve 5. Satırı hiçbir zaman işletemeyecektir. 1. void yildiz() 2. 3. return; 4. for(int i=0;i<10;i++) 5. cout<<"*"; 6. 7. int main(int argc,char** argv) 8. 9. yildiz(); 10. 11. yildiz fonksiyonu ile ilgili bir özellikte parametresinin olmamasıdır.

Fonksiyonların ĠĢleyiĢi Fonksiyonlar çağrıldığında işlemci kodu işletme sırasını değiştirip farklı satırlardaki komutları çalıştırmaya başlayacaktır. Örneğin aşağıdaki kodun 12.satırında ustal fonksiyonu çağrıldığında işlemci artık main fonksiyonunda devam etmeyip 3.satırdaki kodları işletmeye başlar. main fonksiyonu ustal fonksiyonu geri dönene kadar beklemede kalacaktır. Bu teknik bütün programlama dillerinde mevcuttur. Bir fonksiyonu daima başka bir fonksiyon çağıracaktır. Çağıran fonksiyon çağrılan fonksiyon işini bitirene kadar beklemede kalır. 1. int ustal(int taban,int ust) 2. 3. cout<<"ustal calisti"<<endl; 4. 5. 6. for(int i=0;i<ust;i++) 7. sonuc*=taban; 8. 9. 10. int main(int argc,char** argv) 11. 12. int sayi = ustal(0,4); 13. cout<<"main devam ediyor"<<endl; 14. EKRAN ÇIKTISI main fonksiyonunun işleyişi aşağıdaki şekilde gösterilmiştir. Şekilden de görüleceği gibi ustal fonksiyonu çağrıldıktan sonra main fonksiyonu ustal fonksiyonun bitmesini beklemektedir. ustal döndükten sonra main yoluna devam etmektedir.

DEĞER ĠLE ÇAĞIRMA ( call by value) Fonksiyon parametrelerinin de birer değişken olduğundan bahsetmiştik. Ayrıca değişkenler konusu sayesinde değişkenlerin tanımlandıkları etki alanları içerisinde var olduklarını biliyoruz. Buna göre aşağıda ki degistir fonksiyonunun a ve b değişkenlerinden haberi yoktur. Fonksiyona sadece a ve b değişkenlerinin sahip olduğu değerler verilir. Aşağıda degistir fonksiyonu çağrılmadan önceki hafızanın sembolik bir görüntüsü verilmiştir. 1. void degistir(int sayi1,int sayi2) 2. 3. int temp = sayi1; 4. sayi1= sayi2; 5. sayi2 = temp; 6. 7. int main(int argc,char** argv) 8. 9. int a=2,b=4; 10. degistir(a,b); 11. cout<<a<<b; 12. Değişken Adı Hafıza Hücre İçeriği a 2 b 4 Fonksiyon çağrıldıktan sonraki hafıza görüntüsü de aşağıda verilmiştir. degistir fonksiyonuna ait olan sayi1 ve sayi2 değişkenleri, a ve b değişkenlerinin sadece değerlerini almıştır. Fonksiyon a ve b değişkenlerinin varlığından habersizdir. Dolayısıyla onları manipüle edemez. 1. void degistir(int sayi1,int sayi2) 2. 3. int temp = sayi1; 4. sayi1= sayi2; 5. sayi2 = temp; 6. 7. int main(int argc,char** argv) 8. 9. int a=2,b=4; 10. degistir(a,b); 11. cout<<a<<b; 12. Değişken Hafıza Hücre Adı İçeriği a 2 b 4 sayi1 2 sayi2 4 Aslında fonksiyona parametre olarak bir değişken verilirken sadece değişkenin değeri alınmaktadır. Alınan bu değerler aşağıdaki gibi fonksiyonun sayi1 ve sayi2 değişkenlerine ilk değer olarak atanmaktadır. (aşağıdaki işlem sadece bir gösterimdir) 1. void degistir(int sayi1 = 2,int sayi2 =4 ) 2. 3. int temp = sayi1; 4. sayi1= sayi2; 5. sayi2 = temp; 6. 7. int main(int argc,char** argv) 8. 9. int a=2,b=4; 10. degistir(a,b); 11.

Ön Tanımlama ( Forward Decleration) Fonksiyon çağrısının da makine kodu karşılığı mevcuttur. Fakat çağrı yapılmadan önce de bazı hazırlık işlemlerinin yine makine kodu ile yapılması gerekir. Derleyicinin bütün bu işleri doğru şekilde yapabilmesi için çağrılacak fonksiyonun dönüş değeri, ismi ve parametre bilgilerini çağrıdan önce bilmesi gerekir. Aşağıda degistir fonksiyonun çağrısına karşılık gelen makine kodları gösterilmektedir. 5.satırdaki call komutu fonksiyonu çağıran asıl makine komutudur. Önceki satırdaki makine komutları fonksiyon çağrısına yapılan hazırlıktır. 1. void degistir(int sayi1,int sayi2) 2. 3. int temp = sayi1; 4. sayi1= sayi2; 5. sayi2 = temp; 6. 7. int main(int argc,char** argv) 8. 9. int a=2,b=4; 10. degistir(a,b); 11. 1. mov eax,dword ptr [b] 2. push eax 3. mov ecx,dword ptr [a] 4. ecx 5. call ustal (2111C7h) Programımız tek bir dosyadan ibaret olduğundan şu ana kadarki fonksiyon tanımlama yöntemi bir problem teşkil etmeyecektir. Fakat büyük projelerde birçok dosya olması kaçınılmazdır. Bugüne kadarki programlarımızda daima bir kütüphane eklediğimizi düşünürsek aslında bizim projelerimizde birden fazla dosya ile çalışmaktadır. Dolayısıyla fonksiyonlar farklı dosyalarda bulunabilir. Bu fonksiyonları çağırmak için derleyicinin fonksiyona ait dönüş türü, fonksiyon ismi ve parametre bilgilerine ihtiyaç duyacaktır. Bu bilgiler fonksiyon çağrılmadan önce derleyiciye verilmelidir. C++ programlama dili gövdesi farklı yerde bulunan fonksiyonların çağrılmasına imkân tanıyan ön tanımlama (forward decleration) adı verilen bir mekanizmaya sahiptir. Aşağı solda bulunan kod parçasını incelersek degistir fonksiyonunun gövdesinin çağrıldıktan sonra tanımlandığını göreceğiz. C++ derleyicisi bu durumda bizlere değiştir fonksiyonun tanımlı olmadığını söyleyecektir(fonksiyon farklı bir dosyada da olabilirdi). Derleyici, çağrı yapılmadan önce fonksiyonu göremediği için hata vermektedir. Bu problemin çözümü fonksiyonun ön tanımlamasını çağrılmadan önce yapmaktır. Fonksiyonun ön tanımlamasına prototip adı da verilmektedir. int main(int argc,char** argv) int a=2,b=4; degistir(a,b); cout<<a<<b; void degistir(int sayi1,int sayi2) int temp = sayi1; sayi1= sayi2; sayi2 = temp; Hatalı Çağrı void degistir(int sayi1,int sayi2); int main(int argc,char** argv) int a=2,b=4; degistir(a,b); cout<<a<<b; void degistir(int sayi1,int sayi2) int temp = sayi1; sayi1= sayi2; sayi2 = temp; Doğru Çağrı

Kendini Çağıran Fonksiyonlar (Öz Yineleme) Kimi problemler aynı işlemin farklı değerler ile sürekli yapılmasıyla elde edilebilir. Bu tip durumlar da şuana kadar döngüleri kullanmaya çalıştık. Fonksiyonlar sayesinde farklı bir çözüm daha üretebiliyoruz. Örneğin aşağıdaki faktöriyel hesabı yapan fonksiyonu öz yinelemeli olarak çözümü gösterilmektedir. int main() int faktoriyel = 7; int sayi = faktoriyel(5); if(sayi==1) return 1; return sayi*faktoriyel(sayi-1); int main() int sayi = faktoriyel(5); faktoriyel fonksiyonu 5 değeri ile çağrıldığında gerçekleşen işlemler aşağıdaki gibidir. Fonksiyon ilk olarak parametrenin 1 olup olmadığını kontrol ediyor. Ardından bu fonksiyon içerisinde faktoriyel fonksiyonu 4 değeri ile yeniden çağrılıyor. Aynı işlem şekilde de görüldüğü üzere parametre 1 olana kadar devam etmektedir. Ardından faktoriyel(1) fonksiyonu faktoriyel (2) fonksiyonuna 1 değerini döndürür. faktoriyel (2) fonksiyonu bu değeri 2 ile çarpıp sonucu faktoriyel (3) fonksiyonuna döndürür. Bu işlem faktoriyel (5) fonksiyonuna kadar devam eder. faktoriyel(5) fonksiyonu kendisine dönen değeri 5 ile çarpıp sonucu ilk çağrıyı yapana döndürecektir. int sayi = faktoriyel(5); //faktoriyel(4) için int faktoriyel(4) if(4==1) return 1; return 4*faktoriyel(3); //faktoriyel(2) için int faktoriyel(2) if(2==1) return 1; return 2*faktoriyel(1); //faktoriyel(5) için int faktoriyel(5) if(5==1) return 1; return 5*faktoriyel(4); //faktoriyel(3) için int faktoriyel(3) if(3==1) return 1; return 3*faktoriyel(2); //faktoriyel(1) için int faktoriyel(1) if(1==1) return 1;

Aşağıdaki şekle dikkat edecek olursak fonksiyonlar parametre değerini bir azaltarak sürekli aynı fonksiyonu çağırıyorlar. Taki faktoriyel(1) fonksiyonu çağrılana dek. Parametre 1 olduğunda fonksiyon kendisini çağırmayı kesip 1 değerini geri döndürmektedir. Bu bir döngünün bitiş koşuluna benzer. Öz yineleme işlemininde de bir sona ihtiyacı vardır. Aksi taktirde sonsuz bir fonksiyon çağrısı programımızın hata (stack overflow) verip sonlanmasına sebep olacaktır. Dikkat etmemiz gereken bir hususta faktoriyel(2) fonksiyonunun faktoriyel(1) fonksiyonu bitmeden yoluna devam edemeyecek olmasıdır. faktoriyel(1) fonksiyonu 1 değerini faktoriyel(2) fonksiyonuna döndürecektir. Aynı şekilde faktoriyel(2) fonksiyonu da hesapladığı sonucu faktoriyel(3) fonksiyonuna oda şekilde de görüldüğü gibi sonucu faktoriyel(4) fonksiyona döndürecektir. faktoriyel(4) fonksiyonu öz yinelemeyi başlatan faktoriyel(5) fonksiyonuna kombine sonucu döndürecektir. faktoriyel(5) fonksiyonu ise çağrıldığı noktaya döndürdüğü değeri bırakıp işlemi sonlandıracaktır. int sayi = faktoriyel(5); 5*faktoriyel(4) 4*faktoriyel(3) 3*faktoriyel(2) 2*faktoriyel(1) 1 int sayi = 120 5*24 4*6 3*2 2*1 1

Kara Kutu Tasarımı (Black box) Fonksiyonlarımızı tasarlarken onları sadece kendimiz için değil başka programcılarında kullanacağını düşünerek tasarlamalıyız. Aynı şekilde bizler de bugüne kadar başkaları tarafından tasarlanmış fonksiyonları kullandık. Örneğin pow fonksiyonu üst almaya yaramaktadır. Bu fonksiyon hakkında bildiğimiz iki parametre aldığı ve sonucu dönüş değeri olarak döndürdüğüdür. Fonksiyonun gövdesi hakkında bilgi sahibi değiliz. Bizim açımızdan pow fonksiyonu bir kara kutudan ibarettir. Bu televizyon ile kumanda arasındaki ilişkiye benzer. Televizyonun teorik olarak nasıl çalıştığını bilmiyoruz ama kumanda sayesinde onu istediğimiz gibi kullanıp sonuç alabiliyoruz. Aşağıda pow fonksiyonun çağrısı gösterilmiştir. pow fonksiyonuna yapacağı hesaplama ile ilgili bilgileri parametre yoluyla veriyoruz. Fonksiyon gerekli işlemleri yaptıktan sonra elde ettiği sonucu bize dönüş değeri olarak bildirmektedir. Binlerce programcı bu fonksiyonu bizimle aynı amaç için kullanmaktadır. Bu yüzden bir fonksiyon tasarlarken basitliğine özen gösterilmelidir. pow(2.0,3.0) pow 8 pow fonksiyonu tek ve basit bir işi gerçekleştirmektedir. Bu sayede fonksiyon herkesin isteğine karşılık verebilir. pow fonksiyon içerisine sadece bizim işimizi görecek kodlar yerleştirseydik fonksiyonu kullanacak tek kişi de biz olurduk. Örneğin tasarladığınız fonksiyonun içerisine konsola yazı yazdırmak gibi işlemler yapılmamalıdır. Fonksiyon Gövdesinin Büyüklüğü Fonksiyonlar tasarlanırken gövdesi olabildiğince küçük tutulmalıdır. Bunu sağlayabilmek için yazdığımız fonksiyonun tek bir görevi gerçekleştirmesini sağlamalıyız. Örneğin e sayısını hesaplayacak bir fonksiyon tasarlamak isteyelim. e sayısını elde edeceğimiz seri aşağıdaki gibi olduğuna göre bu işlemi gerçekleştirecek fonksiyonda sağdaki gibi olacaktır. float ehesapla(int sinir) float sonuc = 0; for(int i=0;i<sinir;i++) int faktoriyel = 1; for(int j=i;j>0;j--) faktoriyel*=j; sonuc+=1.0f/faktoriyel; Eğer ehesapla fonksiyonuna dikkat edecek olursak iki işlemi bir arada yapmaktadır. İçerdeki döngü faktöriyel işlemi yapmaktadır. Bu işlem için ayrı bir fonksiyon tasarlayabiliriz.

float ehesapla(int sinir) float sonuc = 0; for(int i=0;i<sinir;i++) sonuc+=1.0f/ faktoriyel(i); Faktöriyel işlemi ayrı bir fonksiyon ile elde edildiğinden ehesapla fonksiyonunun gövdesi daha basit bir hale geldi. Ayrıca ehesapla fonksiyonunda oluşacak hatalar fonksiyon gövdesi küçük olduğundan çok daha kolay bulunacaktır. Programcılık hayatınız boyunca oluşturacağınız fonksiyon gövdelerinin küçük olmasına dikkat edin. Büyük gövdeye sahip olan bir fonksiyonda çıkacak bir hatayı bulmak çok zor olacaktır. Hâlbuki gövde küçük olduğunda hatayı bulmakta kolay olacaktır. Fonksiyon Dokümantasyonu Programcı olarak yazdığımız kodların daima bir program üreteceğini düşünmemeliyiz. Kimi zaman programcıların görevi başka programcılara yardımcı olacak kütüphaneleri tasarlamak olabilir. Bu durumda sonuçta tek başına çalışılabilecek bir ürün elde edilmez. Ayrıca yazdığımız fonksiyonları başka programcılar kullanacağından fonksiyonların kullanımı ve davranışları hakkında bilgi verilmesi gerekir. Genellikle bu bilgiler fonksiyon isminin üzerinde yer alır. /* Bir sayının istenen üstünü hesaplar. @Param taban üstü alınacak olan sayı @Param ust tabanın alınacak üst değeri. Negatif girilmemelidir. @return ust alma işleminin sonucu döndürülür. */ int ustal(int taban,int ust) for(int i=0;i<ust;i++) sonuc*=taban; Yazdığımız her fonksiyon için yukarıda olduğu gibi bir yorum bloğu eklemeliyiz. Bu sadece başka programcılar için değil kendimiz içinde faydalı olacaktır. Yorum stiliniz yukarıdaki ile birebir olmak zorunda değildir. Fakat fonksiyonun yaptığı iş, parametreleri, dönüş değeri ve kullanımı hakkında temel bilgiler yazılması şarttır.

Fonksiyon AĢırı Yükleme Programcılık hayatımızda aynı işlemin farklı türde parametreler için yapılması gerektiğini göreceğiz. Örneğin üst alma işlemi tam sayılar üzerinde çalıştığı gibi ondalık sayılar üzerinde çalışmasını da istiyoruz. Yapılacak işlem yine üst alma işlemi fakat parametreler farklıdır. C++ dili bu tip durumlar için fonksiyon aşırı yükleme adı verilen bir tekniğe sahiptir. Bu teknikte ismi aynı olan farklı fonksiyonlar tasarlayabilmekteyiz. Aşağıda iki farklı ustal isminde fonksiyon tanımlanmıştır. int ustal(int taban,int ust) for(int i=0;i<ust;i++) sonuc*=taban; float ustal(float taban,float ust) float sonuc = 1; for(int i=0;i<ust;i++) sonuc*=taban; int main(int argc,char** argv) cout<< ustal(2.4f,4.0f)<<endl; cout<< ustal(2,4)<<endl; EKRAN ÇIKTISI Yukarıdaki koda dikkat edecek olursak ustal fonksiyonu iki tanedir. Derleyici hangi fonksiyonun çağrılacağına, programcının fonksiyona girdiği parametrelerden karar vermektedir. main fonksiyonundaki ilk ustal(2.4f,4.0f) çağrısı derleyiciye parametreleri iki float olan ustal fonksiyonunun çağrılacağını belirtmektedir. main deki ikinci çağrı da ise parametreler iki tam sayıdır. Bu da derleyiciye çağrılacak fonksiyonun iki tane tam sayı olacağını belirtir. Bir fonksiyonu aşırı yükleyebilmek için parametre sayısının veya türlerinin değiştirmesi gerekir. Parametre sayısı arttırılabilir veya azaltılabilir. Mühim olan parametrelerin farklı olmasıdır. Aşırı yükleme için sadece dönüş değerlerinin farklı olması yeterli değildir. Derleyici hangi fonksiyonun çağrılacağına parametreler üzerinden karar verir. Fonksiyon isimleri aynı olması fonksiyonların aynı olduğu anlamına gelmez. Aslında iki farklı fonksiyon olmasına rağmen derleyici bizlere aynı ismi verme kolaylığı sağlamıştır. Aşağıdaki şekilde aşırı yüklenmiş fonksiyonların bizim tarafımızdan görünüşü ile derleyici tarafından görünüşleri verilmiştir. Biz float parametreli ustal fonksiyonunu çağırdığımızda derleyici bizim hangi fonksiyonu istediğimizi anlıyor ve ona göre asıl fonksiyonu çağırıyor. int ustal(int taban,int ust) int ustal_int_int(int taban,int ust) float ustal(float taban,float ust) int ustal_float_float(float taban,float ust) Bizim Gördüğümüz Derleyicinin Gördüğü