bim104-sunum3

Download Report

Transcript bim104-sunum3

BM-104
Nesneye Yönelik Programlama
Bahar 2013
(3. Sunu)
(Yrd. Doç. Dr. Deniz Dal)
Fonksiyonlara Giriş
 En iyi program yazma ve geliştirme pratiği tek bir
büyük program yazmak yerine onu daha kolay
kontrol altında tutmamıza yardımcı olabilecek küçük
programların (fonksiyonların) birleşimi halinde
oluşturmaktır. Bu yönteme “Böl&Yönet”
(“Divide&Conquer”) adı verilir.
 Bir fonksiyon gerektiğinde fonksiyon adı ile çağrılır
ve fonksiyonun işleyeceği bilgiler argüman
(parametre) olarak fonksiyona aktarılır. Örneğin bir
patron (fonksiyonu çağıran) bir çalışanını (çağrılan
fonksiyon) yanına çağırır ve doldurması için eline bir
dosya verir (argüman). Çalışanı işini bitirdiği zaman
işlenmiş dosyayı patronuna geri götürür (return).
Matematik Kütüphanesi Fonksiyonları
 Bu fonksiyonlar standart kütüphaneden <cmath>
header dosyası include edilerek kullanılabilir.
 Matematik kütüphanesinin bütün fonksiyonları
genellikle double veri tipinde parametre(ler) alırlar ve
geriye double veri tipinde bir değer döndürürler.
 Örnek: cout<<sqrt(900.0);
 Bu örnekte matematik kütüphanesi
fonksiyonlarından “sqrt” çağrılır. “900.0” rakamı bu
fonksiyonun argümanı olarak adlandırılır. Yukarıdaki
deyim ekrana sonuç olarak “30.0” yazdırır. “sqrt”
fonksiyonu kendisine double veri tipinde bir argüman
alır ve yine double veri tipinde bir değer döndürür.
 Fonksiyon argümanları sabit bir sayı, değişken ya
da bunların bir karması olabilir.
Matematik Kütüphanesi Fonksiyonları
FONKSİYON
TANIM
ÖRNEK
ceil( x )
x argümanını kendinden büyük ilk
tamsayıya yuvarlar. (artı sonsuz)
ceil( 9.2 ) is 10.0
ceil( -9.8 ) is -9.0
cos( x )
Radyan cinsinden x argümanına
kosinüs fonksiyonunu uygular.
cos( 0.0 ) is 1.0
exp( x )
Exponansiyel Fonksiyon ex
exp( 1.0 ) is 2.71828
exp( 2.0 ) is 7.38906
fabs( x )
x argümanının mutlak değerini
hesaplar.
fabs( 5.1 ) is 5.1
fabs( 0.0 ) is 0.0
fabs( -8.76 ) is 8.76
floor( x )
x argümanını kendinden küçük ilk
tamsayıya yuvarlar. (eksi sonsuz)
floor( 9.2 ) is 9.0
floor( -9.8 ) is -10.0
fmod( x, y )
x sayısının y sayısına bölümünden
kalan ondalıklı sayıyı hesaplar.
fmod( 2.6, 1.2 ) is 0.2
log( x )
Doğal logaritma hesaplar. (e
tabanında)
log( 2.718282 ) is 1.0
log( 7.389056 ) is 2.0
log10( x )
10 tabanında logaritma hesaplar.
log10( 10.0 ) is 1.0
log10( 100.0 ) is 2.0
pow( x, y )
x argümanının y. kuvvetini
hesaplar.xy
Radyan cinsinden x argümanına sinüs
fonksiyonunu uygular.
pow( 2.0, 7.0 ) is 128
pow( 9, 0.5 ) is 3
Pozitif x argümanının karekökünü
hesaplar.
Radyan cinsinden x argümanına
tanjant fonksiyonunu uygular.
sqrt( 9.0 ) is 3.0
sin( x )
sqrt( x )
tan( x )
sin( 0.0 ) is 0
tan( 0.0 ) is 0
Örnek: pow Fonksiyonu
Fonksiyonlar Nasıl Çağrılırlar?
Fonksiyon Formatı
“döndürülen veri tipi” “FonksiyonunAdı”(parametre listesi)
{
deklarasyonlar ve deyimler;
return anahtar kelimesi;
}
 Parametre listesindeki birden fazla parametre birbirlerinden
virgül ile ayrılır. Herbir parametre fonksiyon içerisinde bir
değişken olarak kullanılacağı için bir isme ve bir veri tipine
sahiptir.
 Döndürülen veri tipi “void” ise bu fonksiyon hiçbir veri geri
döndürmez ve return anahtar kelimesi kullanılmak zorunda
değildir.
Fonksiyon Prototipi
 Fonksiyon prototipi, derleyiciye, kullanılacak fonksiyonun adını,
döndürülecek veri tipini, kaç parametre alınacağını ve tiplerini,
bu parametrelerin hangi sırada olacağını hatırlatır. Parametre
olarak kullanılan değişkenlerin isimleri prototip içine yazılmaz.
Sadece değişkenlerin veri tipleri yazılır. Eğer fonksiyon
prototipte tanımlandığı gibi çağrılmazsa derleyici hata verir.
Bütün bunlar fonksiyon kullanımını daha da kolaylaştırmak ve
yapılacak yanlışları önlemek içindir.
 Eğer fonksiyon, çağrılmadan önce tanımlanmışsa prototipe
gerek yoktur. Sonra tanımlanmışsa gerek vardır.
 Örneğin: int Maksimum(int,int,int); prototipi Maksimum adlı
fonksiyonun 3 integer parametre alacağını ve geriye yine bir
integer döndüreceğini söyler.
void Fonksiyonlar
void EkranaBas(); şeklinde tanımlı prototip EkranaBas
adlı fonksiyonun hiçbir argüman almadığını ve geriye
hiçbir değer döndürmediğini söyler bize.
Paskal Notasyonu
 Fonksiyonlar isimlendirilirken en fazla kullanılan
notasyonlardan birisi Paskal notasyonudur (pascal
notation). Bu notasyon, fonksiyon ismi birden fazla
kelime içeriyorsa ilk kelime de dahil bütün kelimelerin
ilk karakterlerinin büyük harfle yazıldığı
bir
notasyondur. KaresiniAl, AsalMi, Swap gibi.
Başlık (Header) Dosyaları
 Standart kütüphanenin her bir elemanı, bünyesinde
barındırdığı fonksiyonların prototiplerini ve tanımlarını
“başlık dosyası” olarak isimlendirdiğimiz ve “include”
deyimi ile programımızın başına eklediğimiz
dosyaların içerisinde saklar.
 Standart kütüphaneden eklediğimiz “başlık” dosyaları
< ile > karakterleri arasına konur. Kullanıcının
oluşturduğu “başlık” dosyaları ise " ile " karakterleri
arasına yerleştirilir ve uzantısı ".h" dir.
 Örnek: #include <iostream>
#include "bm104.h"
C++ Standart Kütüphanesinin Başlık Dosyaları
C++ Standard
Library Header File
Açıklama
<iostream>
Standart input ve output işlemleri için gerekli fonksiyon
prototiplerini ve tanımlarını içerir. Mesela cout ve cin
kullanabilmek için bu header dosyası gereklidir.
<iomanip>
Veriyi formatlı yazdırabilmek için gerekli fonksiyon
prototiplerini ve tanımlarını içerir. Mesela setprecision
kullanabilmek için bu header dosyası gereklidir.
<cmath>
Matematik kütüphanesinde tanımlı fonksiyonların prototiplerini
ve tanımlarını içerir. (pow, ceil veya floor gibi)
<cstdlib>
Rakamları
metinlere,
metinleri
rakamlara
çeviren
fonksiyonların ve rastgele sayı üreten fonksiyonların
prototiplerini ve tanımlarını içerir. (atoi, atof, rand veya srand
gibi)
C++ Standart Kütüphanesinin Başlık Dosyaları
C++ Standard
Library Header File
Açıklama
<ctime>
Zaman ve tarih manipülasyonu için kullanılan fonksiyonların
prototiplerini ve tanımlarını içerir. (time gibi)
<vector>,
<list>,
<deque>,
<queue>,
<stack>,
<map>,
<set>,
<bitset>
<cctype>
Bunlar C++ standart kütüphanesi içinde depolama amaçlı kullanılan
sınıfların (classes) header dosyalarıdır.
<cstring>
Karakterlere ve metin dizilerine uygulanabilecek testleri içeren
fonksiyonların prototiplerini ve tanımlarını içerir. Mesela bir
karakterin harf mi veya noktalama işareti mi olduğunu bulmamıza
yarayan bir fonksiyon bu header dosyası eklenerek kullanılabilir. (Ya
da küçük harfleri büyük harflere çeviren ya da tam tersi.) (isdigit,
islower, tolower veya toupper gibi)
C programlama dilinin stiline uygun string proses etmek için
kullanılacak fonksiyonların prototiplerini ve tanımlarını içerir. (strcpy
veya strncmp gibi)
C++ Standart Kütüphanesinin Başlık Dosyaları
C++ Standard
Library Header File
Açıklama
<fstream>
Hard diskteki bir dosyadan bilgi okuma veya dosyaya bilgi
yazma amacıyla kullanılacak fonksiyonların prototiplerini ve
tanımlarını içerir.
<string>
C++ Standart kütüphanesinde tanımlı string sınıfının (class)
tanımını içerir.
Bellekteki stringlerin okunması ve yazılması için gerekli
fonksiyonların prototiplerini ve tanımlarını içerir.
C++ Standart kütüphanesinde mevcut algoritmalara ait
sınıfların ve fonksiyonların tanımlarını içerir.
<sstream>
<functional>
C++ Standart Kütüphanesinin Başlık Dosyaları
C++ Standard Library Açıklama
Header File
<iterator>
<algorithm>
C++ kütüphanesindeki depolayıcıların içindeki
verilere ulaşmak için gerekli sınıf tanımlamalarını
içerir.
C++ kütüphanesindeki depolayıcıların içindeki verileri
manipule etmek için gerekli fonksiyonları içerir. (find,
count veya swap gibi)
Rastgele integer Sayı Üretme
 Standart kütüphaneden <cstdlib> include edilir ve burada
tanımlı rand() fonksiyonu bu iş için kullanılır.
 rand() fonksiyonu 0 ile RAND_MAX arasında rastgele bir
tamsayı üretir. RAND_MAX cstdlib kütüphanesi içerisinde
tanımlı sabit bir sayıdır ve değeri şu an itibariyle 32767 dir.
 rand() fonksiyonunun ürettiği rastgele sayı istenilen aralığa
modülüs(%) operatörü kullanılarak çekilir.
 Örneğin rand()%6 bize 0 ile 5 arasında integer sayılar üretir.
 Örneğin rand()%6+1 bize 1 ile 6 arasında integer sayılar
üretir.
 rand() fonksiyonu programımızı test veya debug ederken
bize kolaylık olsun diye programı çalıştırdığımız her sefer
aynı sayıyı üretir.
Soru.........
32 ile 122 arasında rastgele bir tamsayı üretecek C++
deyimi aşağıdakilerden hangisidir?
a) rand()%122+32
b) rand()%32+122
c) rand()%90+32
d) rand()%32+90
e) Hocam!! Bu tür sorularla aklımızı karıştırmayınız
Örnek: rand() Fonksiyonu
srand(seed) Fonksiyonu
 Programımızı test ettikten ve tam olarak çalıştığına emin
olduktan sonra programın çalıştırıldığı her sefer farklı bir sayı
üretilsin isteriz.
 Bunun için yine standart kütüphanenin <cstdlib> header
dosyasından srand fonksiyonunu kullanırız. srand fonksiyonu
kendisine unsigned int veri tipine sahip bir argüman alır. Bu
argüman çekirdek değer (seed) olarak adlandırılır.
Örnek: srand(seed) Fonksiyonu
srand(time(0)) Fonksiyonu
 Her seferinde farklı bir çekirdek değer girmek yerine srand
fonksiyonuna argüman olarak standard kütüphanenin <ctime>
header dosyasının içinde tanımlı time fonksiyonu kullanılır.
 Örneğin time(0) (time fonksiyonu sıfır değerini kendisine
argüman olarak almış) bilgisayarın o anki saat değerini saniye
cinsinden geriye döndürür.
 srand(time(0)) ise üretilen bu saat değerini unsigned integer e
çevirir ve çekirdek değer olarak kullanır.
Örnek: srand(time(0)) Fonksiyonu
Rekürsif Fonksiyonlar
 5!=5*4!=5*4*3! ….. (Rekürsif Faktöriyel)
 35=3*34=3*3*33 ….. (Rekürsif Üs Alma)
 4*7=4+4*6=4+4+4*5 ….. (Rekürsif Çarpma)
Rekürsif Fonksiyonlar
 Şu ana kadar gördüğümüz ve tanımladığımız
fonksiyonlarda hiyerarşik bir yapı içerisinde bir
fonksiyon başka bir fonksiyonu çağırıyordu. Bazı
problemler için fonksiyonların kendi kendilerini
çağırmaları daha faydalı olabilir. Bu tür fonksiyonlara
Rekürsif Fonksiyonlar denir.
 Bir rekürsif fonksiyonun ne zaman kendi kendini
çağırmayı durduracağını bilmesi gerekir. Biz buna
temel durum (base case) diyoruz. Eğer bu şart
sağlanmazsa program sonsuza kadar çalışır.
 Öte yandan rekürsif fonksiyonlarla gerçekleştirilebilen
işlemler döngüler ile de yapılabilirler.
Örnek: Rekürsif Faktöriyel Hesaplama
Döngü değişkeninin üst limiti 10 yerine
13 olsaydı ne olurdu? Programınız
mevcut haliyle 13 sayısının faktöriyelini
doğru olarak hesaplar mıydı? Bu sorunu
nasıl çözüme kavuşturursunuz?
5!
Değer ve Referans ile Fonksiyon Çağırma
 Birçok bilgisayar dilinde argümanlar fonksiyonlara iki şekilde
iletilirler. Değer ile (call-by-value) veya Referans ile (call-byreference).
 Bir argüman Değer ile bir fonksiyona aktarıldığında argümanın
bir kopyası alınır ve fonksiyon içersinde değerlendirilir.
Fonksiyon içinde argüman değerine yapılan değişiklikler
fonksiyonun çağrıldığı yerdeki değişkeni etkilemez. (ORİJİNAL
EVRAKIN FOTOKOPİSİ) Bu sunuda şu ana kadar gördüğümüz
örneklerde güvenli olduğu için hep bu yolu kullandık.
 Ama bazı durumlarda Referans ile fonksiyon çağırmak icap
eder. Bu yolla, fonksiyonu çağıran, fonksiyona aktardığı
argümanın değiştirilmesine de izin vermiş olur. (ORİJİNAL
EVRAK) Bu tür bir fonksiyona en güzel örnek “swap”
fonksiyonudur.
 Referans parametresi ya da argümanı ile ilgilendiğimizi
göstermek için “&” karakterini kullanırız.
İKİ DEĞİŞKENİN DEĞERİNİN YER
DEĞİŞTİRMESİ (SWAPPING)
A
B
Elinizdeki TV kumandası
yardımıyla kayıtlı 2 kanalın
yerini nasıl değiştirirsiniz?
geciciDegisken=A;
A=B;
B=geciciDegisken;
!!! GEÇİCİ BİR DEĞİŞKENE İHTİYAÇ VAR !!!
Değer ile Swap Fonksiyonu (Çalışmaz)
Referans ile Swap Fonksiyonu (Çalışır)
Soru
Fonksiyonlar return komutuyla sadece bir değer geriye
çevirirler (döndürürler). Geriye birden fazla değer
çevirebilmek (döndürebilmek) için ne yapmamız
gerekir?
(3 sayının en küçüğünü ve en büyüğünü tek bir
fonksiyon içerisinde hesaplayıp geriye döndürmeniz
gerektiğini hayal edin.)
(void fonksiyonların hangi amaçlarla kullanıldıklarını
hatırlayın.)
Referans ile Değişken Kontrolü
 Referanslar başka değişkenlerin yerine takma isim
(alias) olarak da kullanılabilirler.
 Alias (orijinal değişkenin başka bir adı olarak da
düşünülebilir) olarak tanımlanan bir değişken üzerinde
yapılan her türlü işlem orjinal değişken uzerinde de
gerçekleşir.
 Alias değişkenler MUHAKKAK ilk değerli (initialization)
olarak deklare edilmelidirler.
 Örnek:
 int count = 1;
int &ref = count;
ref++;
• count değişkeninin değeri ref adlı alias kanalıyla 1
artırılır.
Fonksiyon Aşırı Yüklemesi (Function Overloading)
 C++ aynı fonksiyon adına sahip birden fazla fonksiyonun
kullanımına izin verir. Ancak bu durum sadece aynı adlı
fonksiyonların farklı argüman listelerine ya da dönüş
değerlerine sahip olması durumunda geçerlidir.
 C++ derleyicisi aşırı yüklenmiş bir fonksiyon çağrıldığında
fonksiyonun kaç argümana sahip olduğuna, argüman veri
tiplerine ve argümanların sırasına bakarak uygun fonksiyonu
çalıştırır.
 Fonksiyon aşırı yüklemesi, genellikle, benzer işleri farklı veri
tipleri üzerinde yapan aynı ada sahip fonksiyon tanımları için
kullanılır.
 Örnek:
int KaresiniAl(int x){return x*x;}
double KaresiniAl(double y){return y*y;}
Fonksiyon Şablonları (Function Templates)
 Fonksiyon şablonlarını kullanarak aynı işlemi farklı veri
tipleri üzerinde yapan fonksiyonlar için birden fazla
fonksiyon tanımı yapmak zorunda kalmayız.
 Fonksiyon şablonları template anahtar kelimesi ile
başlar ve veri tipleri class anahtar kelimesi ile “<“ ve
“>” karakterleri arasında tanımlanır.
Fonksiyon Şablonları (Function Templates)
Hata Ayıklama (Debugging)
(Ne Umuyordum Ne Buldum?)
 Yazdığımız programlar ya hiç çalışmayabilir ya da çalışır ama beklediğimiz sonuçları
üretmez.
 ÇALIŞAN AMA BEKLEDİĞİMİZ GİBİ SONUÇLAR ÜRETMEYEN programlarımızdaki
MANTIKSAL hataları bulmak için Visual Studio programının DEBUG menüsü
seçeneklerinden faydalanırız.
 Debug Menüsü -> Run To Cursor (Ctrl+F10): İmlecin bulunduğu satırın öncesindeki
bütün satırlar Visual Studio tarafından işletilir ve kontrol imlecin olduğu satırda
kullanıcıya devredilir.
 Debug Menüsü -> Step Over (F10): Kontrolü devralan kullanıcı F10 tuşu yardımıyla
programın kalan satırlarını manuel olarak işletir. F10 tuşu fonksiyonların içerisine
dallanmaz.
 Debug Menüsü -> Step Into (F11): F11 tuşu yardımıyla fonksiyonların içerisine de
girilir.
 Programlarımızdaki mantıksal hataları tespit edebilmenin bir başka yolu da hatanın
kaynaklanabileceğini düşündüğümüz noktanın (noktaların) öncesine veya sonrasına
cout deyimleri eklemektir.