Download as pdf or txt
Download as pdf or txt
You are on page 1of 191

Programlamaya Giri Ders Notlar

H. Turgut Uyar

ubat 2004

ii

nsz

(C) 2001-2004, H. Turgut Uyar <uyar@cs.itu.edu.tr> Bu notlar, stanbul Teknik niversitesi'nde verilen Introduction to Scientic and Engineering Computation dersi iin Bilgisayar Mhendislii Blm retim grevlisi H. Turgut Uyar tarafndan hazrlanmtr. Yazarnn aka belirtilmesi kouluyla eitim amal kullanlabilir ve datlabilir. Dier her trl kullanm iin yazarndan izin alnmaldr.

Srm: 0.99.5 Son dzenleme tarihi: 5 ubat 2004 Web sayfas:

http://www.ce.itu.edu.tr/Members/uyar/c

Bu dersin amac, renciye yalnzca programlamay ya da C dilini retmek deil, ayn zamanda temel saysal yntemleri ve sralama algoritmalar gibi ska kullanlan programlama tekniklerini de gstermektir. Bu amala uygulamalarda daha ok saysal yntemler zerine rnekler seilmeye allmtr. Bu rneklerin ou Prof. Dr. Nadir Ycel'in Saysal Analiz Algoritmalar kitabndan uyarlanmtr. Notlarn hazrlanmasnda yeni standartlara uyumu kolaylatrmas asndan C++ dilinin getirdii baz yeniliklerden yararlanlmtr. Metin iinde yeri geldike, C++ dilinde geerli olup C dilinin izin vermedii zellikler belirtilmitir. Programlarn ekran ktlarnda kullancnn yazd deerler italik olarak iaretlenmitir. rnek programlar ve ders iin hazrlanan sunumlar (ngilizce) yukarda belirtilen web sayfasnda bulunabilir.

iii

iv

indekiler

1 Giri
1.1 Veriler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 1.1.2 1.1.3 1.2 Taban Tipler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1
3 5 6 6 9 11 13 14 22 22 23 24 25 25 26

Kaytlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diziler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Algoritmalar 1.2.1

Algoritmalarn Karlatrlmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.3 1.4 1.5 1.6

Blok Yapl Programlama

Soyutlama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Giri / k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Program Gelitirme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 Programlarn Deerlendirilmesi . . . . . . . . . . . . . . . . . . . . . . . Programlarn altrlmas Kitaplklar Standartlar . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Derleme Aamalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 C Diline Giri
2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 simler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deerler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deikenler Veri Tipleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29
32 33 34 35 36 37 38 39 40 41

Deimezler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aritmetik Deyimler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tip Dnmleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Artrma / Azaltma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matematik Kitapl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.10 Giri / k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v

INDEKILER

vi

3 Ak Denetimi
3.1 Koul Deyimleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.2 Seim 3.2.1 3.3 3.4 3.5 3.6 Karlatrma lemleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mantksal lemler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

45
47 47 48 50 53 53 59 62 63

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Koullu le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

oklu Seim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Koul Denetiminde Yineleme Dng Denetimi . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Saya Denetiminde Yineleme

4 Tretilmi Veri Tipleri


4.1 4.2 Numaralandrma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Yaplar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

73
76 79

5 Diziler
5.1 5.2 5.3 5.4 5.5 Tek Boyutlu Diziler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Katarlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Katar Kitapl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ok Boyutlu Diziler Bavurular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

85
87 91 92 94 98

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6 Fonksiyonlar
6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 Parametre Aktarm

103
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

Fonksiyon Bildirimi ve Tanm . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

Yerel Deikenler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Genel Deikenler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Bavuru Aktarm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Giri Parametreleri zerinden Deer Dndrme . . . . . . . . . . . . . . . . . . 116 Dizilerin Fonksiyonlara Aktarlmas . . . . . . . . . . . . . . . . . . . . . . . . . 117 E simli Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

Varsaylan Parametreler

vii

INDEKILER

7 aretiler
7.1 7.2 7.3 7.4 7.5 7.6 areti Tipinden Deikenler

127
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Bellek Ynetimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 areti - Dizi likisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 areti Tipinden Parametreler Statik Deikenler . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

Adres Aktarm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

8 Giri-k
8.1 8.2 8.3 8.4

141

k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Giri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Ana Fonksiyona Parametre Aktarma . . . . . . . . . . . . . . . . . . . . . . . . 146 Dosyalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 8.4.1 8.4.2 Dosya Ama - Kapama . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 Dosyada Okuma-Yazma . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

8.5 8.6 8.7 8.8

Standart Giri / k Birimleri . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Hata letileri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

Katarlar ile Giri-k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 kili Dosyalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

9 nilemci
9.1 9.2 Projeler

153
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Makrolar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

10 Balantl Listeler

163

10.1 Yaplara aretiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

11 Rekrsiyon A Simgelerin Kodlanmas B Unix'de Program Gelitirme


B.1 B.2 B.3 B.4 B.5

171 177 179

Yardmc Belgeler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Derleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Editrler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Hata Ayklayclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

Baarm nceleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

INDEKILER

viii

Blm 1
Giri

Bir problemi zmek zere bir bilgisayar program yazarken iki temel soruna zm getirmek gerekir:

Problemin nasl temsil edilecei.


Bilgisayarlar temelde saylar zerinde ilem yapmak zere tasarlanm makinalardr; dolaysyla tandklar varlk yelpazesi fazla geni deildir. rnein Trkiye'deki karayollaryla ilgili bir program yazlacaksa ehirlerin ve aralarndaki yollarn bir ekilde temsil edilmesi gerekir nk bilgisayarn ehir, yol gibi kavramlar yoktur. Bir ehri temsil etmek iin ehrin ad, enlemi ve boylam kullanlabilir. Bir yolun temsili iinse farkl seenekler dnlebilir:

Yolun dz olduunu varsayarak bir doruyla gstermek (ekil 1.1a). Bu durumda yalnzca balang ve biti ehirlerini (yani enlem, boylam ve isimlerini) bilmek yeterli olacaktr. Bu yntem ilemleri ok basitletirmekle birlikte gerek durumdan byk lde sapmaya neden olur.

Yolu ucuca eklenmi doru paralaryla gstermek (ekil 1.1b). ekilde stanbulAnkara yolu iki, stanbul-zmir yolu drt, Ankara-zmir yolu doru parasndan olumaktadr. Ancak bu yntem daha zordur ve yolu ne kadar ayrntl temsil etmek isterseniz o kadar fazla doru paras kullanmanz gerekir.

Problemi oluturan varlklarn nasl temsil edileceklerinin belirlenmesi, problem iin bir
model oluturulmas anlamna gelir. Problemin zmnde ilk ve en nemli adm doru

ve yeterli ayrntda bir model oluturmaktr. Yukardaki rnekten de grlebilecei gibi, zeceiniz problemi nasl modellediiniz son derece nemlidir, nk zdnz ey problemin kendisi deil, sizin o problemi temsil etmek zere tasarladnz modeldir. Modeliniz problemden uzaksa siz ne kadar iyi bir zm uygularsanz uygulayn elde edeceiniz sonu anlamsz olur. Dier yandan, modelin ne kadar ayrntl olmas gerektii, zmek istediiniz problemin gereksinimleriyle belirlenir. Gerekenden daha ayrntl bir model hazrlarsanz belki daha iyi bir sonu elde edersiniz ama o daha iyi sonuca ulamak iin harcamanz gerekecek ek aba ya da zmzn gerekleme maliyeti aradaki farka demeyebilir. Yine yukardaki 1

rnekle srdrrsek, stanbul-Ankara karayolunun 274. kilometresi gibi bilgilerden sz edecekseniz yolu doru paralaryla modellemeniz gerekecektir nk gerek yaamda bu nokta byk olaslkla o iki ehri birletiren izginin zerinde bir yere dmeyecektir. Ancak yollarn yalnzca uzunluklaryla ilgileniyorsanz dorularla modellemeniz yeterlidir; bu durumda da doru paralaryla modellemek yolun uzunluunun bulunmasnda zorluk karacaktr.

Istanbul

Istanbul

Ankara

Ankara

Izmir

Izmir

(a)

(b)

ekil 1.1: Karayollarnn gsterilmesi.

zmn nasl ifade edilecei.


Bir problem iin dndnz zm baka birine (insan ya da bilgisayar) anlatabilmeniz gerekir. Adm adm hangi ilemlerin yaplacann aklanmas eklinde anlatlan bir zme algoritma ad verilir. Algoritmalara gnlk yaamdan ska verilen bir rnek yemek tarieridir. Aada, bezelyeli Jamaika pilav yapmak iin nternet'ten alnm bir tarif algoritma biiminde yazlmtr: 1. 1 1/2 kutu bezelyeyi 4-5 ncan suya koy. 2. 1/4 kutu hindistan cevizi st, 1 tutam kekik ve az tadna gre tuz ve biber ekle. 3. Bezelyeler yumuayncaya kadar hala. 4. Bir soann dibini ez ve 2 ncan pirin, 1/4 kutu hindistan cevizi st ve 2 tutam kekik ile birlikte suya ekle. 5. Pirincin stnden 2 cm kadar su kalacak ekilde fazla suyu al. 6. 5 dakika kaynat. 7. Pirin yumuayncaya kadar piirmeye devam et. Algoritmann bir bilgisayar tarafndan yrtlebilmesi iin iki nemli zellik salanmaldr:

Her admda ne yaplaca ak olarak belli olmal, hibir ekilde yorum gerektirmemelidir. Yukardaki rnek bu bakmdan bir algoritma saylamaz nk pek ok admda ne yaplaca yoruma braklmtr. Szgelimi, 4-5 bardak, az tadna gre, bezelyeler yumuayncaya kadar gibi deyimler yeterince kesin deildir.

Sonlu sayda admda ya zm bulunmal ya da bulunamad bildirilmelidir.

Giri

1.1

Veriler

Modelinizde kullandnz byklkler programnzn verilerini oluturur. Her byklk programda bir deiken ile temsil edilir. Deiken aslnda o bykle verilmi simgesel bir isimden baka bir ey deildir. Deikenler, programn ileyii srasnda deerler alrlar. Deikenlerin bellekte tutulduklar gznne alnrsa, deiken bir bellek gznn ad, deer ise bu gzn ieriidir. rnein, bir ehri modellemek iin byklk ngrmtk: isim, enlem ve boylam. Her bykle bir deiken kar drmemiz gerektiinden isim bilgisini ve boylam bilgisini

boylam isim

isim, enlem bilgisini enlem boylam

deikenleriyle temsil ettiimizi varsayalm. Bu durumda temsil deikenine stanbul,

ettiimiz ehre gre bu deikenlere uygun deerler vermemiz gerekir. Szgelimi, stanbul eh-

1 29 deerleri verilmelidir (ekil 1.2).


isim "Istanbul"

rini temsil etmek iin

enlem

deikenine 41,

deikenine

enlem 41

boylam 29

ekil 1.2: ehri temsil eden deikenler ve rnek deerler. Bir deikene bir deer verilmesi ilemine atama denir ve sola bakan bir ok iaretiyle gsterilir:

enlem 41.

Atama iaretinin sol tarafna bir deiken ad, sa tarafna bir deyim yazlr.

Deyim, bir deer reten bir hesaplama olarak tanmlanabilir. Bir deyim, tek bir deer ya da bir deiken olabilecei gibi, bunlarn ilemler ile eitli ekillerde balanmalarndan da oluabilir:

41:

yalnzca bir deer yalnzca bir deiken bir deer ile bir deikenin arpma ilemiyle balanmas iki deikenin toplama ilemiyle balanmas

boylam:

4 * boylam:

enlem + boylam:

Atama ilemi bir matematiksel eitlik deildir. rnein yoktur. Benzer ekilde,

41 enlem atamasnn bir anlam i i + 1 atamas, i deikeninin deerinin o anki deerine gre bir

artrlmas demektir; yani deeri bu ilemden nce 5 ise, ilemden sonra 6 olur. Oysa, bu bir eitlik olsayd yanl olurdu (0 = 1).

rnek. Takas
Programlarda ska gerekebilen ilemlerden biri, iki deikenin deerlerini karlkl deitirmektir. Szgelimi, den sonra

say1 deikeninin deeri 32 ve say2 deikeninin deeri 154 ise bu ilemsay1 deikeninin 154, say2 deikeninin de 32 deerini almas istenir (ekil 1.3).

Takas ilemini yapmak zere u atamalarn kullanldn dnelim:

Burada kuzey enlemlerinin ve dou boylamlarnn pozitif saylarla gsterildii varsaylmtr. Gney enlem-

leri ve bat boylamlar negatif saylarla gsterilirse rnein New York ehrinden sz edildiinde New York,

boylam

deikeni -74,

enlem

isim

deikeni

deikeni 40 deerini almaldr.

Bu ilem iin programlama dilleri genelde = ya da := iaretini kullanrlar.

Veriler

sayi1 32

sayi2 154

(a) nce sayi1 154 (b) Sonra sayi2 32

ekil 1.3: Takas ilemi.

say1 say2 say2 say1


Birinci atama ileminden (ekil 1.4a) sonra deikeninin o anki deerini atadndan

say1

deikeni 154 deerini alr,

ninde ise bir deiiklik olmaz. kinci atama ilemi (ekil 1.4b) ise

say2

say2

say2

deike-

deikenine

say1

deikenine yine 154 deeri atanr ve sonuta

her iki deiken de 154 deerini alm olur (ekil 1.4c).

sayi1 32

sayi2 154

(a) sayi1 154 sayi2 154

(b) sayi1 154 (c) sayi2 154

ekil 1.4: Takas ilemi zm (hatal). ki atama ileminin yetersiz olduu grlmektedir. Yaplmas gereken, deikenlerin deerlerini yitirmemek iin, bir deikenin deerini baka bir deikende yedeklemektir:

ara say1 say1 say2 say2 ara

Giri

ara deikeni 32 deerini alr. kinci atamada (ekil 1.5b) say2 deikenine 32 deeri atanr (ekil 1.5d). Bu atamalardan sonra ara deikeninin deerinin ne olduunun bir nemi
Birinci atama (ekil 1.5a) sonucunda

say1

deikenine 154, nc atama (ekil 1.5c) sonucunda da

yoktur.

sayi1 32

sayi2 154

ara xxx

(a)

sayi1 32

sayi2 154

ara 32

(b)

sayi1 154

sayi2 154

ara 32

(c)

sayi1 154

sayi2 32

ara 32

(d)

ekil 1.5: Takas ilemi zm (doru). Deikenlerin, temsil ettikleri varla gre, bir tip leri vardr. Baz programlama yaklamlarnda programcnn deikenin hangi veri tipinden olduunu belirtmesi art koulurken, bazlarnda deikenin tipi, iinde kullanld balamdan kestirilmeye allr.

1.1.1

Taban Tipler

En sk kullanlan deiken tipi saylardr. rnekteki unlardr:

enlem ve boylam deikenleri duruma gre

birer tamsay ya da kesirli say olarak seilebilir. ou programda gerekecek temel veri tipleri

tamsay

Bir insann doum yl, soyadndaki harf says, boyunun santimetre cinsinden uzunluu, bir ilemin ka kere yapldn sayan saya gibi bilgiler.

kesirli say Bir insann boyunun metre cinsinden uzunluu, iki snavdan alnan notlarn ortalamas, bir saynn karekk gibi bilgiler.

Veriler

mantksal

Bir rencinin bir dersten baarl olup olmad, bir insann onsekiz yandan byk olup olmad, kullancnn bast tuun bir rakam tuu olup olmad gibi bilgiler. Bu tipten deikenler

Doru

ya da

Yanl

deerini alabilirler.

simge

musunuz (E/H)?

Birinin adnn ba har, programn almas srasnda  Devam

etmek istiyor

sorusuna karlk hangi tua bast, bir tarih bilgisinde gn, ay

ve yl arasna hangi iaretin konaca (nokta, tire, bl, vs.) gibi bilgiler. Simgeler ounlukla tek trnak iaretleri iinde yazlrlar: 'E', ' ?', '4' gibi. Burada ayrm yaplmas gereken nemli bir nokta, rakamlar ile rakamlar gsteren iaretleri birbirine kartrmamaktr. rnein 5 rakam ile '5' simgesi farkl byklklerdir (bkz. Ek A). katar Bir insann ad, doduu ehir, bir kitabn ISBN numaras gibi bilgiler katarlarla temsil edilmeye uygundur. Katarlar ounlukla ift trnak iinde yazlrlar: Dennis Ritchie, 0-13-110362-8 gibi. Bir byklk btnyle rakamlardan olusa bile baz durumlarda say yerine katarla gstermek daha uygun olabilir. Bir deikenin ancak zerinde aritmetik bir ilem yaplacaksa say tipinden olmas anlaml olur. rnein, stanbul Teknik niversitesi'nde renci numaralar dokuz haneli tamsaylardr ancak bunlar tamsay olarak temsil etmenin bir anlam yoktur nk renci numaralar zerinde aritmetik ilem yapmak gerekmeyecektir (iki rencinin numaralarn toplamak ya da arpmak gibi).

1.1.2

Kaytlar

Birden fazla bykl ortak bir tip altnda toplarlar. Burada gruplanan byklkler ayn tipten ya da farkl tiplerden olabilir. rnein bir ehri temsil etmek zere kullanlan byklk (ehrin ismi, enlemi ve boylam) birletirilerek ehirleri gsterecek bir ve boylam) alan olacaktr (ekil 1.6a). Bu tipten diyelim bir dnda, deikenin alanlarna erimek iin  bakent kentinin

kent

veri tipi oluturu-

labilir. Bu veri tipinin biri bir katar (ehir ismi), dier ikisi de birer kesirli say olan (enlem

bakent deikeni tanmlanismi, bakent kentinin enlemi

gibi deyiler kullanlmaldr. Bu amala ounlukla noktal gsterilimden yararlanlr; rnein

bakent deikeninin isim alanna Ankara deerini atamak iin bakent.isim Ankara
yazlr (ekil 1.6b). Kaytlar alan olarak baka kaytlar da ierebilirler. rnein, bir yolu temsil iin yolun kodu (katar), uzunluu (tamsay) ve balang ve biti kentleri bilgileri kullanlabilir (ekil 1.7). Eriim, tek dzeyli kaytlara benzer ekilde yaplr (tem.son_kent.isim

tem.kod E-6
1.1.3 Diziler

Ankara

ve

gibi).

Ayn tipten varlklardan oluan bir grubu tek bir at altna toplamak iin kullanlrlar. Bir dizinin btn tek bir deiken olarak deerlendirilir. rnein 50 rencili bir snfta bir snavdan alnan notlar ileneceinde, her bir rencinin notunu gstermek zere

, not50
3

gibi ayr ayr 50 tamsay deiken tanmlanacana,

notlar

not1, not2,

adnda 50 elemanl

Bu deerler rneklerde

ve

eklinde ksaltlacaktr.

Giri

baskent kent isim enlem boylam kent isim enlem boylam "Ankara"

(a)

(b)

ekil 1.6: Kayt tipinden deiken rnei.

tem yol kod ilk_kent isim enlem boylam uzunluk son_kent isim enlem boylam

ekil 1.7: ie kaytlar tipinden deiken rnei.

Veriler

bir tamsay dizisi tanmlanabilir. Ayr ayr deikenler bellekte dank bir yap olutururken dizinin elemanlar bellekte birbirini izleyen gzlere yerletirilir (ekil 1.8).

not4

not13

not1

not22

notlar

50

ekil 1.8: Dizi tipinden deiken rnei.

Elemanlar zerinde ilem yapmak iin dizinin kanc elemanndan sz ettiinizi sylemeniz gerekir. Szgelimi, 22. rencinin ald not 95 ise yaplacak atama

4 gsterilir .

notlar22 95

eklinde

Katarlar ou programlama dilinde simge dizileri olarak grlrler; yani bir katar her bir eleman bir simge olan bir dizidir. Szgelimi, birinin ad ve soyad byklnn deeri 'D',

adsoyad

isimli bir dei-

kende tutulacaksa, bu deiken simge dizisi tipinden olacaktr (ekil 1.9). rnekte

adsoyad7

adsoyad1

byklnn deeri ' ' (boluk) simgesidir.

adsoyad D e n n i s R i ... 1 2 3 4 5 6 7 8 9 10

ekil 1.9: Katar tipinden deiken rnei.

Dizilerle kaytlar birlikte de kullanlabilir. Szgelimi, bir saynn asal arpanlarn temsil etmek zere bir dizi kullanabiliriz (6776

= 23 71 112 ).

Dizinin her bir eleman bir asal arpan

gsterir, her bir asal arpan da bir taban ve bir s deerinden olutuu iin bir kaytla temsil edilir (ekil 1.10). Elemanlara eriim daha nce belirtilen kurallarda grld gibi olacaktr:

arpanlar2 .taban 7
carpanlar taban s 1 2 3 taban s 2 7 1 taban s 3 11 2 ... ...

ekil 1.10: Kayt dizisi tipinden deiken rnei.

Bu ilem iin programlama dillerinde keli ayralar kullanlr:

notlar[22]

gibi.

Giri

rneklerden de grlebilecei gibi, bir dizinin btnyle temsil edilmesi iin dizinin eleman deerlerinin yansra ka eleman olduu bilgisinin de bir ekilde tutulmas gerekir.

1.2

Algoritmalar

Algoritmalar gstermek iin ska kullanlan yntemlerden biri ak izenekleridir. Ak izeneklerinde u simgeler kullanlr:

Kutu: Bir ilemi gsterir. Kutunun iine ilemi anlatan bir komut yazlr. Ok: Ak ynn belirtir. Algoritmann bir sonraki admnn hangisi olduunu gsterir. Ekenar drtgen: Karar noktalarn gsterir. ine yazlan sorunun yantnn doru ya da yanl olmasna gre farkl bir yne gidilmesini salar.

Paralelkenar: Giri/k ilemlerini gsterir.

Algoritmann tamam belirtilmise ak izenei keleri yuvarlatlm kutular iinde bulunan bala komutuyla balar ve dur komutuyla biter. Algoritmann tamam deil, yalnzca ilgilenilen bir paras belirtilmek isteniyorsa izenek bo bir yuvarlak ile balar ve bo bir yuvarlak ile sona erer. Ak izeneinin bymesi ve topluca grlmesinin zorlamas durumunda ak izenei paralarnn bandaki ve sonundaki yuvarlaklarn iine etiketler yazarak hangi parann hangi paraya nereden baland belirtilebilir. Algoritmalarn rnek deerler zerinde ileyilerini daha kolay izleyebilmek amacyla tablolar kullanlabilir. Tablonun her bir satr algoritmann bir admna kar der ve o admda eitli deikenlerin ya da deyimlerin aldklar deerlerin grlmesini salar; yani deikenler ve deyimler tablonun stunlarn oluturur.

rnek. En Byk Eleman Bulma


Bir dizinin en byk elemann bulma algoritmasn, 50 rencili bir snfta bir snavdan alnan en yksek notun bulunmas rnei zerinde inceleyelim. Bu ii yapacak bir algoritma yle yazlabilir:

1. Dizideki ilk notu en yksek not olarak se ve sray ikinci renciye geir. 2. Srada renci varsa 3. adma, yoksa 5. adma git. 3. Sradaki rencinin notu u ana kadarki en yksek nottan bykse bu yeni notu en yksek not olarak se. 4. Sray bir sonraki renciye geir ve 2. adma dn. 5. En yksek notu bildir.

Algoritmalar

10

Daha ok gndelik dil kullanlarak yazlm bu algoritmay biimsel olarak ifade edebilmek iin rencilerin notlarn 50 elemanl bir tamsay dizisi (bu deikene kadar bulunmu en yksek notu bir tamsay (max deikeni diyelim) ile ve sradaki rencinin kanc renci olduunu tutmak iin bir saya (i deikeni) tanmlarsak:

notlar adn verelim), o ana

1. 2. 3. 4.

max notlar1 , i2 i 50
ise 3. adma, deilse 5. adma git. ise

notlari > max i i + 1

max notlari

ve 2. adma dn.

5. en yksek not:

max

Yukarda verilen algoritma rneinin ak izenei ekil 1.11'de grld gibidir. 50 eleman yerine 6 elemanl bir dizide en byk elemann bulunmas algoritmasnn ileyii Tablo 1.1'de verilmitir (notlarn srasyla 43, 74, 65, 58, 82, 37 olduklar varsaylmtr, srme koulu eklinde deimelidir).

i 6

basla

max notlar1 i2

i 50 D

bas: max D dur max notlari

notlari > max Y

ii+1

ekil 1.11: En byk eleman bulma algoritmasnn ak izenei.

rnek. Say Tahmin Etme


Arkadanzn nceden aranzda karlatrdnz iki snr arasnda bir tamsay tuttuunu ve sizin bu sayy bulmaya altnz varsayn. Siz bir say sylediinizde arkadanz, tuttuu

11

Giri

max 43 74 82

i 2 3 4 5 6 7

D D D D D Y

i 6 (2 < 6) (3 < 6) (4 < 6) (5 < 6) (6 = 6) (7 > 6)

notlari > max D (74 > 43) Y (65 < 74) Y (58 < 74) D (82 > 74) Y (37 < 82)

Tablo 1.1: En byk eleman bulma algoritmasnn rnek deerlerle ileyii.

say sizin sylediinizden bykse byk, kkse kk diyecek, doru sayy sylediinizde oyun sona erecektir. Bu oyunu oynarken nasl bir algoritma kullanrsnz? Kararlatrdnz snr deerlerinden kk olann

deiken ile gsterelim. Ayrca, biri arkadanzn tuttuu sayy temsil edecek (tutulan isimli), kullanalm.

taban,

byk olann

tavan

isimli birer

dieriyse sizin sylediiniz sayy temsil edecek (sylenen isimli) iki tamsay deiken daha

Algoritma 1.
1. 2. 3.

Alt snrdan bala, bulana kadar birer artrarak ilerle.

sylenen taban sylenen = tutulan


ise buldun, dur ve 2. adma dn

sylenen sylenen + 1

Algoritma 2.
st

Deneme aralnn ortasndaki sayy syle. Byk derse deneme araln u

anki araln st ksmna, kk derse alt ksmna daralt. Bu algoritmay gereklemek iin o anki deneme aralnn alt ve st snrlarn gsterecek iki yeni deikene (alt ve diyelim) gerek duyulur.

1. 2. 3. 4.

alt taban, st tavan sylenen (alt + st) / 2 sylenen = tutulan sylenen > tutulan
2. adma dn. ise buldun, dur ise

st sylenen - 1,

deilse

alt sylenen + 1

ve

Bu algoritmann ak izenei ekil 1.12'de verilmitir. Alt snrn 1, st snrn 63 olduunu ve arkadanzn 19 saysn tuttuunu varsayarsak, her turda deikenlerin aldklar deerler Tablo 1.2'de grld gibi olacaktr.

1.2.1

Algoritmalarn Karlatrlmas

Yukardaki rneklerde grld gibi, ou zaman bir problemi zmenin birden fazla yolu vardr. Ayn problemi zen iki algoritmadan hangisinin daha iyi olduuna karar vermek zere algoritmalar iki zelliklerine gre karlatrlrlar:

Algoritmalar

12

basla

alt taban st tavan

sylenen (alt + st) / 2

sylenen = tutulan

bas: sylenen

sylenen > tutulan

dur

alt sylenen + 1

st sylenen - 1

ekil 1.12: Say tahmin etme algoritmasnn ak izenei.

alt 1 17 19

st 63 31 23 19

sylenen 32 16 24 20 18 19

sylenen = tutulan Y (32 > 19) Y (16 < 19) Y (24 > 19) Y (20 > 19) Y (18 < 19) D (19 = 19)

Tablo 1.2: Say tahmin etme algoritmasnn rnek deerlerle ileyii.

13

Giri

1. Hzlar: Hangi algoritma zm daha abuk buluyor? Bu sorunun yant da iki durum iin incelenir: (a) en kt durumda (b) ortalama durumda Say bulma iin verilen yukardaki iki algoritmay bu bakmdan karlatrrsak, birinci algoritmann rnek deerlerle sayy en kt durumda 63, ortalama durumda 32 denemede bulaca grlr. Oysa ikinci algoritma sayy en kt durumda 6, ortalama durumda 5.09 denemede bulur. 2. Harcadklar yer: Hangi algoritma bellekte daha fazla yer kullanyor? Say bulma algoritmalarnda grdmz gibi, ikinci algoritma birinci algoritmann kullandklarna ek olarak iki deiken daha gerektirmektedir.

Gnmzde bilgisayarlarn kapasiteleri eskiye oranla ok ykselmi olduu iin harcanlan yer ltnn nemi greli olarak azalmtr. Yine de projenin boyutuna ve allan ortamn yeteneklerine gre algoritma gelitirirken hzn yansra harcanacak yerin de gznne alnmas gerekebilir. Algoritmalarn hzlarnn ve harcadklar yerlerin incelenmesi algoritma analizi dalnn konusudur. Bu dalda gelitirilmi bulunan karmaklk kuram, benzer problemlerin zm iin nerilen algoritmalarn karlatrlmasnda bavurulan en nemli aratr.

1.3

Blok Yapl Programlama

Blok yapl programlamann temelinde blok kavram yatar. Blok, birbiriyle ilikili komutlarn oluturduu gruptur. Her algoritma birbirlerine eitli ekillerde balanm bloklardan oluur. Bloklar balamann yolu vardr:

Sra

Bloklarn yukardan aaya doru yazldklar srayla yrtlrler (ekil 1.13a). Sra yaps, komutlarn yazl sralarnn nemli olduunu vurgular. Blm 1.1'de grlen takas rnei iin verilen doru zmde yaplan atama ileminin sralar deitirilirse varlacak sonular yanl olabilir.

Seim

Bir koulun doru olup olmamasna gre farkl bir bloun yrtlmesidir. Yani koul

doruysa bir blok, yanlsa baka bir blok yrtlr (ekil 1.13b). ki bloktan herhangi biri bo olabilir, yani koul doruysa u blou yrt, yanlsa hibir ey yapma eklinde bir yap kurulabilir.

Yineleme

Belirli bir koul saland srece (ya da salanana kadar) bir blok yinelenebilir.

Ak izeneinden (ekil 1.13c) grlebilecei gibi, bu yapdan klabilmesi iin bloun koulu deitiren bir komut iermesi gerekir, aksi durumda koul balangta doruysa hep doru olacandan yapdan klamayacaktr. Yine ak izeneinden grlebilecek bir dier zellik de, koul balangta yanlsa bloun hi yrtlmeyeceidir. Baz uygulamalarda blok kouldan nce de yer alabilir (ekil 1.12 byle bir rnektir); byle durumlarda koul batan yanl olsa bile blok en az bir kere yrtlr.

Soyutlama

14

D blok1

kosul

Y kosul blok2

blok2

blok1

D blok

(a)

(b)

(c)

ekil 1.13: Temel yaplarn ak izenekleri.

Bu yaplarn ortak bir zellii, hepsinin bir giri ve bir klarnn olmasdr. Bylelikle bir bloun k br bloun giriine balanabilir; baka bir deyile, bloklar ardarda eklenebilir. Ayrca, bir bloun iinde baka bir blok yer alabilir. ekil 1.12'de uluyla belirlenen seim yaps, bir alt bileeni durumundadr. Bir programn okunmasn ve anlalmasn en ok zorlatran etkenlerden biri programda yer alan dallanma komutlardr. imdiye kadar yazdmz baz algoritmalarda geen n. adma git tipi komutlar iin -programlama dillerinde genellikle ramlamada yineleme iin zel yaplar vardr ve

sylenen = tutulan

sylenen > tutulan

ko-

kouluyla belirlenen yineleme yapsnn

goto

olarak adlandrlan- bir komut

bulunmas gerektii dnlebilir (zellikle yineleme yaplar iin). Ancak blok yapl prog-

goto

komutunun kullanlmamas zendirilir.

1.4

Soyutlama

Programlamann temel dzeneklerinden biri soyutlama kavramdr. Soyutlama, programn yapaca iin daha kk ve birbirinden olabildiince bamsz alt-ilere blnmesidir. Alt-iler de, benzer ekilde, yapacaklarn alt-alt-ilere blebilirler (ekil 1.14). Bu tip tasarma yukardan aaya tasarm ad verilir.

Her i bir yordam (C dilindeki adyla fonksiyon ) tarafndan gereklenir. Ana-yordamn grevi, alt-ileri gerekleyen yordamlar balatmak ve bunlar arasnda egdm salamaktr. Bir styordam, kulland alt-yordamlarn nasl altklaryla deil, yalnzca sonularyla ilgilenir. Soyutlamann kazandrdklar yle zetlenebilir:

5 6

Bir ii gerekleyen yordam yazlrken, kulland alt-yordamlarn ayrntlaryla uralmaz; alt-yordamn doru alt varsaylarak yordamn kendi iine younlalabilir. By-

Bu konuyla ilgili olarak, Edsger W. Dijkstra'nn Go To Statement Considered Harmful balkl klasik

makalesini makalesini

http://www.acm.org/classics/oct95/

adresinde bulabilirsiniz. adresinde bulabilirsiniz.

Bu konuyla ilgili olarak, Niklaus Wirth'n Program Development by Stepwise Renement balkl klasik

http://www.acm.org/classics/dec95/

15

Giri

ana-is

alt-is-1

alt-is-2

alt-is-3

alt-is-1a

alt-is-3a

alt-is-3b

ekil 1.14: Ana iin alt ilere blnmesi.

lelikle byk ve zlmesi zor olan bir sorunla uramak yerine, her biri kk ve zlebilir sorunlarla uralr ve bunlar daha sonra biraraya getirilir.

Programn bakm kolaylar. Alt-yordamlarn almalar birbirlerinden bamsz olduundan bir alt-yordamda bir deiiklik yapldnda bunu kullanan st-yordam (styordamla olan etkileim deimedii srece) deiiklikten etkilenmez.

Yordamlar olabildiince genel amal yazlmaldr. Szgelimi bir yordamn ii BL105E dersini alan rencilerin ylsonu snav notlarnn en byn bulmak eklinde tanmlanabilir. Oysa ii herhangi bir dizinin en byn bulmak olarak tanmlanan bir yordam gelitirmek ve bu yordam kullanrken hangi dizinin en bynn bulunmasnn istendii belirtmek daha etkin bir alma biimidir. Bu durumda hangi dizi zerinde ilem yaplaca bilgisi yordamn giri parametresi olur. Yordam, almas sonucu rettii deeri k parametresi olarak dndrr. rnekteki yordam kullanlrken giri parametresi olarak BL105E dersini alan rencilerin ylsonu snav notlar verilirse snavda alnan en yksek not, Los Angeles Lakers basketbol takmnn oyuncularnn ayakkab numaralar belirtilirse takmn en byk ayakl oyuncusunun ayakkab numaras k parametresi olur.

rnek. En Byk Ortak Blen Bulma


ki saynn en byk ortak blenini bulma ii u ekilde alt ilere blnebilir:

1. Birinci sayy asal arpanlarna ayr. 2. kinci sayy asal arpanlarna ayr. 3. Saylarn ortak arpanlarn belirleyerek en byk ortak blenin asal arpanlarn bul. 4. Bir nceki admda belirlediin asal arpanlardan en byk ortak bleni hesapla.

Saylarn 9702 ve 945 olduklar varsaylrsa:

Soyutlama

16

1. 9702 = 2 * 3 * 3 * 7 * 7 * 11 = 2 2. 945 = 3 * 3 * 3 * 5 * 7 = 3 3. ortak arpanlar: 3

1 * 32 * 72 * 111

3 * 51 * 71

2 * 71

4. en byk ortak blen: 63

1. ve 2. admlar iin herhangi bir sayy asal arpanlarna ayran bir yordam yazlabilir ve asal arpanlarna ayrlacak say bu yordama parametre olarak yollanabilir. Benzer ekilde, 3. admdaki ortak arpanlarn bulunmas ii de bir alt-yordama verilebilir. 4. admda ortak arpanlardan en byk ortak blenin hesaplanmas ilemleri iin alt-yordam kullanmann fazla bir anlam yoktur, ana yordama brakmak daha yerinde olur. Bylece ekil 1.15'deki yap ortaya kar. rnek saylar zerinde yordamlarn hangi giri ve k parametreleriyle altklar ekil 1.16'da verilmitir.

1. sayi

en byk ortak blen hesapla 1. sayinin arpanlari 2. sayinin arpanlari

2. sayi

1. sayinin arpanlari asal arpanlara ayir 2. sayinin arpanlari

ortak arpanlar ortak arpanlari bul

ekil 1.15: En byk ortak blen hesaplama algoritmasnn yukardan aaya tasarm. Asal arpanlara ayrma algoritmasnda grlen bir sonraki asal sayy bulma ii de asal arpanlarna ayrma iinin bir alt-ii olarak dnlerek bir baka yordama braklabilir. Bu yordam kendisine parametre olarak gnderilen saydan bir sonraki asal sayy bularak sonucu geri yollayacaktr. Benzer ekilde bu yordam da bir saynn asal olup olmadn snamak zere baka bir yordamdan yararlanmak isteyebilir. Bu rnek iin verilen yordamlar gerekleyecek algoritmalar blmn sonundaki uygulamada verilmitir.

rnek. Euclides Algoritmas


Yukarda verilen algoritmann en nemli sorunu, zellikle byk saylar asal arpanlarna ayrmann zorluudur. Bilinen en eski algoritma rneklerinden biri olan Euclides algoritmas, iki saynn en byk ortak bleninin arpanlara ayrmadan hzl biimde hesaplanmasn salar. En byk ortak bleni bulunacak saylardan byk olanna

a,

kk olanna

dersek:

17

Giri

9702

en byk ortak blen hesapla 945

2 32 72 11 33 5 7

2 32 72 11

32 7

asal arpanlara ayir

33 5 7

ortak arpanlari bul

ekil 1.16: rnek saylar zerinde en byk ortak blen hesaplama algoritmasnn ileyii.

a = q 1 b + r1
eklinde yazlabilir. Burada ile

r1 = 0

ise iki saynn en byk ortak bleni

b'dir.

Deilse

saylarnn en byk ortak bleni

ile

r1

saylarnn en byk ortak blenine eittir.

Dolaysyla, blmden kalan 0 olana kadar aadaki eitlikler yazlabilir:

b = q 2 r1 + r2 r1 = q 3 r 2 + r 3 ... rn2 = qn rn1 + rn rn1 = qn+1 rn + rn+1 (rn+1 = 0)


Bu durumda

ile

b'nin

en byk ortak bleni

rn 'dir.

Yine

a = 9702, b = 945

rneini alrsak:

9702 = 10 945 + 252 945 = 3 252 + 189 252 = 1 189 + 63 189 = 3 63 + 0


Her denklem iin en byk ortak bleni alnacak saylardan byk olann deikeninde, bu ikisinin blmnden kalan deeri de

a, kk olann b r deikeninde tutarsak (kalan ilemi %

iaretiyle gsterilsin), bu algoritma bir yineleme yapsyla gereklenebilir. Bir blme ileminde

Soyutlama

18

her zaman kalan, blenden kk olaca iin her yinelemede de

r'nin

deerini alarak ilerlenir ve

deikeni

0 olduunda en byk ortak blen

b'nin, b

deikeni

deikeninde elde

edilmi olur. Bu algoritmann ak izenei ekil 1.17'de, rnek deerlerle ileyii Tablo 1.3'de verilmitir.

D a sayi1 b sayi2

sayi1 > sayi2

Y a sayi2 b sayi1

b>0 D ra%b ab br

bas: a

ekil 1.17: Euclides algoritmasnn ak izenei.

a 9702 945 252 189

b 945 252 189 63

r 252 189 63 0

Tablo 1.3: Euclides algoritmasnn rnek deerlerle ileyii.

Uygulama: Algoritmalar

rnek. Asal arpanlarn Bulunmas

Herhangi bir saynn asal arpanlarna ayrlmas iin kullanlabilecek bir algoritma ekil 1.18'de verilmitir. Bu algoritmada

x asal arpanlarna ayrlacak sayy, c arpan olup olmad o anda

Orijinal haliyle algoritmada blmeden kalan ilemi yerine kartma ilemi kullanlyordu. Blmeden kalan

ilemi algoritmann nemli lde hzlanmasn salayan bir deiiklik olarak sonradan getirilmi bir yntemdir.

19

Giri

snanmakta olan asal sayy,

u da sradaki arpann kuvvetini gsterir. 945 says rnek olarak

alnrsa algoritmann ileyii Tablo 1.4'de verilmitir.

c2

x>1 D

x%c=0 D c bir carpandir u0

x%c=0 D uu+1 xx/c

c sonraki asal sayi

ekil 1.18: Bir sayy asal arpanlarna ayrma algoritmas.

rnek. Ortak arpanlarn Bulunmas

ki saynn arpanlarndan en byk ortak blenin arpanlarn bulma iini yapacak yordamn algoritmas gelitirilirken, asal arpanlara ayrma yordamnn alma ekli nedeniyle arpanlarn kkten bye doru sral olduklar varsaylabilir. Bu varsayma gren alan algoritma ekil 1.19'da verilmitir. Bu algoritmada carpanlar1 birinci saynn asal arpanlar dizisini, carpanlar2 ikinci saynn asal say arpanlar dizisini, c1 birinci saynn sradaki asal arpann, c2 de ikinci saynn sradaki asal arpann gsterir. Her iki dizinin elemanlarna erimek iin de srasyla i1 ve i2 saya deikenleri kullanlmtr. rnek dizilerle algoritmann ileyii Tablo 1.5'de verilmitir.

Soyutlama

20

x 945 315 105 35 7 1

2 3

x > 1 D (945 > 1) D (945 > 1)

5 7 11

D (35 > 1) D Y (7 > 1) (1 = 1)

Y D D D D Y D D Y D D Y

x % c = 0 (945 mod 2 = (945 mod 3 = (945 mod 3 = (315 mod 3 = (105 mod 3 = (35 mod 3 = (35 mod 5 = (35 mod 5 = (7 mod 5 = (7 mod 7 = (7 mod 7 = (1 mod 7 =

carpan 1) 0) 0) 0) 0) 2) 0) 0) 2) 0) 0) 1) 3

u 0 1 2 3 0 1 0 1

5 7

Tablo 1.4: Asal arpanlarna ayrma algoritmasnn ileyii.

c1
1 2
3 7

c2
3 3
5

taban
2 < 3 3= 3

us
2 < 3

carpan
3

2 2 1

7 > 5 7= 7 1 < 2 7

1 7
11

Tablo 1.5: Ortak arpanlar bulma algoritmasnn ileyii.

21

Giri

c1 carpanlar11, c2 carpanlar21 i1 1, i2 1

c1 ve c2 bos deil

D D i1 i1 + 1 c1 carpanlar1i1

c1.taban < c2.taban

c1.taban > c2.taban

i2 i2 + 1 c2 carpanlar2i2

c1.us < c2.us

c1 bir carpandir

c2 bir carpandir

i1 i1 + 1, i2 i2 + 1 c1 carpanlar1i1, c2 carpanlar2i2

ekil 1.19: Ortak arpanlar bulma algoritmas.

Giri / k

22

1.5

Giri / k

Bir programlama dilinin kullanlabilir olmas iin dilde blok yapl programlamann kavramlarn desteklemenin dnda baz gereklilikler de yerine getirilmelidir:

Giri

Bir program her seferinde ayn veri deerleri zerinde almaz, ileyecei verileri alma srasnda bir ekilde renmesi gerekir. Bunun en sk karlalan yntemi verileri program kullanan kiiye sormak olmakla birlikte verileri bir dosyadan okumak ya da ortamdan renmek (szgelimi odann scakln len bir duyargadan almak) gibi seenekler de bulunabilir. Programlama dillerinin girdi komutlar giri birimlerinden aldklar deerleri deikenlere aktarrlar. Aksi belirtilmedike standart giri birimi kullancnn tutakmdr.

k

Program, verilerin ilenmesi sonucu elde ettii sonular bir ekilde deerlendirmelidir.

En sk grlen yntem sonucun kullancnn ekranna yazlmasdr ama girite olduu gibi sonularn bir dosyaya yazlmas ya da ortama gnderilmesi (oda scakln denetleyen klimaya bir sinyal yollanmas gibi) szkonusu olabilir. Programlama dillerinin kt komutlar, deiken deerlerini istenen k birimine ynlendirirler. Aksi belirtilmedike standart k birimi kullancnn ekrandr. Programn almas srasnda karlalan hata durumlarnn bildirilmesi de ktnn bir parasdr. Ancak, hatalarn daha kolay farkedilmelerini salamak amacyla, bu iletilerin normal kt iletilerinden ayrlabilmeleri istenir. Bu nedenle, hata iletileri hata birimine ynlendirilir. Aksi belirtilmedike bu birim -standart kta olduu gibi- kullancnn ekrandr.

Bu notlarda ilenecek rnek programlarda alma hep ayn ekilde olacaktr: verilerin girilmesi, ilenmesi, sonularn gsterilmesi. Bu tip programlara konsol program, komut satr program ya da metin kipi program gibi adlar verilir. Grak arayzle alan programlar ise olaya dayanan bir mantkla alrlar. Program almaya baladnda kullancyla iletiimi iin gerekli arayz kurar (pencere izer, men oluturur, dme koyar, v.b.) ve sonra kullancnn bir edimde bulunmasn bekler. Kullancnn edimine gre ilgili yordamlar altrr.

1.6

Program Gelitirme

Bir programn gelitirilmesi eitli aamalardan oluur:

Tasarm

Bu aamada yazlacak program kat zerinde tasarlanr. Yani programn algorit-

masna, hangi programlama dilinin kullanlacana, kullancyla nasl bilgi alveriinde bulunulacana, ksacas neyin nasl yaplacana karar verilir. Dikkatli bir tasarm, programn hem gelitirilmesinde hem de bakmnda byk kolaylklar salar.

Kodlama

Bu aamada program tasarm srasnda verilen kararlara gre bir programlama di-

liyle yazlr. Bunun sonucunda yazlmn kaynak kodu oluur.

8 Kaynak kodunu bilgisayar

ortamnda oluturmak iin editr ad verilen yazlmlar kullanlr.

Metinde bunda sonra geen

kod

szc aksi belirtilmedike kaynak koduna kar decektir.

23

Giri

Snama

Bu aamada program altrlarak eitli senaryolar iin doru sonular retip ret-

mediine, beklendii gibi davranp davranmadna baklr. Bu ilemin etkinlii gznne alnan senaryolarn gerekte oluabilecek durumlarn ne kadarn rttyle balantldr.

Hata Ayklama

Bu aamada snama aamasnda bulunan hatalarn nedenleri belirlenerek

gerekli dzeltmeler yaplr. Programlarn ilk yazldklar ekliyle doru olmalar neredeyse olanakszdr. Hatta stne ok allm, pek ok hatas bulunup dzeltilmi programlarda bile btn hatalarn bulunup dzeltilmi olmas son derece dk bir olaslktr. Ayrca programlara yeni yetenekler eklendike yeni hatalar oluacandan aa yukar hibir program hibir zaman tam olarak hatasz olmayacaktr. Hata ayklama ilemine yardmc olmak zere hata ayklayc ad verilen yazlmlar kullanlr.

Programlarda iki tr hata szkonusu olabilir:

1. Yazm hatalar: Programcnn yazd baz komutlar kulland programlama dilinin kurallarna uymuyordur. 2. Mantk hatalar: Programcnn yazd kod dilin kurallar asndan dorudur ama altrlmasnda sorun kar. Szgelimi bir tamsayy baka bir tamsay deikene blmek geerli bir ilemdir ama blen say 0 olursa bu ilem gerekletirilemez. Bu tr hatalara
alma-zaman hatas da denir.

1.6.1

Programlarn Deerlendirilmesi

Bu aamalar sonucunda ortaya kan bir programn iyi bir program olup olmadnn, ya da ne kadar iyi bir program olduunun deerlendirilmesinde u ltlere bavurulur:

Etkinlik

Bu konu algoritmalarn karlatrlmalarnda kullanlan ltlerle ayndr. Program

ne kadar hzl alyor? Dzgn kullanlabilmesi iin ne kadar sistem kayna gerekiyor (hangi ilemci, ne kadar bellek, ne kadar disk, v.b.?).

Salamlk

Program, kullancnn yapaca kullanm hatalarna kar dayankl m? Szgelimi,

kendisine bir yl bilgisi sorulduunda kullanc yanllkla (ya da kt niyetle) bir isim yazarsa ne oluyor?

Tanabilirlik

Program, zerinde fazla deiiklik yaplmas gerekmeden, baka bir donanm

ve baka bir iletim sistemi zerinde alacak hale getirilebiliyor mu?

Anlalabilirlik Bakm kolayl


kolay m?

Baka biri program okuduunda anlayabilecek mi? Hatta stnden bir sre

getikten sonra kendiniz baktnzda anlayabilecek misiniz? Programda hata olduunda hatann kaynann belirlenmesi ve dzeltilmesi

Gelitirilebilirlik

Program yeni yeteneklerin eklenmesiyle gelitirilmeye ak m? Bu tip ek-

lemelerin yaplmas kolay m?

Program Gelitirme

24

Gelitirme aamalarnda daha az sorunla karlamak ve daha kaliteli yazlmlar retmek iin eitli yntemler gelitirilmitir. Bu yntemlerin temel fark, problemin nasl modelleneceine ilikin yaklamlardr. Blok yapl yaklam, nesneye dayal yaklam, fonksiyonel yaklam gibi yntemler eitli alanlarda yaygn olarak kullanlmaktadr. Setiiniz programlama dili hangi programlama yaklamn kullanacanz da belirler. Szgelimi C dili blok yapl, Java dili nesneye dayal, Haskell diliyse fonksiyonel dillerdir. C++ dili hem blok yapl hem de nesneye dayal zellikler gsteren karma bir dildir.

1.6.2

Programlarn altrlmas

Bilgisayarlarn altracaklar programlarn belli bir biimi olmas zorunludur. Bu biim, bilgisayardan bilgisayara ve iletim sisteminden iletim sistemine gre farkllklar gsterir. Szgelimi, bir kiisel bilgisayar zerinde Windows iletim sisteminde alan bir program, Sun marka bir iistasyonunda Solaris iletim sisteminde almaz. Hatta, yine ayn kiisel bilgisayar zerinde Linux iletim sisteminde de almaz. Programlarn bu altrlabilir biimine makina
kodu ad verilir. Makina kodu, insanlarn anlamas ve zerinde almas son derece zor bir

biim olduundan programclar programlar dorudan bu kod ile yazmazlar. nsann anlamas daha kolay (insan diline daha yakn) yksek dzeyli bir dil ile kaynak kodunu oluturup yardmc yazlmlar araclyla makina koduna evirir ve altrrlar. Kaynak kodunun makina koduna evrilmesi ve altrlmas ilemi farkl yaklamla gerekletirilebilir:

Yorumlama

Programn komutlar bir yorumlayc tarafndan teker teker okunur, makina

koduna evrilir ve altrlr. Yani yorumlayc, nce birinci komutu okur, makina koduna evirir ve altrr. Sonra ikinci komutu alr ve ayn ilemleri yapar. Programn her almasnda evirme ilemi yeniden yaplr. Herhangi bir komutun evrilmesinde ya da altrlmasnda bir hatayla karlatnda bunu kullancya bildirir ve almay durdurur. Basic, Perl, Tcl gibi diller genellikle yorumlayclar araclyla kullanlrlar.

Derleme

Program bir derleyici tarafndan bir btn halinde okunur ve makina koduna ev-

rilerek bir altrlabilir dosya oluturulur. Bu dosya daha sonra istendii zaman altrlr, yani evirme ile altrma ilemleri birbirinden ayrlr. Bylelikle evirme ilemi yalnzca bir kere yaplr. Herhangi bir komutta hata varsa evirme ilemi tamamlanmaz, yani altrlabilir kodun olumas iin hibir yazm hatas olmamas gerekir; ancak program daha sonra altrlrken alma-zaman hatalaryla karlalabilir. Fortran, Pascal, C gibi diller genelde derleyicilerle kullanlrlar.

Karma

Hem derleme hem de yorumlama teknii kullanlr. Bu tip almada kaynak kodu

sanal bir bilgisayarn makina koduna (bytecode) evrilir ve daha sonra bu sanal bilgisayar gerekleyen bir program yardmyla yorumlanarak altrlr. rnein Java dilinde yazlm bir kaynak kodu nce Java derleyicisinden geirilerek Java sanal makinasnn (Java Virtual Machine - JVM) makina koduna dntrlr; sonra da bu sanal makinay gerekleyen bir Java alma ortam (Java Runtime Environment - JRE) yardmyla altrlr.

Yorumlama ynteminde kodun okunmas ve evrilmesi programn almas srasnda yapldndan hz dktr. Ayrca yorumlayc yalnzca karlat ilk hatay rapor edebilir. Bu

25

Giri

hata dzeltildiinde sonraki almada da program ancak bir sonraki hataya kadar ilerleyebilir. Oysa derleyici kaynak kodundaki btn hatalar bulabilir. Buna karlk hata ayklama ilemi yorumlayclarla daha kolaydr. Ayrca derleyicilerle gelen baz snrlamalarn kalkmas nedeniyle daha esnek bir alma ortam salanr. Son yllarda iki yntemin stn yanlarn birletiren karma diller (Java ve Python gibi) ne kmaya balamlardr.

1.6.3

Kitaplklar

Bir programcya gerekebilecek her eyi programlama dilinin iine almak o dili ileyecek aralarn hantallamalarna neden olur. C dili bu nedenle olduka kk bir dil olarak tasarlanmtr. rnein basit aritmetik ilemlerin tesindeki matematik ilemleri dilin tanm iinde yer almaz; szgelimi karekk alma ilemi iin bir C komutu yoktur. Bununla birlikte, pek ok programcnn bu tip ilemlere gereksinim duyacaklar da aktr. Byle bir durumda programc, isterse karekk alma ilemini yapacak kodu kendisi yazabilir. Ancak programcnn bu tip ilemler iin kendi kodlarn yazmasnn nemli sakncalar vardr:

1. Her programcnn ayn ileri yapan kodlar yazmas byk zaman kaybna yol aar. 2. Programcnn yazaca kod hatal olabilir, yani yanl sonu retebilir. Ya da doru sonu retse bile, yeterince etkin olmayabilir, yani ilemi yapmak iin gereinden fazla zaman ya da sistem kayna harcayabilir.

Hem dilin tanmn kk tutmak hem de bu sakncalar giderebilmek iin, ou programcya gerekebilecek ilemler (yordamlar) kitaplk ad verilen arivlerde toplanmtr. Bir saynn karekkn almak isteyen bir programc matematik kitaplndaki

sqrt

yordamn kullanabi-

lir. Kitapln kullanlmas yukarda sz geen sakncalar giderir, yani programcya zaman kazandrd gibi, doru ve etkin alt snanm olduundan dikkatini programn dier ksmlarna younlatrma frsat verir.

1.6.4

Standartlar

C dilinin gelitirilmesinde gzetilen ana hedeerden biri tanabilirlikti. Bunun iin deiik ortamlardaki aralar arasnda bir standart olmas gerektii aktr. C dilinde yaplan standartlama almalar sonucunda oluan ANSI C standard, hem C dilinin kurallarn belirler, hem de bir C gelitirme ortamnda bulunmas zorunlu olan standart kitaplklar ve bu kitaplklarda yer alacak yordamlar tanmlar. Uluslararas Standartlar Organizasyonu'nun (ISO) C++ dili iin hazrlad ISO-C++ standard da son yllarda yazlm btn C/C++ gelitirme ortamlar iin en temel kaynaklardan birini oluturmaktadr. Dier nemli bir standart olan POSIX standard ise programlama dili ile iletim sistemi arasndaki balantlar belirler. rnein dosya silmek, dosya ad deitirmek, sistemdeki baka bir programla haberlemek gibi ilemler iin gereken yordamlar bu standartta yer alrlar. Yine de ska gereksinim duyulan btn ilemler iin btn kitaplklarda bir standart henz salanamamtr. rnein grak bir arayze sahip uygulamalardaki grak ilemlerini yapacak kitaplklar standartlatrlmam olduundan eitli rma ve kurumlar bu ilemleri yapan farkl

Program Gelitirme

26

kitaplklar gelitirmilerdir. Dolaysyla bu kitaplklar kullanlarak yazlan programlar tam anlamyla tanabilir olmamakta, yalnzca bu kitapln destekledii ortamlara tanabilmektedir. Son zamanlarda farkl iletim sistemlerinde alabilen grak kitaplklar yaygnlat iin doru aralar seildiinde bu sorunun da stesinden gelinebilmektedir.

1.6.5

Derleme Aamalar

Kaynak koddan retilecek olan altrlabilir makina kodunda hem programcnn kendi yazd yordamlarn, hem de yararland kitaplk yordamlarnn makina koduna evrilmi hallerinin bulunmas gerekir. Bu nedenle, kaynak kodunun makina koduna evrilmesi iki aamada gerekleir (ekil 1.20):

derleme kaynak kodu ara kod

baglama alistirilabilir kod

kitapliklar

ekil 1.20: Tek kaynak kodlu projelerin derleme aamalar.

Derleme

lk aamada kaynak kodu derlenerek bir ara koda dntrlr. Bu kod, kullancnn

yazd yordamlarn makina kodu karlklarn ieren bir dosyadr. Ancak, programcnn kullanm olduu kitaplk yordamlarn iermediinden henz altrlabilir durumda deildir.

Balama

kinci aamada ara kod ile programcnn kulland kitaplk yordamlar arasnda

balantlar kurulur ve altrlabilir dosya retilir. Szgelimi, programc karekk alma iin matematik kitaplndaki bir yordam kullandysa, balayc ara kodda karekk yordamnn kullanld yerlerde gerekli dzenlemeleri yapar.

Sorular
1. Blm 1.1'de verilen takas ilemi iin yazlan atama komutunun sralarn deitirerek ne sonular elde edildiini belirleyin. Problemin ka doru zm vardr? 2. Blm 1.2.1'de yaplan algoritma hz karlatrmalarnda verilen en kt ve ortalama durum deerlerini kendiniz karn. Alt snrn 1, st snrn 2 durumda en kt ve ortalama deerleri

n - 1 eklinde verildii genel

cinsinden hesaplayn.

3. ki saynn en byk ortak blenini hesaplamak iin verilen iki algoritmay, basitlik ve etkinlik alarndan karlatrn. kiden fazla saynn en byk ortak blenlerini hesaplamak iin bir algoritma gelitirin.

27

Giri

4. Euclides algoritmasnda iki saydan byk olannn hangisi olduuna baklmakszn deikenine

say1, b

deikenine

varsayalm. Balangta

a say2 deerleri atanarak yineleme yapsna girildiini say1 > say2 ya da say1 < say2 olmas durumlarnda al-

goritma doru sonu retir mi? 5. arpanlara ayrarak en kk ortak kat hesaplamak iin gereken en kk ortak katn arpanlarn bulma yordamnn ak izeneini izin ve rnek deerler zerinde nasl ileyeceini gsteren tabloyu oluturun.

Program Gelitirme

28

Blm 2
C Diline Giri

Bu blmde deikenler, atama, deyimler, giri-k gibi konularn C dilinde nasl gereklendikleri zerinde durulacaktr.

rnek 1. Daire evresi ve Alan


Yarapn kullancdan ald bir dairenin evresini ve alann hesaplayarak ekrana yazan bir program yazlmas isteniyor. Programn rnek bir almasnn ekran kts ekil 2.1'de verilmitir.

Yarap yaznz: 4.01 evresi: 25.1828 Alan: 50.4915

ekil 2.1: rnek 1 ekran kts. rnek zerinde bir C programnn baz temel zelliklerini grelim:

Aklamalar

Anlalabilirlii artrmak iin kodun iinde gerekli yerlere aklamalar yazmakta

byk yarar vardr. zellikle kolayca anlalmayacak programlama tekniklerinin kullanld kod paralarnn aklanmas gerekir. Aklamalar derleyici tarafndan gzard edilir, yani programn ileyilerine hibir etkileri yoktur. Kodun iine aklama iki ekilde yazlabilir:

Birinci yntemde, aklamann bana bl-yldz, sonuna yldz-bl simgeleri konur. Bu ekildeki aklamalar birden fazla satr srebilir. rnekteki birinci aklama birinci satrdaki  lk  alann

hesaplar.

C programm

szckleriyle balar ve nc satrdaki

szckleriyle biter. Bu tip aklamalar iie yazlamaz, yani

bir aklamann iinde ikinci bir aklama olamaz. ie aklamalar u ekilde bir yap oluturur:

...a... /* ...b... /* ...c... */ ...d... */ ...e...


29

30

rnek 1 Bir dairenin evresini ve alann hesaplayan program.

/* lk C programm. * * * * Yarap verilen bir dairenin evresini ve alann hesaplar. */ #include <iostream> #include <stdlib.h> using namespace std; #define PI 3.14 int main(void) { float radius; float circum, area; cout << "Yarap yaznz: "; cin >> radius; circum = 2 * PI * radius; area = PI * radius * radius; cout << "evresi: " << circum << endl; cout << "Alan: " << area << endl; return EXIT_SUCCESS; // cout,cin,endl iin // EXIT_SUCCESS iin

31

C Diline Giri

Bu yapda birinci

/*

ile aklama balar. Aklamann iinde grlen ikinci

zard edilir ve gelen ilk

oluturur. Bundan sonra gelen blm (d blgesi) normal C kodu gibi deerlendirileceinden hataya yol aar.

*/

aklamay sona erdirir; yani aklamay

ve

/*

g-

blgeleri

kinci yntemde, aklama ift bl ile balar ve satrn sonuna kadar srer. satrdaki  cout,cin,endl satrdaki  EXIT_SUCCESS

1 Ksa

aklamalar iin bu yntem daha kullanldr. rnekteki ikinci aklama beinci

iin szcklerinden oluur. nc aklama da altnc iin szcklerini kapsar.

Komutlar

C dilinde komutlar noktal virgl ile sona erer. Pepee birden fazla boluk derleyici

tarafndan tek boluk olarak deerlendirilir; dolaysyla bir komutun bir satr iinde balayp sona ermesi zorunluluu yoktur. Yani

cout < < Alan:  < < area < < endl;
komutu

cout < < Alan:  < < area < < endl;
biiminde ya da

cout < < Alan:  < < area < < endl;
biiminde yazlabilirdi. C dilinde komutlarn noktal virgl ile sona ermesi ve fazla boluklar ile satr geilerinin Gelenek neminin olmamas nedeniyle komutlar satrlara istendii ekilde yerletirilebilir.Ancak bu konuda bir dzene uyulmazsa kodun okunmas ve anlalmas son derece zorlar. Okunabilirlii artrmak amacyla alt-bloklar bir miktar ieriden balatlrlar (girintileme ). Bylece ayn dzeydeki (ayn bloa ait) komutlar ayn hizadan balarlar. rnekte

fonksiyon bloundaki btn komutlar satr bandan drt harf ieriden balamaktadr. zellikle iie yaplarn kullanld durumlarda (seimin iindeki yinelemenin iindeki seimin iindeki seim gibi) bloklar hiyerarik bir ekilde girintilemek byk nem tar.

Atama

Atama ilemi eit iaretiyle yaplr. rnekteki

circum = 2 * PI * radius;
komutu bir atama komutudur, nine atar.

2 * PI * radius

deyiminin sonucunu

circum

deike-

1 2

Bu aklama yntemi C++ ile getirilmi bir yeniliktir, C dilinde geerli deildir. Tek atama komutuyla birden ok deikene ayn deer atanabilir. rnein

a = b = c = 24;
komutu

a, b ve c deikenlerinin ne de 24 deerini atar. Bu ilem sadan sola doru gerekletirilen pepee

atamalar eklinde dnlebilir:

c = 24; b = c; a = b;

simler

32

Fonksiyonlar

Blok yapl programlamadaki yordamlar C dilinde fonksiyonlar ile gerekleti-

rilir. Ana ii yapan fonksiyonun ad zorunludur.

main

olarak verilmelidir. Programn yrtlmesine

ana iten balanaca iin her programn bir ve yalnz bir

main

fonksiyonu bulunmas

C dilinde bir fonksiyonun ierdii komutlar bir blok olarak deerlendirilir. Bloklar assl-ayra ile balar ve kapa-ssl-ayra ile sona erer. Bu notlardaki ou rnekte fonksiyonu u ablona uyacaktr:

main

int main(void) { ... return EXIT_SUCCESS; }

Balk dosyalar

Kitaplklarda tanmlanm olan fonksiyonlar, birimler ya da byklkler

kullanld zaman derleyiciye bunlarla ilgili bilgileri nerede bulabileceini sylemek gerekir. Bu bilgilerin yer ald balk dosyalar program banda belirtilir. rnein ramda

cout

birimi

iostream

#include

komutuyla

balk dosyasnda bulunduundan rnek prog-

#include <iostream>
komutu yer almaktadr.

3 Benzer ekilde,

stdlib.h

EXIT_SUCCESS szcnn kullanlabilmesi iin

dosyas ierilmelidir.

Bir kitaplktan yararlanacanz zaman gerekli bilgilerin hangi balk dosyalarnda yer aldn bilmeniz gerekir. Temel fonksiyonlar standartlarda belirlenmi olduundan (bkz. Blm 1.6.4) bunlarn balk dosyalarn ou C/C++ kitabnda bulabilirsiniz. Standartlara girmemi fonksiyonlar iinse kullandnz derleyici ve kitaplklarn yardmc belgelerine bavurmalsnz.

2.1

simler

Programlardaki deiken, fonksiyon gibi varlklara verilen isimlerin baz kurallara uymalar gerekir:

simler, ngilizce byk ve kk harer, rakamlar ve altizgi iaretinden oluabilir. Bu kurala gre

weight-1

pi, weight, weight1

ve

weight_1

geerli isimlerdir, ancak

, arlk

ve

geerli isimler deildir.

smin ilk simgesi bir rakam olamaz. Bu kurala gre

2weight

geerli bir isim deildir.

C standardnda balk dosyalarna

ts bulunmayabilir. rnekteki nektir.

.h uzants verilir. C++ standardnda ise baz balk dosyalarnn uzaniostream balk dosyas C++ ile tanmlanm yeni balk dosyalarna bir r-

Unix iletim sistemlerinde yardmc belgeler ile ilgili bilgi iin bkz. Ek B.1.

33

C Diline Giri

smin en az ilk 31 simgesi anlamldr. Baka bir deyile, ilk 31 simgesi ayn olmayan iki ismin farkl olaca kesindir ama aynlarsa derleyici bu iki ismin farkl olmadna karar verebilir. rnein

population_increase_between_years_2000_and_2001 ile population_increase_between_years_2001_and_2002 isimli iki deiken tanmlanrsa


ilk 31'er simgeleri ayn olduundan baz derleyiciler bu ikisinin ayn deiken olduklarna karar verebilir.

simlerde byk-kk harf ayrm vardr. Yani

weight1, Weight1, WEIGHT1 ve wEiGHT1 int, main, void, return


geerli

isimlerinin hepsi geerli olmakla birlikte hepsi birbirinden farkldr. C dilinin szckleri isim olarak seilemez. Yani rnein isimler arasnda deildir. Szgelimi, istenirse bu durumda kt iin kullanlan

isimler deildir. Kitaplklardan alnan fonksiyon ya da dier varlklarn isimleri sakl

cout

cout isimli bir deiken kullanlabilir ancak

kitaplk biriminden artk yararlanlamaz.

Byk projelerde isim akmalar sorun yaratmaya balar. Bu durumu dzeltmek amacyla isim uzaylarndan yararlanlr. Bu kitaptaki rnekler kk boyutta olduklar iin bu sorunlar gzard edilecek ve standart isim uzaynn kullanldn belirtmek zere programn banda

using namespace std;


bildirimi yaplacaktr. Bu bildirim

cin, cout

ve

kullanlmazsa bu deerlere eriim iin balarna

endl deerlerine kolay std:: eklemek gerekir:

eriimi salar;

std::cin > > radius; std::cout < < Area:  < < ... < < std::endl;
simlerin seiminde ou programcnn uyduu baz gelenekler vardr:
Gelenek

Deiken ve fonksiyon isimleri kk harerle balar. Baka bir deyile, byk harer ya da altizgi iaretiyle balamaz. Deiken ve fonksiyonlara gsterdikleri bilgiye ya da yaptklar ie uygun den, anlaml bir isim verilir. Szgelimi bir insann arl bilgisini tutacak bir deikene anlamsz ya da

height

x4szb

gibi

gibi yanltc isimler verilmez.

Anlaml isimler verilmek istendiinde bazen birden fazla szce gereksinim duyulabilir. Bu durumda ya ismi oluturan iki szck bir altizgi iaretiyle birletirilir (rnein

birth_month)

ya da ikinci szck byk hare balar (rnein

birthMonth).

2.2

Deerler

Tamsaylarn doal gsterilimleri onlu dzendedir, ancak istenirse sekizli ya da onaltl dzende de gsterilebilirler. rnekte 2 says onlu gsterilimde yazlm bir tamsaydr. 0 rakamyla balayan saylarn sekizli, 0x ile balayanlarn onaltl dzende olduklar varsaylr. Buna gre, 59 says sekizli dzende 073, onaltl dzende 0x3b olarak yazlr.

Deikenler

34

Kesirli saylarn doal gsterilimi noktal gsterilimdir, ancak istenirse bilimsel gsterilim (mantis * 10

us ) de kullanlabilir. rnekte 3.14 says noktal gsterilimde yazlm bir ke2 ) olarak

sirli saydr. Saynn yazlnda E simgesi geiyorsa bu simgenin ncesi mantis, sonras s olarak deerlendirilir. Buna gre, 3.14 says bilimsel gsterilimde 314E-2 (314 * 10 yazlabilir. Simgeler tek, katarlar ift trnak iaretleri arasnda yazlrlar. rnekte Alan:  deeri bir katardr; yalnzca A harnden sz edilmek isteniyorsa 'A' eklinde yazlr. Katar iinde yazlan her boluun nemi vardr, yani szgelimi pepee be boluk brakldnda bu bir boluk olarak deil, be boluk olarak deerlendirilir. rnein Alan ile iki nokta stste iareti arasnda be boluk bulunacaktr. :  katarnda Alan szc

2.3

Deikenler

C dilinde, bir deikene bir deer vermeden ya da deerini bir hesapta kullanmadan nce deikenin tanmlanmas gerekir. Tanmlama ilemi, bellekte gerektii kadar yerin bu deiken iin ayrlmasn salar; bylece sistem, bellekte ayrlan bu yeri bu deiken iin kullanr ve baka ilerde kullanmaz. Tanmlama, deikenin tipinin ve adnn belirtilmesinden oluur. rnekte

float radius;
tanm derleyiciye yarar. Ayn tipten olan deikenler ayn tanmn iinde yer alabilirler. rnekteki

radius adnda bir deiken olduunu ve bir kesirli say tutacan belirtmeye

float circum, area;


tanm, her ikisi de birer kesirli say olan,

circum

ve

area

adnda iki deiken kullanacamz

anlamna gelir. rnekteki tanmlar istenirse

float radius; float circum; float area;


eklinde ayrlarak ya da

float radius, circum, area;


eklinde birletirilerek de yazlabilirdi. Tanm srasnda istenirse deikene balang deeri de verilebilir:

float radius, circum = 0.0, area = 0.0;

35

C Diline Giri

Bu durumda tanm srasnda

radius
Gelenek

circum

ve

area

deikenlerinin her ikisine de 0.0 deeri verilir,

deikenine bir balang deeri verilmez.

Deikenlere balang deeri atanmas yararl bir alkanlktr. Balang deeri atanmazsa deiken rasgele bir deer alabilir ve programcnn dikkatsiz davranmas durumunda bu rasgele deer yanllkla hesaplarda kullanlabilir ve istenmeyen sonulara yol aabilir. Genelde bir blok iindeki deiken tanmlar ile komutlar birbirlerinden ayrlr, yani kullan- Gelenek lacak btn deikenlerin tanmlar bittikten sonra komutlar balar. arasnda bir satr boluk braklr.

5 Tanmlarn sona erdii

ve komutlarn balad yerin kolayca grlmesini salamak amacyla tanmlar ile komutlar

2.4

Veri Tipleri

C dilinde tanmlanan taban veri tipleri unlardr (bkz. Blm 1.1.1): tamsay

int sakl szcyle belirtilir. Bu veri tipi short ve long belirteleriyle gelitirilerek ksa tamsay (short int) ve uzun tamsay (long int) tipleri oluturulabilir.
Aksi belirtilmedike tamsay tiplerinin iaretli olduklar varsaylr, yani hem pozitif hem de negatif deerler alabilirler. Deiken yalnzca pozitif saylardan (0 da olabilir) deer alacaksa iaretsiz olarak tanmlamak iin lir. Ksacas, 6 adet tamsay tipi vardr:

unsigned short int


kesirli say

ve

unsigned szc kullanlabiint, short int, long int, unsigned int, unsigned long int. double)
tipleri

nirse ifte duyarllkl (double) ya da uzun ifte duyarllkl (long kullanlabilir. simge

float

sakl szcyle belirtilir. Say daha yksek duyarllkla gsterilmek iste-

char

sakl szcyle belirtilir. Simgeler kullanlan kodlamadaki sralarna gre

deerler alrlar (bkz. Ek A). rnein 'A' har ASCII kodlamasnda 65. srada olduundan 'A' simgesinin say deeri 65'tir. mantksal

bool

sakl szcyle belirtilir. Bu tipten deikenler

alabilirler.

true

ya da

false

deerini

Bir deikenin tanmlanaca veri tipi, o deikenin alabilecei deer araln belirlediinden son derece nemlidir. Bu nedenle bir deikenin veri tipine karar verirken o veri tipinin izin verdii deer aralna dikkat etmek gerekir. Szgelimi

short int

veri tipi yalnzca -32768

ile +32767 arasndaki saylarn gsterilebilmesine olanak veriyorsa ve sizin tanmlayacanz deikenin 45000 deerini almas szkonusu olabilecekse deikeninizi bu tipten tanmlamamalsnz. Bir veri tipinin boyu

sizeof

ilemi yardmyla belirlenebilir. Her deiken bellekte

bu boy kadar yer kaplar (sekizli cinsinden). Ksa tamsay veri tipinin boyunun 2 sekizli yani 16 bit olduunu varsayalm. Bu boy hem iaretli hem de iaretsiz ksa tamsaylar iin geerlidir. Bu durumda iaretsiz ksa tamsay cinsinden tanmlanan bir deikenin alabilecei en kk deer 0, en byk deer ise yani 65535 olacaktr.

216 1

5 6

C++ dilinde komutlar baladktan sonra da deiken tanmlanabilir. C dilinde buna izin verilmez. C dilinde mantksal verileri temsil edecek zel bir veri tipi yoktur, bu tip C++ dilinde getirilmitir; yani ve

bool, true

false

szckleri geerli C szckleri deildir.

Deimezler

36

2.5

Deimezler

Programda kullanlan baz bilgiler de programn farkl almalar arasnda deer deitirmezler. rnekteki

PI

says ve dairenin evresinin hesaplanmasnda kullanlan 2 says bu tipten

byklklerdir. Deimezlerin bazlarna isim vermek birtakm kolaylklar salar:

Anlalrl artrr. Programn iinde 3.14 yazmak yerine

PI

yazmak program okuyan

birinin bu saynn neye kar dtn daha kolay anlamasn salar. Deitirmek kolay olur. Diyelim programn gelitirilmesinin ileri aamalarnda 3.14 deerinin yetersiz kaldna ve 3.14159 deerinin daha uygun olduuna karar verirsek kod iinde tek bir noktada deitirmek yeterli olur. br trl, kodun iindeki btn 3.14 saylarnn yerine 3.14159 yazmamz gerekir. Daha da kts, kodun iindeki baka byklkleri gsteren 3.14 deerlerinin de gemesi olasldr. Bu durumda btn 3.14 deerlerini tek tek inceleyerek deitirilip deitirilmeyeceine karar vermek gerekir.

Deimezler iki ekilde tanmlanabilirler:

1.

#define

bildirimiyle tanmlama. Bu yntem bir deere bir isim vermekte kullanlr.

rnekte yaplan 3.14 saysna kod iinde

PI ismini vermektir. Bu bildirimin sonucu, programcnn PI geen her yere kendisinin 3.14 deerini yazm olmasyla ayndr. Bu ekilde

tantlan deimezlere gelenek olarak tamam byk harerden oluan isimler verilir. Bu bildirim ynteminde deimezlerin tipleri ayrca belirtilmez. Tamsay deimezler

int

tipine smyorlarsa

eklenirse

long, u

ya da

long int
eklenirse

varsaylrlar. Deerlerinin sonuna

unsigned

ya da

hareri

belirteci seilmi olur.

#define MAXSHORT 0x7FFF #define MAXUSHORT 65535U


Kesirli deimezlerin deerlerinin sonuna duklar varsaylr.

ya da

eklenirse

f ya da F eklenmemise double long double tipinden olurlar.

tipinden ol-

#define EULER 2.81782F #define PERCENT 1E-2


2. Deiken tanmna benzer ekilde ancak veri tipinin nne

const

niteleyicisi koyarak

tanmlama. Bylece deeri deitirilemeyen bir deiken tanmlanm olur. Bu ekilde tanmlanan deimezlere byk harerden oluan isimler verilmez. rnekteki mezinin bu yntemle tanm yle olurdu:

PI

dei-

const float pi = 3.14;


Her iki tanmda da deimez olarak bildirilmi bir bykle deer atanmaya alrsa derleyici hata verir.

C dili

const

ile tanmlanm deimezlerin deerlerinin deitirilebilmesine izin verir. Bu tipten bir dei-

kene atama yaplmak istendiinde derleyici hata deil, yalnzca bir uyar retecektir.

37

C Diline Giri

2.6

Aritmetik Deyimler

Aritmetik deyimlerde kullanlabilecek ilemler unlardr:

Toplama: kartma: arpma: Blme: Kalan:

+ -

ileciyle gereklenir. ileciyle gereklenir.

ileciyle gereklenir.

/ %

ileciyle gereklenir. ileciyle gereklenir. Yalnzca iki tamsay arasnda yaplabilir, kesirli saylarda

tanml deildir.

Bunlarn yansra matematik kitaplnda yer alan fonksiyonlar da aritmetik deyimlerde yer alabilirler (bkz. Blm 2.9). Komutlarn okunurluunu artrmak amacyla C programclarnn uyduklar geleneklerden biri Gelenek de, eit iaretinin ncesinde ve sonrasnda birer boluk brakmaktr. Benzer ekilde, deyimlerde yer alan ilelerin (rnekte

simgesi) nce ve sonralarnda da birer boluk braklr.

C'de deyimlerin hesaplanmasnda izlenen ncelik sras, matematikten alk olunan sradr. Yksek ncelikliden alak ncelikliye doru ncelik gruplar yledir:

1. Ayra iindeki deyimler 2. Say iareti belirten

ve

ilemleri, artrma, azaltma

3. arpma, blme, kalan 4. Toplama, karma

Eit ncelik gruplar kendi ilerinde soldan saa doru deerlendirilirler.

rnek.
a+b+c+d+e 5
aritmetik deyimi C'de

(a + b + c + d + e) / 5
eklinde yazlmaldr. Ayralar kullanlmazsa ortaya kan

a + b + c + d + e / 5

Tip Dnmleri

38

C deyimi

a+b+c+d+
aritmetik deyimine kar der.

e 5

rnek.
p * r % q + w / x - y
deyimi u srayla hesaplanr:

t1: t2: t3: t4: t5:


2.7

p * r t1 % q w / x t2 + t3 t4 - y

Tip Dnmleri

leme giren saylarn her ikisi de tamsay ise sonu da tamsay olur. Saylardan herhangi birinin kesirli say olmas durumunda sonu da kesirli say olacaktr. Bu durum blme ileminde dikkat edilmesi gereini dourur. Blme ilemine giren her iki say da tamsay ise sonu da tamsay olacaktr, yani sonucun varsa kesir ksm atlacaktr. rnein

14 / 4

deyiminin sonucu 3.5

deil 3 olacaktr. leme giren her iki say da tamsay ise ve sonucun kesir ksmnn yitirilmemesi isteniyorsa saylardan en az birinin kesirli say olmasn salamak gerekir. Yukardaki rnek iin zm u yazllarla salanabilir:

14.0 / 4 14 / 4.0 14.0 / 4.0


Bir blme ilemine giren iki deikenin ikisinin de tamsay tipinden olmas durumunda sonu yine tamsay olacaktr. rnein

int num1 = 14, num2 = 4; float quotient; quotient = num1 / num2;


ilemleri sonucui mak iin

num1

ve

quotient deikeni 3.0 deerini alr. lemin doru olarak yaplmasn salanum2 deikenlerinden en az birinin kesirli say tipine evrilmesi gerekir. Bu

ileme tip zorlama ad verilir ve bir deyimin bana ayra iinde deyimin sonucunun almas istenen tipin adnn yazlmasyla yaplr. Yukardaki rnein doru almas iin u komutlardan herhangi biri kullanlabilir:

39

C Diline Giri

quotient = (float) num1 / num2; quotient = num1 / (float) num2; quotient = (float) num1 / (float) num2;
Birinci komutta yalnzca

num1

deikeni, ikinci komutta yalnzca

num2

deikeni, nc ko-

mutta ise her ikisi birden kesirli sayya evrilmektedir. Buna karlk

quotient = (float) (num1 / num2);


komutu ise nce blmeyi sonra tip zorlamasn yapacandan deerini atar. Genel olarak, bir ileme giren saylar farkl tiptense, bunlarn ortak bir tipe evrilmeleri gerekir. Dar tipten geni tipe gei ilemleri derleyici tarafndan otomatik olarak yaplr. rnein, bir toplama ileminin ilenenlerinden biri tamsay dieri kesirli say ise tamsay olan kesirli sayya evrilir ve toplama yaplr. Aadaki rnekte toplama ileminin ikinci ileneni kesirli say olduundan toplamadan nce

quotient

deikenine yine 3.0

num1

deikeni kesirli sayya evrilecektir:

int num1 = 14; float sum; sum = num1 + 7.32;


Geni tipten dar tipe geiler ise bilgi yitirilmesine neden olabilirler. rnein kesirli say tipinden bir deikenin tamsay tipinden bir deikene atanmas srasnda saynn kesir ksm yitirilebilir:

int num1; float num2 = 65.717; num1 = num2;


Derleyiciler bu gibi durumlarda genelde hata deil yalnzca uyar retirler.

2.8

Artrma / Azaltma

Bir atamann sa tarafndaki deyim, atamann sol tarafndaki deikeni ieriyorsa, yani

deiken = deiken deyim;


( herhangi bir ilem simgesi olabilir) eklindeyse bu komut

deiken = deyim;

Matematik Kitapl

40

eklinde ksaltlabilir. rnein:

a += 5; a /= 2; a *= c + d;

// a = a + 5; // a = a / 2; // a = a * (c + d);

Buna gre, bir deikenin deerini artrmak ya da azaltmak iin aadaki komutlar kullanlabilir:

a = a + 1; a += 1; a = a - 1; a -= 1;
Ancak artrma ve azaltma ilemleri programlarda ska gereksinim duyulan ilemlerden olduklarndan C'de bunlar iin zel ileler tanmlanmtr. deikenin deerini 1 artrr;

++ ileci, nne ya da arkasna yazld -- ileciyse nne ya da arkasna yazld ilecin deerini 1 azaltr.
8

Her iki ile de yalnzca tamsay veri tipleri ile alrlar ve basit kullanmda ilecin deikenin nne mi arkasna m yazldnn bir nemi yoktur:

a++; a--; ++a; --a;

2.9

Matematik Kitapl

ANSI standard, bir C derleme ortamnn matematik kitaplnda bulunmas zorunlu olan fonksiyonlar belirler. Bu fonksiyonlarn kullanlabilmesi iin programlarn banda balk dosyasnn alnmas gerekir. Matematik kitaplnn en sk kullanlan fonksiyonlar Tablo 2.1'de verilmitir. Btn bu fonksiyonlardaki

math.h

ve

giri parametreleri

double

tipindendir ve k parametresi de

double

tipinden olacaktr.

Artrma ve azaltma ilemleri baka ilemlerle birlikte kullanlabilir. Szgelimi bir artrma ilemiyle bir

atama ilemi ayn komut ierisinde yaplabilir. Byle durumlarda artrma/azaltma ilecinin deiken adnn nne ya da arkasna yazlmas nem kazanr. nne yazldnda nce artrma, sonra atama yaplacaktr. Arkasna yazldndaysa nce atama, sonra artrma yaplr. Yani

y = ++x;
komutu

x++; y = x;
koduna kar derken

y = x++;
komutu

41

C Diline Giri

Ad

levi trigonometrik fonksiyonlar ters trigonometrik fonksiyonlar hiperbolik trigonometrik fonksiyonlar

sin(x) cos(x) tan(x) asin(x) acos(x) atan(x) sinh(x) cosh(x) tanh(x) exp(x) log(x) log10(x) pow(x,y) sqrt(x) floor(x) ceil(x) fabs(x)

ex e ve 10 xy x |x|

tabannda logaritma fonksiyonlar

alt ve st snr fonksiyonlar:

Tablo 2.1: Matematik kitapl fonksiyonlar.

Trigonometrik fonksiyonlarda giri parametresi derece deil radyan cinsinden verilmelidir; rnein sin(30) deyimi 0.5 deil -0.988032 deerini retir. 30 derecenin sinsn sin(30*3.141529/180) ya da sin(3.141529/6) deyimini yazmak gerekir. almak iin

Alt ve st snr fonksiyonlarnn almasnda giri parametresinin pozitif ya da negatif olmasna dikkat edilmelidir. Alt snr fonksiyonu her zaman o saydan daha kk olan ilk tamsayy, st snr fonksiyonu ise o saydan daha byk olan ilk tamsayy verir.

floor(3.1) 3, floor(-3.1) -4 ceil(3.1) 4, ceil(-3.1) -3


Tamsaylar iin de tamsay giri parametresi alan ve tamsay k parametresi reten isimli bir mutlak deer fonksiyonu vardr.

abs

2.10

Giri / k

C dilinde kullancyla iletiimi salayan ilemler giri/k birimleri zerinden yaplr (bkz. Blm 1.5). Girdiler

9 gnderilir.
rnekteki

cin biriminden alnrken, ktlar cout, hatalar da cerr biriminebirimine

cin > > radius;


y = x; x++;
koduna kar der.

C dilinde

cin, cout ve cerr birimleri yoktur, bunlarn yerine standart girdi/kt kitaplndaki fonksiyon-

larn kullanlmas gerekir (bkz. Ek 8).

Giri / k

42

komutu sonucunda

radius

deikeni kullancnn tutakmndan yazd saynn deerini alr.

Birden fazla deiken birlikte okunmak isteniyorsa bunlar birbiri ardna > > iaretleriyle belirtilebilir. Szgelimi, iki tane say deeri okunacak ve kullancnn yazd birinci saynn deeri

num1,

ikinci saynn deeriyse

num2

deikenine aktarlacaksa:

cout < < Saylar yaznz: ; cin > > num1 > > num2;
gibi bir program paras kullanlabilir. Bu rnekte kullancnn saylar yazarken aralarnda bir boluk brakmas gerekir. k birimlerine katarlar ya da deyimler gnderilebilir. Katarlar olduklar gibi yazlrken deyimlerin deerleri grntlenir. rnekteki

cout < < Alan:  < < area < < endl;
komutu ekrana nce

satra geer. Programda

Alan:  katarn, daha sonra area deikeninin deerini yazar ve yeni circum ve area deikenleri tanmlanmadan ve atama komutlar

kullanlmadan kt ilemleri

cout < < evresi:  < < 2 * PI * radius < < endl; cout < < Alan:  < < PI * radius * radius < < endl;
komutlaryla da yaplabilirdi.

Uygulama: Gelitirme Ortam


Bu uygulamada basit giri/k ilemlerine ve matematik kitaplnn kullanmna rnek verilmesi istenmektedir. Grak bir editr (kate) tantlacak ve C derleyicisinin nasl kullanlaca retilecektir. Basit hatalarda derleyicinin hangi mesajlar rettii gzlenecektir.

10

rnek 2. Forml Hesab

y = ex

formlnde

deerini kullancdan alarak

deerini hesaplayan ve ekrana yazdran

bir program yazlmas isteniyor.

rnekte verilen program yazn, derleyin ve altrn.

y'nin

iin 0.002 deerini verdiinizde

ald deeri gzleyin.

PI deimezinin tanmn 3.14 yerine 3.14159 olarak verin ve ayn x deerinde y'nin ald
deeri gzleyin.

10

Deiken tanmlarnn yapld

Unix iletim sistemlerinde derleme aamalar ile ilgili bilgi iin bkz. Ek B.2.

43

C Diline Giri

rnek 2 y = ex

formln hesaplayan program.

#include <iostream> #include <stdlib.h> #include <math.h> using namespace std; #define PI 3.14 int main(void) { float x, y; cout << "x: "; cin >> x; y = exp(-PI * x); cout << "y: " << y << endl; return EXIT_SUCCESS;

// cout,cin.endl // EXIT_SUCCESS // exp

float x, y;
satrndaki 'x' harni 'X' ile deitirin ve derleme sonucunda oluan hatay gzleyin.

rnekteki

cin > > x;


satrnn ardna

PI = 3.14159;
komutunu ekleyin ve derleme sonucunda oluan hatay gzleyin.

Bir nceki admda yaptnz deiiklii silmeden, rnekte

#define

PI deimezinin tanmland

satrn silin ve

float x, y;
satrnn ardna

const float PI = 3.14;


deimez tanmn ekleyin. Derleme sonucunda oluan hatay gzleyin.

Bataki

#include <math.h>

satrn silin ve derleme sonucunda oluan hatay gzleyin.

Giri / k

44

Sorular
1. altnz gelitirme ortamnda

int

tabanl veri tiplerinin deer aralklarn belirleyin

ve bu aralklar dnda bir deer atandnda nasl bir sonu elde edildiini gzleyin. 2. Aadaki deyimlerin sonularn bulun:

8 + 17 % 3 * 5 45 / (4 + 7) - 5.0 / 2
3. Aadaki aritmetik deyimleri gerekleyen C deyimlerini yazn:

1 2ab

g cd efh x(y + z)

4. Aadaki C deyimlerinin gerekledii aritmetik deyimleri yazn:

a + 3 * b - (c + d) / 2 * y;

Blm 3
Ak Denetimi

Bu blmde blok yapl programlamada gereken seim ve yineleme yaplarnn C dilinde nasl gereklendikleri zerinde durulacaktr.

rnek 3. kinci Derece Denklem Kkleri


kinci dereceden (ax

+ bx + c = 0

eklinde) bir denklemin kklerinin yerlerini belirleyen bir

program yazlmas isteniyor. Diskriminantn

b2 4ac

eklinde tanmlandn ve kklerin

x1,2 =

b2 4ac 2a

formlne gre hesaplanacan gznnde bulundurarak, program denklemin katsaylarn kullancdan aldktan sonra aadaki ilemleri gerekletirecektir:

Denklemin gerel kk yoksa (diskriminant negatifse) bu durum kullancya bildirilir. Denklemin kkleri akksa (diskriminant sfrsa) bu durumu kk deeriyle birlikte kullancya bildirilir.

Denklemin iki farkl gerel kk varsa (diskriminant pozitifse) bunlar hesaplanarak ekrana kartlr.

Programn rnek bir almasnn ekran kts ekil 3.1'de verilmitir

a, b ve c katsaylarn yaznz: -2 1 9.2 -1.90928 ve 2.40928 noktalarnda iki gerel kk var.

ekil 3.1: rnek 3 ekran kts.

45

46

rnek 3 kinci dereceden bir denklemin kklerini bulan program.


#include <iostream> #include <stdlib.h> #include <math.h> // cout,cin,endl // EXIT_SUCCESS // sqrt

using namespace std; int main(void) { float a, b, c; float disc; float x1, x2; cout << "a, b ve c katsaylarn yaznz: "; cin >> a >> b >> c; disc = b * b - 4 * a * c; if (disc < 0) cout << "Gerel kk yok." << endl; else { if (disc == 0) { x1 = -b / (2 * a); cout << x1 << " noktasnda akan iki kk var. " << endl; } else { x1 = (-b + sqrt(disc)) / (2 * a); x2 = (-b - sqrt(disc)) / (2 * a); cout << x1 << " ve " << x2 << " noktalarnda iki gerel kk var." << endl; } } return EXIT_SUCCESS;

47

Ak Denetimi

3.1

Koul Deyimleri

Blok yapl programlamadaki seim ve yineleme yaplarnda bir koula gre bir karar verilmesinin salanmas gerektii grlmt (bkz. Blm 1.3). Koullar, koul deyimleriyle gsterilirler. C dilinde bir koul deyimi, iki saysal bykln (aritmetik deyimin) karlatrlmas ile oluturulur ve mantksal bir deer (doru ya da yanl) retir. Dier btn veri tipleri gibi mantksal deerler de saylarla temsil edilirler; yanl deeri 0, doru deeriyse 1 saysyla gsterilir.

3.1.1

Karlatrma lemleri

ki say deeri arasnda u karlatrma ilemleri yaplabilir:

Eitlik:

== ileciyle gereklenir. lecin solundaki deerle sandaki deer aynysa doru,

farklysa yanl sonucunu retir. Farkllk: != ileciyle gereklenir. Eitlik karlatrmasnn tersidir. lecin solundaki deerle sandaki deer farklysa doru, aynysa yanl sonucunu retir. Kklk:

< >

ileciyle gereklenir. lecin solundaki deer sandaki deerden kkse

doru, kk deilse yanl sonucunu retir. Byklk: ileciyle gereklenir. lecin solundaki deer sandaki deerden bykse

doru, byk deilse yanl sonucunu retir. Kklk veya eitlik: retir.

<= ileciyle gereklenir. Byklk karlatrmasnn tersidir. le-

cin solundaki deer sandaki deerden kk veya eitse doru, bykse yanl sonucunu

Byklk veya eitlik: retir.

>= ileciyle gereklenir. Kklk karlatrmasnn tersidir. le-

cin solundaki deer sandaki deerden byk veya eitse doru, kkse yanl sonucunu

rnekler

Yl 4'e kalansz blnebiliyor mu?

(year % 4) == 0

Ya 18'den byk ya da eit mi?

age >= 18
Karlatrma ilemleri tam ya da kesirli saylarn karlatrlmasnda kullanlabilecei gibi, harerin abecedeki sralarna gre karlatrlmasnda da kullanlabilir. Szgelimi

'm' < 'u'

Koul Deyimleri

48

koul deyimi doru deerini retir. Ancak bu ilem yalnzca ngilizce harer arasnda doru sonu retecektir. Ayrca, byk-kk harf karlatrmalarnda da abece srasndan farkl sonular kabilir. rnein u koul deyimi doru deerini retir:

'Z' < 'a'


Bu nedenlerle, simgelerin karlatrlmas yalnzca ngilizce harer iin ve ikisi de byk ya da ikisi de kk harerin karlatrlmasnda kullanlmaldr.

1 Ayrca, karlatrma ileleriyle

katarlar abece srasna gre karlatrlamaz, yani aadaki komut geerli deildir (doru ya da yanl sonucunu retmez, derleyicinin hata vermesine neden olur):

dennis < ken


Kesirli saylarn eitlik asndan karlatrlmasnda da dikkatli olunmas gerekir. Kesirli saylar bilgisayarlarda tam olarak temsil edilemeyebileceklerinden bunlar arasnda eitlik karlatrmas yapmak hatal sonular dourabilir. Genellikle farklarnn mutlak deerinin yeterince kk bir say olup olmadna bakmak daha emin bir yntemdir. rnein

f1 == f2
yerine aadaki gibi bir koul yazlabilir:

fabs(f1 - f2) < 1E-6


3.1.2 Mantksal lemler

Baz durumlarda tek bir karlatrma ilemi btn koul deyimini oluturmak iin yeterli olmaz. rnein bir insann yann 18 ile 65 arasnda olup olmadn snamak istiyorsanz, bunu tek bir karlatrma ilemiyle yapamazsnz (18 retilebilir. tane mantksal ilem vardr: DEL ilemi: ! ileciyle gereklenir. nne yazld koul deyimini deiller, yani doruysa yanl, yanlsa doru deerini retir (bkz. Tablo 3.1).

<= x < 65

gibi bir deyim yazlamaz). Byle

durumlarda, karlatrma ilemleri mantksal ilemlerle balanarak karmak koul deyimleri

koul
doru yanl

!(koul)
yanl doru

Tablo 3.1: Deil ilemi doruluk tablosu.

rnek

Ya 18'den kk deil:

!(age < 18)

49

Ak Denetimi

koul1
doru doru yanl yanl

koul2
doru yanl doru yanl

(koul1) && (koul2)


doru yanl yanl yanl

Tablo 3.2: VE ileminin doruluk tablosu.

VE ilemi:

&&

ileciyle gereklenir. Balad koullarn hepsi doruysa doru, en az biri

yanlsa yanl deerini retir (bkz. Tablo 3.2).

rnek

Ya 18'den byk veya eit ve 65'den kk:

(age >= 18) && (age < 65)


VEYA ilemi:

||

ileciyle gereklenir. Balad koullarn hepsi yanlsa yanl, en az

biri doruysa doru deerini retir (bkz. Tablo 3.3).

koul1
doru doru yanl yanl

koul2
doru yanl doru yanl

(koul1) || (koul2)
doru doru doru yanl

Tablo 3.3: VEYA ileminin doruluk tablosu.

rnek

Ya 18'den kk veya 65'den byk veya eit:

(age < 18) || (age >= 65)

rnek

Bir yln artk yl olup olmadn belirleyen koul deyimi. Sonu 00 ile biten (100'e

kalansz blnen) yllar dndaki yllar 4 saysna kalansz blnyorlarsa artk yl olurlar. Sonu 00 ile bitenler ise 400 saysna kalansz blnyorlarsa artk yldrlar. Bunlarn dnda kalan yllar artk yl deildir. Szgelimi, 1996, 2000, 2004 ve 2400 yllar artk yldr ama 1997, 2001, 1900 ve 2100 yllar artk yl deildir.

((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)


Ayralar kullanlmadnda mantksal ilelerin ncelikleri yksek ncelikliden balayarak DEL, VE, VEYA srasyladr. Buna gre yukardaki rnek

(year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)


ya da

Aslnda burada karlatrlan bu iki simgenen ASCII kodlamasndaki sralardr.

Seim

50

(year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0)


biiminde de yazlabilirdi.

3.2

Seim

C dilinde seim yaplar, alyorsa

if

ile balayan blok (blok1), yanl deerini alyorsa

if/else

bloklaryla gereklenir. Verilen koul deyimi doru deerini

else

ile balayan blok (blok2)

yrtlr:

if (koul ) { blok1 ; } else { blok2 ; }


rnekte iie iki seim yaps vardr. teki seim yaps u ekildedir:

if (disc == 0) { x1 = -b / (2 * a); cout < < x1 < <  noktasnda akan iki kk var. < < endl; } else { x1 = (-b + sqrt(disc)) / (2 * a); x2 = (-b - sqrt(disc)) / (2 * a); cout < < x1 < <  ve  < < x2 < <  noktalarnda iki gerel kk var. < < endl; }
Burada

disc deikeninin deeri 0 ise akk kklerle ilgili ilemler yaplr (iki komuttan oluan

bir blok); deilse farkl iki gerel kk bulunmas durumundaki ilemler yaplr ( komuttan oluan bir blok). Seim yaplarnda bir

else

blou bulunmas zorunlu deildir, yani yap

if (koul ) { blok ; }
2
Birden fazla kouldan oluan mantksal deyimler deerlendirilirken sonu belli olduu zaman deyimin geriye kalan hesaplanmaz. rnein

(year % 4 == 0) && (year % 100 != 0)


deyiminde ndan

(year % 4 == 0) koulu yanl deerini verirse deyimin (year % 100 != 0) koulu snanmaz. Benzer ekilde (year % 4 == 0)

geri kalanna baklmaya gerek kalmayaca-

(year % 4 == 0) || (year % 100 != 0)


deyiminde koulu doru deerini verirse yine ikinci koul snanmaz.

51

Ak Denetimi

eklinde olabilir. Bu durumda koul doruysa blok yrtlr, deilse hibir ey yaplmaz. Bir blok tek bir komuttan oluuyorsa bloun ssl ayralar ile snrlanmas zorunlu deildir. rnekteki d seim yapsnda dikkat edilirse koulun doru olmas durumunda yrtlecek blokta ssl ayralar kullanlmamtr:

if (disc < 0) cout < < Gerel kk yok. < < endl; else { ... ... ... }
Burada istenseydi birinci blok da ssl ayralarla belirtilebilirdi:

if (disc < 0) { cout < < Gerel kk yok. < < endl; } else { ... ... ... }
Gelenek olarak tek komutlu bloklarda ssl ayralar kullanlmaz, yani rnek programda kul- Gelenek lanlan yazl ekline uyulur. Ancak bu durumda ssl ayra kullanlmayan bloun tek komut iermesine ok dikkat etmek gerekir. Dier bir gelenek de, koulun doru ya da yanl olmasna gre yrtlecek bloklardan biri dierine gre ok ksaysa, ksa olan blok ste gelecek (koulun doru olmas durumunda yrtlecek) ekilde dzenlenmesidir. rnekte bu gelenee uyulmam olsayd d seim yaps u ekilde yazlabilirdi:

if (disc >= 0) { ... ... ... } else cout < < Gerel kk yok. < < endl;
Seim ve ileride grlecek yineleme yaplar bir btn olarak tek bir komut olarak deerlendirilirler. Dolaysyla bir blokta yer alan tek yap baka bir seim ya da yineleme blouysa ssl ayralarn kullanlmas zorunlu deildir. Yani u blok

if (koul1 ) { if (koul2 ) blok ; }

Seim

52

u ekilde de yazlabilir:

if (koul1 ) if (koul2 ) blok ;


Ssl ayralar kullanlmadnda iie lenmeden yazlm u rnee bakalm:

if / else

yaplarnda belirsizlikler oluabilir. Girinti-

if (koul1 ) if (koul2 ) blok1 ; else blok2 ;


Burada

blok2

hangi koul salanmazsa yrtlecektir? C dilinin bu konudaki kural

kendinden nce gelen son

koul2

if

kouluna balanddr, yani rnekte

blok2 , koul1

else'in

doru ve

yanlsa yrtlr. Doru bir girintilemeyle yazlrsa

if (koul1 ) if (koul2 ) blok1 ; else blok2 ;


Yine de karkla neden olmamas iin byle durumlarda ssl ayralar kullanmak daha dorudur.
DKKAT

Herhangi bir aritmetik deyim koul deeri olarak deerlendirilebilir; deyimin sonucu 0 ise yanl, 0'dan farkl ise doru olduu varsaylr. Buna gre, szgelimi 8 - 2 deyimi doru, 8 - 2 * 4 deyimiyse yanl bir koul olarak deerlendirilir. Bu davran zellikle eitlik karlatrmalarnda hataya yol aabilir. En sk yaplan C hatalarndan biri bir eitlik karlatrmasnda yerine

==

iareti kullanlmasdr.

age = 12; ... ... if (age = 18) blok1 ; else blok2 ;


Yukardaki programda koulun snanmas srasnda eitlik ilemi deil atama ilemi belirtildiinden

age

deikenine 18 atanr, deyimin deeri 18 olarak bulunur ve 0'dan farkl olduu

iin doru saylarak deimez ve

blok2

blok1

yrtlr. Oysa

==

simgesi kullanlsayd

age

deikeninin deeri

yrtlrd.

53

Ak Denetimi

3.2.1

Koullu le

Koullu ile, bir koulun gerekleip gereklememesine gre iki deyimden birini seer.

deyim1 ? deyim2 : deyim3


Burada ncelikle

deyim1

deerlendirilir. Sonu doruysa

deyim2 ,

yanlsa

deyim3

seilir.

Basit bir rnekle, iki saydan kn semek iin yle bir kod kullanlabilir:

if (x < y) z = x; else z = y;
Ayn ilem koullu ile kullanlarak yle de yazlabilirdi:

z = x < y ? x : y;
Adndan da anlalabilecei gibi, koullu ile bir iletir, yani birtakm byklkler zerinde bir ilem yapar ve belli bir tipten bir sonu retir. Bir seim yaps deildir, yani programn aknn nasl devam edecei zerinde bir etki yaratmaz; ak bir sonraki komutla devam eder.

rnek 4. lem Seimi


lemi ve ilenenleri kullancnn belirttii hesaplamay yaparak sonucu ekrana yazan bir program yazlmas isteniyor. Programn rnek bir almasnn ekran kts ekil 3.2'de verilmitir.

lemi yaznz: 18 / 5 18/5 ileminin sonucu: 3

ekil 3.2: rnek 4 ekran kts.

3.3

oklu Seim

Bir deyimin ok sayda deer iinden hangisini alm olduunu snamak istiyorsak yazacamz

if

kodu uzun ve irkin bir grnm alr. rneimizde yaplacak ilemin hangisi olduunu

anlamak iin yazlacak

if

kodu u tip bir ey olurdu:

if (op == '+') { ... } else {

oklu Seim

54

rnek 4 Kullancnn belirttii ilemi yapan program.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; int main(void) { int num1, num2, result; char op; cout << "lemi yaznz: "; cin >> num1 >> op >> num2; switch (op) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '*': result = num1 * num2; break; case '/': result = num1 / num2; break; case '%': result = num1 % num2; break; default: cout << "Byle bir ilem yok." << endl; return EXIT_FAILURE; } cout << num1 << op << num2 << " ileminin sonucu: " << result << endl; return EXIT_SUCCESS;

55

Ak Denetimi

if (op == '-') { ... } else { if (op == '*') { ...


Seim bloklarnn tek bir komut olarak deerlendirilmesi oklu karlatrmalarda da daha kolay bir yazm olana salar. Buna gre, yukardaki oklu karlatrma yaps u ekilde de yazlabilir:

if (op == '+') ... else if (op == '-') ... else if (op == '*') ... switch
komutu bu tip karlatrmalar iin daha okunakl bir yap sunar:

switch (deyim ) { case deer_1 : blok_1 ; break; case deer_2 : blok_2 ; break; ... case deer_n : blok_n ; break; default: blok ; break; }
Bu komutun ak izenei ekil 3.3'de grld gibidir. Deyim, nce birinci deerle karlatrlr ve eitse buna ilikin blok yrtlr ve deilse

break

komutuyla

switch

yapsnn dna

klr. Birinci deere eit deilse ikinci deerle karlatrlr. Karlatrmalarn hibiri doru

default blou yrtlr ve switch sona erer. Her switch yapsnda bir default blou

bulunmas zorunlu deildir. Burada dikkat edilmesi gereken bir nokta, deyimin dier bir deyimle deil, bir deerle karlatrlddr. Yani, karlatrlacak deerlerin yazld deyimlerde deikenler yer alamaz. rnein aadaki yazmda deyim yazl geerlidir ancak deerin yazl geerli deildir:

switch (5 * x) { ... case y: ... ... }

oklu Seim

56

case 1 Y

blok 1

break

case 2 Y

D blok 2

break

case n Y

blok n

break

default blok

ekil 3.3:

switch

komutunun ak izenei.

57

Ak Denetimi

Karlatrlan deyim ve deerler yalnzca tamsay ve simge tipinden olabilir (rnekte simge tipinden deerlerle karlatrma yaplmtr). rnein aadaki yazmlar geerli deildir:

switch (name) { ... case Dennis: ... ... } switch (x) { ... case 8.2: ... ... }
Yine dikkat edilmesi gereken bir nokta, karlatrmann yalnzca eitlik zerinden yaplddr. Bu yazmda, deyimin deerden kk ya da byk olup olmad ya da dier herhangi bir mantksal deyimin doruluu belirtilemez. Ayrca, yazmdan grlebilecei gibi, yaplarnda bloklar ssl ayralar iine alnmaz. C programlarnda ska yaplan hatalardan biri bloklardaki rnein birinci bloun sonuna konmas gereken ama baarl olursa

switch

break

komutu unutulursa de yrtlr ve

break komutlarnn unutulmasdr. switch komutu break break


ile

ekil 3.4'de grld gibi alr. Birinci karlatrma ilemi baarsz olursa bir sorun kmaz

blok 1

yrtldkten sonra

blok 2

switch

sonlanr. Yani, baarl olan ilk karlatrmadan balanarak gelen btn bloklar yrtlr. rnek programdaki hibir

komutu grlene kadar

break komutu konmam olsa ilemin toplama olduu durumda nce Byle bir ilem yok.
denilerek herhangi bir sonu

toplama, sonra kartma, arpma, blme ve son olarak da kalan ilemi yaplr (yani yalnzca kalan ilemi geerli olur), ayrca da deminki gibi devam eder. grntlenmeden programdan klr. lem kartma olduunda toplama ksm atlanr, gerisi

Uygulama: Seim Yaplar


Bu uygulamada Windows ortamnda bir tmleik gelitirme ortam (Visual C++ ya da DevC++) tantlacaktr. Hata ayklaycda adm adm ilerleme ve deiken deerlerinin gzlenmesi gsterilecektir.

rnek 5. Birim Dnm


Bu rnekte ngiliz uzunluk ve scaklk l birimlerinin metrik birimlere dnmn yapan bir program yazlacaktr. inch biriminden verilen bir uzunluu santimetre birimine evirmek iin

Bu davran, baz durumlarda yararl ynde de kullanlabilir (bkz. rnek 10).

oklu Seim

58

case 1 Y

blok 1

case 2 Y

D blok 2

break

case n Y

blok n

break

default blok

ekil 3.4:

switch

komutunda

break

kullanlmazsa oluan ak izenei.

59

Ak Denetimi

1 inch = 2.54 cm
eitlii ve Fahrenheit biriminde verilen bir sckl Celcius birimine evirmek iin de

5 C = (F 32) 9
forml kullanlacaktr.

Verilen rnek program yazn, altrn, birka deer iin deneyin case 1 blounun sonundaki break komutunu silin ve program altrarak her iki dnme de birer rnek deneyin

cm->inch ve c->f dnmlerini yapmak zere kodunuzu gelitirin

1f t = 12inch eitliini kullanarak ft cinsinden verilmi bir uzunluu mt cinsine evirecek


eklemeyi yapn

mt->ft dnmn yapacak eklemeyi yapn

rnek 6. Euclides Algoritmas

ki saynn en byk ortak blenini Euclides algoritmasn kullanarak bulan bir program yazlmas isteniyor. Bu algoritmaya ilikin ak izenei ekil 1.17'de, programn rnek bir almasnn ekran kts ekil 3.5'de verilmitir.

Saylar yaznz: 9702 945 9702 ve 945 saylarnn en byk ortak bleni: 63

ekil 3.5: rnek 6 ekran kts.

3.4

Koul Denetiminde Yineleme

C dilinde temel yineleme yaplar

while

szcyle kurulur:

while (koul ) { blok ; }

Koul Denetiminde Yineleme

60

rnek 5 ngiliz-metrik birim dnm yapan program.


#include <iostream> #include <stdlib.h>

// cout,cin,endl // EXIT_SUCCESS,EXIT_FAILURE

using namespace std; int main(void) { int choice; float inch, cm, f, c; cout << "1. inch-cm" << endl; cout << "2. f-c" << endl; cout << "3. k" << endl; cout << "Seiminiz: "; cin >> choice; switch (choice) { case 1: cout << "inch cinsinden uzunluk: "; cin >> inch; cm = 2.54 * inch; cout << cm << " cm" << endl; break; case 2: cout << "f cinsinden scaklk: "; cin >> f; c = (f - 32) * 5.0 / 9.0; cout << c << " C" << endl; break; case 3: return EXIT_SUCCESS; default: cout << "Byle bir ilem yok." << endl; return EXIT_FAILURE; } return EXIT_SUCCESS;

61

Ak Denetimi

rnek 6 ki saynn en byk ortak blenini bulan program.


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; int main(void) { int num1, num2; int a, b, r = 1; cout << "Saylar yaznz: "; cin >> num1 >> num2; a = num1 > num2 ? num1 : num2; b = num1 > num2 ? num2 : num1; while (b > 0) { r = a % b; a = b; b = r; } cout << num1 << " ve " << num2 << " saylarnn en byk ortak bleni: " << a << endl; return EXIT_SUCCESS;

Dng Denetimi

62

rnekteki

while

blou

deikeninin deeri 0'dan byk olduu srece yinelenecek, 0 oldu-

unda sona erecektir. Bu rnekte algoritmann doas gerei bu deiken eninde sonunda 0 deerini alacaktr; ancak yineleme yaplar kurarken dngnn her durumda mutlaka sonlanmasnn salanmasna zellikle dikkat edilmelidir. Benzer bir dier yineleme yaps ise

do-while

szckleriyle kurulabilir:

do { blok ; } while (koul );


Bu yapnn

while

yapsndan en nemli fark, koulun doru olup olmamasna baklmakszn

bloun en az bir kere yrtlmesidir. rnekteki yineleme blm u ekilde de yazlabilirdi:

do { r = a % b; a = b; b = r; } while (b > 0);


Balangta

num1 ve num2 deikenlerinden birinin 0 olmas durumunda b deikeni 0 deerini

alrd. lk rnekte koul salanmayaca iin en byk ortak blen 1 olarak bildirilirdi; ikinci
Gelenek

rnekte ise sfra blme yapmaya kalklacandan bir alma zaman hatas oluurdu. Her ne kadar dzenlenebilseler de, yineleme yaps kurmak iin genelde

while ile kurulan yaplar ve do-while ile kurulan yaplar birbirlerinin ei olacak ekilde while kullanlmas nerilir.
Dng Denetimi

3.5

Yineleme yaplarnda kullanlan dier bir yntemse, dngy bir sonsuz dng olarak kurup dngden kma durumu olutuunda

break

komutunu kullanmaktr:

while (true) { ... if (<kma koulu salanyor >) break; ... // kma koulu salanmad zaman yaplacaklar }
oklu seim (switch) yapsnda olduu gibi burada da

break komutu iinde bulunulan yapdan k salar. Ancak rnekte grld gibi iinden klan yap if deil while yapsdr. Yani, break komutu switch, while, do-while ve birazdan greceimiz for yaplarndan kartr, if yapsndan kartmaz.
ie dngler kullanldnda, beklenebilecei gibi,

break komutu yalnzca en iteki dngden

kartr ve bir stteki dngnn sradaki komutundan devam edilmesini salar:

Bu tr bir yap rnek 10'da grlebilir.

63

Ak Denetimi

while (true) { ... while (true) { ... if (<kma koulu salanyor >) break; ... } ... // stteki break komutu sonucunda buraya gelinir }
Dnglerde ak denetimine ynelik dier bir komut ise

continue komutudur. Bu komut dn-

gnn geri kalan ksmnn atlanarak dng bana gidilmesini salar:

i = 0; while (i < 50) { i++; ... if (<koul> ) { ... continue; } ... }


Bu rnekte dngnn

if ile belirtilen koul salanyorsa birtakm ilemlerin gerekletirilmesinden sonra bana dnlr. Yani if bloundan sonra gelen komutlar atlanarak i deikeninin

bir sonraki deerinden ilemler srdrlr.

rnek 7. Yinelemeli Yaz-Tura At


Kullancnn verdii say kadar yaz-tura atarak yaz ve turalarn kaar kere geldiini sayan ve sonular ekrana kartan bir program yazlmas isteniyor. Bu programa ilikin ak izenei ekil 3.6'da, programn rnek bir almasnn ekran kts ekil 3.7'de verilmitir.

3.6

Saya Denetiminde Yineleme

rnekte yaz-tura simlasyonunun kullancnn belirtecei sayda yinelenmesi isteniyor. Bir bloun belli sayda yinelenmesi istendiinde kullanlabilecek en uygun yap sayacn denetiminde yineleme yapmak iin unlarn belirtilmesi gerekir:

for

yapsdr. Bir

Sayacn balang deeri: rnekte bu deer 1'dir. Kaa kadar saylaca: rnekte bu deer kullancdan alnan saynn tutulduu deikeniyle belirlenir.

count

Saya Denetiminde Yineleme

64

basla

oku: count

i1 heads 0 tails 0

i count

D Tura Yazi

bas: heads bas: tails

at

dur bas: "Tura" bas: "Yazi"

heads heads + 1

tails tails + 1

ii+1

ekil 3.6: Yinelemeli yaz-tura atnn simlasyonu.

Ka kere atlacak? 7 Yaz Tura Tura Yaz Yaz Yaz Yaz Tura says: 2, Yzdesi: %28.5714 Yaz says: 5, Yzdesi: %71.4286

ekil 3.7: rnek 7 ekran kts.

65

Ak Denetimi

rnek 7 Yinelemeli yaz-tura at simlasyonu yapan program.


#include <iostream> #include <stdlib.h> #include <time.h>

// cin,cout,endl // EXIT_SUCCESS,srand,rand,RAND_MAX // time

using namespace std; int main(void) { int count, i; float number; int heads = 0, tails = 0; cout << "Ka kere atlacak? "; cin >> count; srand(time(NULL)); for (i = 1; i <= count; i++) { number = (float) rand() / RAND_MAX; if (number < 0.5) { cout << "Tura" << endl; heads++; } else { cout << "Yaz" << endl; tails++; } } cout << " Tura says: " << heads << ", Yzdesi: %" << 100.0 * heads / count << endl; cout << " Yaz says: " << tails << ", Yzdesi: %" << 100.0 * tails / count << endl; return EXIT_SUCCESS;

Saya Denetiminde Yineleme

66

Kaar kaar saylaca: rnekte sayacn birer birer artrlaca belirtilmitir.

for

yaps bu belirtimin ayn anda yaplmasna olanak salar. Ay iinde nce balang

deeri atamas, ikinci olarak hangi koul saland srece devam edilecei ve son olarak da sayacn nasl artrlaca belirtilir.

for (i = 1; i <= count; i++)


komutu yle okunabilir:

kk veya eit olduu srece blou her yrtnden sonra 1 artr.

i deikenine 1 deerini ver ve bu deikenin deeri count deikeninin deerinden i deikeninin deerini

for

dngleri

while

dngleri eklinde de yazlabilirler:

for (balang_atamas ; srme_koulu ; artrma_komutu ) { blok ; }


dngs

balang_atamas ; while (srme_koulu ) { blok ; artrma_komutu ; }


dngsne edeerlidir. Yine de saya denetiminde yinelemeler iin yinelemeler iin

while

for,

koul denetiminde

kullanmak anlalrlk asndan daha dorudur.

Bu yapyla ilgili olarak baz noktalara dikkat etmek gerekir:

Dng, belirtilen koul salanmad zaman sonlanr ve programn yrtlmesi dngnn arkasndan gelen komutla srdrlr. rnekte

i deikeninin deeri count deikei

ninin deerinden byk olduu zaman dng sona erer.

Artrma ilemi dng gvdesi yrtldkten sonra yaplr. rnekte dngnn gvdesi deikeninin 1, 2, ...,

count

deerleri iin yinelenir, 1 deeri atlanmaz.

Verilen balang deeri dng koulunu salamyorsa dngnn gvdesi hi yrtlmez. rnein

for (i = 1; i == 10; i++)

67

Ak Denetimi

dngsnde balang deeri srme koulunu salamadndan (1 == 10 doru olmadndan) dngye hi girilmez.

Artm miktar iin artrma ileci kullanlmas zorunlu deildir, herhangi bir C deyimi kullanlabilir.

for (i = 1; i < count; i = i + 3)


dngs 1, 4, 7, 10, 13, ... eklinde sayarken

for (i = 1; i < count; i = i * 2)


dngs 1, 2, 4, 8, 16, ... eklinde sayar.

Rasgele Saylar
Yaz-tura atn temsil etmek iin en kolay yol 0 ile 1 arasnda bir rasgele say retmek ve bu saynn 0.5'den kk olmas durumunu bir sonuca (diyelim tura), eit ya da byk olmasn da dier sonuca (bu durumda yaz) atamaktr.

rand fonksiyonu 0 ile RAND_MAX arasnda bir rasgele tamsay retir. RAND_MAX standart kitaplkta tanmlanm bir deerdir ve sistemden sisteme farkllk gsterebilir. rand fonksiyonundan gelen say RAND_MAX deerine blnrse 0 ile 1 arasnda bir rasgele
C standart kitaplndaki kesirli say elde edilir. Rasgele saylarn kullanmnda daha ok 1 ile bir st snr arasnda deer alacak bir rasgele tamsayya gereksinim duyulur. Bu st snr

max

ile gsterilirse

1 + rand() % max
deyimi istenen trden bir say retir (Neden?). Rasgele saylar, bir seri olarak retilirler; yani her rasgele say seride bir nceki rasgele saydan retilir. Bu serinin balayabilmesi iin ilk sayy retmekte kullanlacak bir balang deeri (tohum ) verilmesi gerekir.

srand

fonksiyonu bu tohumun belirtilmesini salar. Ayn

tohumla balanrsa ayn seri retilir. Her serinin programn almasndaki bir senaryoya karlk dt dnlrse istendii zaman ayn senaryoyu retebilmek programn hatalarnn ayklanmas asndan yararldr. Her defasnda farkl bir tohumla balamak iin tohumun da her defasnda farkl verilmesi gerekir. Standart kitaplktaki

time

fonksiyonu, 1 Ocak 1970 tarihinden o ana kadar geen

saniyelerin saysn verdiinden her arlnda farkl bir tohum retebilir. Bu fonksiyona giri parametresini gndermek yeterlidir.

NULL

Uygulama: Dngler
Bu uygulamada Unix bir hata ayklayc (ddd) tantlacaktr. Hata ayklaycda adm adm ilerleme ve deiken deerlerinin gzlenmesi gsterilecektir.

Saya Denetiminde Yineleme

68

rnek 8. Seri Toplam


Bu uygulamada grlecek programlarda, toplamndan yararlanlacaktr:

ex

fonksiyonunun hesaplanmas iin aadaki seri

f (x) =
i=0

xi x2 x3 x4 =1+x+ + + + i! 2! 3! 4!

Birinci programda (rnek 8) iie iki dng vardr. erideki dng o anda ilenmekte olan terimde gerekecek faktryel deerinin hesaplanmasn salar. D dngyse her yineleniinde serinin o anki terimi hesaplayarak toplama ekler. Hesaplanan terim kullancnn belirttii hatadan kk olduunda deerin istenen duyarllkta hesaplandna karar verilerek sonu ekrana kartlr.

rnek 8 ex

deyimini genel terimden giderek hesaplayan program.

#include <iostream> #include <stdlib.h> #include <math.h> using namespace std;

// cin,cout,endl // EXIT_SUCCESS // pow

int main(void) { float x, error, term, result = 1.0; int i = 1, f; float fact; cout << "x: "; cin >> x; cout << "Hata: "; cin >> error; term = error + 1; while (term > error) { fact = 1.0; for (f = 2; f <= i; f++) fact = fact * f; term = pow(x, i) / fact; result = result + term; i++; } cout << "Sonu: " << result << endl; } return EXIT_SUCCESS;

69

Ak Denetimi

kinci programdaysa (rnek 9) ayn ilemin nasl daha etkin (daha az hesap ykyle) yaplabilecei grlecektir. Serinin genel teriminin kendisinden nceki terimin edilir.

ai =
ai ai1

elemann kendisinden nceki elemana blm

xi i! olduu gznne alndnda dizide bir = x olarak hesaplanabilir. Yani her terim, i

ile arplp

i'ye

blnmesiyle bulunabilir. Bylece her admda

s alma ve faktryel hesaplama ilemlerine gerek kalmaz ve seri toplam ok daha hzl elde

rnek 9 ex

deyimini bir nceki terimden giderek hesaplayan program.

#include <iostream> #include <stdlib.h> using namespace std;

// cin,cout,endl // EXIT_SUCCESS

int main(void) { float x, error, term, result = 1.0; int i = 1; cout << "x: "; cin >> x; cout << "Hata: "; cin >> error; term = 1; while (term > error) { term = term * x / i; result = result + term; i++; } cout << "Hata: " << result << endl; } return EXIT_SUCCESS;

Her iki program da yazarak altrn. Tama durumunun gzlenmesi

Sorular
1.

(x % 3 == 2) && (x > 4) || !(x % 3 == 2) && (x < 6)


(a) doru yapacak bir

mantksal deyimini

deeri verin.

(b) yanl yapacak bir x deeri verin.

Saya Denetiminde Yineleme

70

(c)

iaretsiz bir tamsay ise,

x'in

hangi deerleri iin bu deyim doru deerini alr?

2. Aada verilen program paras iin zeneini izin.

deikeninin balang deerinin 115 olduu var-

saymyla deikenlerin alacaklar deerleri izlemek zere bir izelge oluturun. Ak i-

i = -1; while (x >= 1) { i++; y[i] = x % 8; x = x / 8; } for (j = i; j >= 0; j--) cout < < y[j];
3.

x ve m saylar aralarnda asalsa x saysnn m saysna gre evrii r says, xr = 1 mod m eitliini salayan saydr (r < m). rnein, x = 5 ve m = 7 ise r = 3 olur. Buna gre, kullancdan ald x ve m saylarna gre r deerini hesaplayan ve ekrana kartan bir program yazn. x = 8, m = 11 deerleri iin programnzdaki deikenlerin alacaklar
deerleri bir izelge halinde gsterin.

4. Kusursuz bir say, kendisinden kk btn arpanlarnn toplamna eit olan saydr. rnein,

28 = 1 + 2 + 4 + 7 + 14.

Buna gre, ilk 10000 say iindeki kusursuz saylar

ekrana dken bir program yazn. 5. nsan bedeninin alann hesaplamakta kullanlabilecek iki forml aada verilmitir. DuBois forml: Boyde forml:

bsa = h0.725 w0.425 71.84 104

bsa = h0.3 w(0.72850.0188 log w) 3.207 104

Her iki formlde de alann

h deikeni cm cinsinden boyu ve bsa deikeni de m2 cinsinden beden gsterirken, w deikeni ktleyi DuBois formlnde kg, Boyde formlndeyse

g cinsinden gsterir. DuBois forml yetikinlerde iyi sonu verirken, ocuklarda (bu formlle elde edilen alan deeri 0.6'dan kkse) ok hatal olabilmektedir. Buna gre, boy ve ktlesini kullancdan ald bir insann (yetikin ya da ocuk) beden alann yukarda anlatlan ltlere gre hesaplayarak ekrana karan bir program yazn. 6. Aada verilen Pascal geni iin verilen formlle hesaplanr: 0 0 1 2 3 4 1 1 1 1 1 1 2 3 4 1 3 6 1 4 1 1 2 3 4

i.

satr

j.

stundaki deer (binom katsays) yanda

binomi,j =

1 binomi1,j1 + binomi1,j

j =0j =i aksi durumda

Buna gre, genin ilk 30 satrn hesaplayp ekrana kartacak bir program yazn. 7. Aadaki seri toplam hesaplanmak isteniyor:

71

Ak Denetimi

(1)i
i=0
(a) Bu serinin

xi x0 x1 x2 x3 x4 x5 = + + + ... (2i)! 0! 2! 4! 6! 8! 10! ai


ise,

i.

eleman

ai+1 /ai

oran nedir?

(b) Bu bilgiyi kullanarak, serinin toplamn hesaplayan bir program yazn (x ve erleri kullancdan alnacaktr).

de-

8. Rasgele say retirken kalan ilecini (%) kullanarak sayy belli bir arala indirgemek saylarn retilme olaslklarn bozar m? Szgelimi,

RAND_MAX'n deerinin 32767 olduunu

varsayarak 1 ile 6 arasnda reteceiniz rasgele sayda bu alt saynn gelme olaslklar eit midir? Deilse, daha iyi bir yntem nerebilir misiniz?

Saya Denetiminde Yineleme

72

Blm 4
Tretilmi Veri Tipleri

Bu blmde programcnn var olan veri tiplerinden kendi veri tiplerini (szgelimi kaytlar, bkz. Blm 1.1.2) nasl tretebilecei zerinde durulacaktr. C dilinin programcya kendi veri tiplerini tanmlayabilmesi iin sunduu temel olanak, var olan veri tiplerine yeni isimler verilebilmesidir. Bunun iin

typedef veri_tipi yeni_isim ;


komutu kullanlr. Bunun sonucunda verilmi olur. rnein bir rencinin snav notlar ilenmek isteniyor olsun. Notlarn 0 ile 100 arasnda birer tamsay olaca varsaymyla, renci notu tipinden bilgileri temsil etmek zere bir veri tipi tanmlanabilir:

veri_tipi

isimli tipe

yeni_isim

adnda bir isim daha

typedef int score_t;


Bylece

int veri tipine score_t diye yeni bir isim verilmi olur. Daha sonra bu tipten deiken

tanmlamak iin

score_t midterm1, midterm2, final;


gibi bir komut yazlabilir. stenirse asl veri tipi isminin kullanlmasnda da bir saknca yoktur, yani

int midterm1, midterm2, final;


tanm da geerliliini korur ve bu iki tanm birbirine edeerlidir. Bir veri tipine yeni bir isim vermenin yararlar yle aklanabilir:

Anlalrlk artar: Programn kodunu okuyan kii bu veri tipinin temsil ettii bilgiyle ilgili daha iyi bir kir edinebilir. 73

74

Deitirmek kolay olur: Programn gelitirilmesinin ileri aamalarnda ya da sonraki srmlerde renci notlarnn kesirli olabilecei durumu ortaya karsa yalnzca veri tipine isim verme komutunun

typedef float score_t;


biiminde deitirilmesi yeterli olur. Veri tipi tanm olmasa btn kodun taranarak renci notuna karlk gelen

int

veri tiplerini bulup deitirmek gerekir. Bu da baz

int

szcklerinin deimesi, bazlarnn deimemesi anlamna gelir ve programn boyutlarna gre byk zorluklar karabilir.

rnek 10. Barbut


Barbut oyununun kurallar yledir:

Oyuncu bir ift zar atar.

  

Att zarlarn toplam 7 ya da 11 ise oyuncu kazanr. Att zarlarn toplam 2, 3 ya da 12 ise oyuncu kaybeder. Dier durumlarda att zarlarn toplam oyuncunun says olur.

Oyuncu ayn toplam veren zarlar bir daha atana kadar ya da att zarlarn toplam 7 olana kadar zar atmaya devam eder.

 

Ayn toplam bir daha atarsa oyuncu kazanr. Att zarlarn toplam 7 olursa oyuncu kaybeder.

Verilen rnek, bu oyunu simle eden bir programdr. Bu rnein ilgin bir yn nn baz durumlarnda kastl olarak

switch yapsbreak kullanlmamasdr. Bylelikle durumlar gruplanarak

her bir grup iin yaplacak ilemlerin bir kere belirtilmesi salanmtr. Programn rnek bir almasnn ekran kts ekil 4.1'de verilmitir.

Zarlar: 1 + 4 = Say: 5 Zarlar: 5 + 1 = Zarlar: 5 + 5 = Zarlar: 6 + 5 = Zarlar: 4 + 1 = Oyuncu kazanr.

5 6 10 11 5

ekil 4.1: rnek 10 ekran kts.

Bu rnek, H.M. Deitel ve P.J. Deitel'in yazdklar C: How to Program kitabndan uyarlanmtr.

75

Tretilmi Veri Tipleri

rnek 10 Barbut oyununu simle eden program.


#include <iostream> #include <stdlib.h> #include <time.h>

// cin,cout,endl // EXIT_SUCCESS,srand,rand // time

using namespace std; enum status_e { GAME_CONTINUES, PLAYER_WINS, PLAYER_LOSES }; typedef enum status_e status_t; int main(void) { int die1, die2, sum, point; status_t game_status = GAME_CONTINUES; srand(time(NULL)); die1 = 1 + rand() % 6; die2 = 1 + rand() % 6; sum = die1 + die2; cout << "Zarlar: " << die1 << " + " << die2 << " = " << sum << endl; switch (sum) { case 7: case 11: game_status = PLAYER_WINS; break; case 2: case 3: case 12: game_status = PLAYER_LOSES; break; default: game_status = GAME_CONTINUES; point = sum; cout << "Say: " << point << endl; break; } while (game_status == GAME_CONTINUES) { die1 = 1 + rand() % 6; die2 = 1 + rand() % 6; sum = die1 + die2; cout << "Zarlar: " << die1 << " + " << die2 << " = " << sum << endl; if (sum == point) game_status = PLAYER_WINS; else { if (sum == 7) game_status = PLAYER_LOSES; } } if (game_status == PLAYER_WINS) cout << "Oyuncu kazanr." << endl; else cout << "Oyuncu kaybeder." << endl;

Numaralandrma

76

4.1

Numaralandrma

rnekte oyunun iinde bulunabilecei eitli durumlara birer say deeri atanarak oyunun o an hangi durumda olduu izlenebilir. rnein kodumuzda oyunun durumunu gsteren

game_status

deikeninin deerinin 0 olmas oyunun sryor olmasna, 1 olmas oyuncunun kazanmasna ve 2 olmas da oyuncunun kaybetmesine karlk drlebilir. Burada 0, 1 ve 2 deerlerinin zel bir anlamlar yoktur, herhangi farkl deer de ayn ilevi grr. Okunulurluu artrmak amacyla bu saylara birer isim vermek yararl olur. yleyse

#define GAME_CONTINUES 0 #define PLAYER_WINS 1 #define PLAYER_LOSES 2


eklinde deimez tanmlar yaplarak kodun iinde saylar yerine isimler yazlabilir. Bu tip, birbiriyle ilintili birden fazla deimezi birlikte tanmlamak iin numaralandrma yntemi kullanlabilir.

enum { GAME_CONTINUES, PLAYER_WINS, PLAYER_LOSES };


komutu yukarda yazlm olan

#define komutuyla ayn etkiyi yaratr. Aksi belirtilmedike,

ssl ayralar iinde yazlan deimezlerden ilkine 0, sonrakine 1, sonrakine 2 vs. eklinde deer verilir. Programc isterse baka deerler belirtebilir ancak bizim rneimizde -demin de sylendii gibi- deerlerin, farkl olduklar srece, ne olduklarnn bir nemi yoktur:

enum { GAME_CONTINUES = 58, PLAYER_WINS = 17, PLAYER_LOSES = 154 };


Herhangi bir deimeze deer verilirse onu izleyen deimezlerin deerleri birer artarak devam eder:

enum { JANUARY = 1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
Numaralandrma ile oluturulmu bir deimezler kmesine de topluca bir isim verilerek yeni bir veri tipi oluturulabilir:

enum knye { deimez_tanmlar };


Bu komutun sonucunda da bu tipe

enum knye

isimli yeni bir veri tipi oluur ve bu tipten deikenler

tanmlanabilir. rnekte nce bu ekilde

typedef

enum status_e isimli bir tip oluturulmu, daha sonra

komutuyla yeni bir isim verilmitir. Bu tipten deiken tanmlarken her

iki yeni isim de kullanlabilir, yani rnekteki

status_t game_status = GAME_CONTINUES;

77

Tretilmi Veri Tipleri

komutu

enum status_e game_status = GAME_CONTINUES;


komutuyla edeerlidir.

Dzenli bir alma iin numaralandrma tipinden tanmlanan deikenlerin yalnzca o numaralandrmayla belirlenen deimezler kmesinden deer almas gerekir. Szgelimi rneimizde tanmlanan

game_status

deikeni

GAME_CONTINUES, PLAYER_WINS

ve

PLAYER_LOSES

dnda

herhangi bir deer alamamaldr. Ancak C dili byle bir kstlama getirmez, yani

game_status = 25;
gibi anlamsz olacak bir atama C dilinin kurallarna gre yasak deildir.

rnek 11. Paralel Diren Edeeri


Direnlerin paralel edeeri aadaki formlle hesaplanabilir:

1 R1

1 R2

1 + +

1 Rn

Buna gre, kullancdan ald direnlerin paralel edeerini hesaplayarak sonucu ekrana kartan bir program yazlmas isteniyor. Kullancnn ka tane diren deeri girecei batan belli olmad iin bu dng

for

yapsyla deil

while

yapsyla kurulmaya daha uygundur. Son-

suz dngden kabilmek iin kullancnn bir ekilde bunu belirtmesine olanak verilmelidir. Bu programda uygulanan yntem, zel bir deeri (rnein 0) bitirme iareti olarak semektir. Kullanc bu deeri girerek baka diren deeri yazmayacan belirtebilir. Sonlandrma deerinin uygun seilmesi gerekir; geerli diren deerleri sonlandrma deeri olmaya uygun deildir. Programn rnek bir almasnn ekran kts ekil 4.2'de verilmitir. Bu programn almasnda dikkat ekici bir nokta, kullancnn yazd diren deerlerinin uygun ekilde toplama eklenmelerinin ardndan unutulmalardr. Yani ileride kullancnn girmi olduu deerlerle bir ilem yaplmak istense bunlar bir ekilde ulalabilir olmayacaklardr. Bu programn amac asndan bu durum bir saknca dourmaz ancak baka problemlerde farkl yaplar kullanmak gerekebilir.

C dilinde mantksal bir veri tipi ve

true, false

deerleri bulunmad daha nce sylenmiti. Ancak,

doru ve yanl byklkleri programlarda ska gereksinim duyulan deerler olduklarndan C programlarnda genellikle bunlar genellikle programn banda deimez olarak tanmlanrlar.

#define TRUE 1 #define FALSE 0


Daha sk kullanlan bir yntemse bunlar bir numaralandrma iinde tanmlayarak oluacak veri tipine yeni bir isim vermektir.

enum bool_e { FALSE, TRUE }; typedef enum bool_e bool_t;


Bylelikle C++ dilinde olduu gibi mantksal bir veri tipi tanmlanm olur ve bu tipten deikenler kullanlabilir.

Numaralandrma

78

rnek 11 Paralel diren edeeri hesaplayan program.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; struct rational_s { int nom; int denom; }; typedef struct rational_s rational_t; int main(void) { int res_value; rational_t equiv = { 0, 1 }; int a, b, r; int i = 0; while (true) { i++; cout << "R" << i << " (bittiyse 0): "; cin >> res_value; if (res_value == 0) break; equiv.nom = equiv.nom * res_value + equiv.denom; equiv.denom = equiv.denom * res_value; // kesiri basitletir a = equiv.nom; b = equiv.denom; while (b > 0) { r = a % b; a = b; b = r; } equiv.nom = equiv.nom / a; equiv.denom = equiv.denom / a;

} if (equiv.nom != 0) cout << "Edeer diren: " << equiv.denom << " / " << equiv.nom << " = " << (float) equiv.denom / equiv.nom << endl; else cout << "Hatal ilem." << endl; return EXIT_SUCCESS;

79

Tretilmi Veri Tipleri

R1 (bittiyse 0): 5 R2 (bittiyse 0): 8 R3 (bittiyse 0): 11 R4 (bittiyse 0): 4 R5 (bittiyse 0): 0 Edeer diren: 440/293 = 1.50171

ekil 4.2: rnek 11 ekran kts.

4.2

Yaplar

Kayt tiplerinin zelliklerinden Blm 1.1.2'de sz edilmiti. C dilinde kaytlara yap ad verilir ve yle tanmlanrlar:

struct knye { alan_tanmlar ; };


Yap tanmnn sonucunda

struct knye

isimli yeni bir veri tipi oluur ve bu tipten deiken-

ler tanmlanabilir. Alan tanmlar deiken tanmlarna benzer ekilde yaplr ancak deiken tanm deildirler. Deiken tanmlarnn bellekte ilgili deiken iin yer ayrlmasna neden olduu grlmt, oysa tip tanm bellekte yer ayrlmasna neden olmaz. Yer ayrlmas ancak bu yap tipinden bir deiken tanmlandnda gerekleir. rnekte rasyonel saylar gstermek zere iki alan olan bir yap kullanlmtr: saynn pay ksmn gsteren

nom

ve payda ksmn gsteren

denom.

Rasyonel saylarn tanm gerei her

iki alan da tamsay tipindendir. Tip tanm sonucunda artk

struct rational_s
adnda bir veri tipi olumutur. Kullanm kolayl asndan bu veri tipine

3 yeni bir isim verilmitir.

typedef komutuyla
ile verilen yeni

Yap tipinden deiken tanmlanrken istenirse knyeli isim, istenirse Aadaki iki komut ayn ii yaparlar, yani yapsnda olan iki deiken tanmlarlar ve balang deerini verirler (ekil 4.3):

typedef

isim kullanlabilir ve deikenin alanlarna ssl ayralar iinde balang deerleri verilebilir.

res ve equiv isimlerinde, her biri birer rasyonel say equiv deikeninin nom alanna 0, denom alanna 1

Tipin tanmlanmas ve yeni isim verilmesi ilemleri istenirse tek komutta birletirilebilir:

typedef struct rational_s { int nom, denom; } rational_t;


Birletirilmi tanmlamada istenirse tipin knyesi de belirtilmeyebilir, yani yukardaki rnekte yazmaktr. Bu yazl numaralandrmalar iin de geerlidir.

rational_s

szc yazlmasa da olurdu. Yine de ounlukla nerilen yntem, belirtilmeleri zorunlu olmasa da knyeleri

Yaplar

80

rational_t res, equiv = { 0, 1 }; struct rational_s res, equiv = { 0, 1 };


res nom equiv nom

0
denom denom

ekil 4.3: Yap tipinden deiken tanmlama. Bu deikenlerin her biri, yapda belirtilen alanlar barndrr. Alanlar zerinde ilem yapmak iin, daha nce grld gibi, noktal gsterilim kullanlr, yani deikenin adndan sonra nokta iaretiyle alann ad belirtilir. Bu durumda, edeer diren deerini tutan deikenin payda ksmyla bir ilem yaplacaksa

equiv.denom

yazlr.

Yaplarn alanlar skalar tiplerden tanmlanabilecei gibi, baka yap tiplerinden ya da tipli numaralandrma tipinden de tanmlanabilir:

enum month_e { JANUARY = 1, FEBRUARY, ..., DECEMBER }; typedef enum month_e month_t; struct date_s { int day; month_t month; int year; }; typedef struct date_s date_t; struct academic_year_s { date_t begin, end; }; typedef struct academic_year_s academic_year_t;
tanmlar ekil 4.4'de grlen yapy oluturur. Alanlara eriim yine noktal gsterilimle salanr:

academic_year_t year_2001_2002; year_2001_2002.end.day = 31; year_2001_2002.end.month = MAY; year_2001_2002.end.year = 2002;


Ayn yap tipinden deikenler arasnda atama ilemi yaplabilir. Atama sonucunda kaynak deikenin btn alan deerleri var deikenin ayn isimli alanlarna atanr. Bu gsterilim btn alt alanlarn tek tek atanmas zorunluluunu giderir, yani

81

Tretilmi Veri Tipleri

year_2001_2002 academic_year_t begin day end day

month

month

year

year

ekil 4.4: Yap iinde yap kullanma.

equiv.nom = res.nom; equiv.denom = res.denom;


eklinde atama yapmak yerine yalnzca

equiv = res;
yazlabilir.

Uygulama: Yaplar
rnek 12. Noktann Daireye Gre Konumu
Koordinatlarn kullancdan ald bir noktann, merkez noktasnn koordinatlar ile yarapn yine kullancdan ald bir dairenin iinde mi, dnda m, zerinde mi olduunu belirleyerek sonucu ekrana karacak bir program yazlmas isteniyor. Noktann koordinatlar merkezinin koordinatlar

x ve y ,

daire

xc

ve

yc ,

dairenin yarap

ile gsterilirse:

(x xc )2 + (y yc )2 < r (x xc )2 + (y yc )2 > r (x xc )2 + (y yc )2 = r

ise nokta dairenin iinde ise nokta dairenin dnda ise nokta dairenin zerindedir.

Program yazarak altrn. Merkez noktasnn koordinatlarn (2.1,5.664), yarapn 3.2, aranan noktann koordinatlarn (5.3,5.664) olarak verin. Bu nokta dairenin neresindedir? Program ne kt veriyor? Hatalysa neden hataldr ve nasl dzeltilebilir?

Yaplar

82

rnek 12 Noktann daireye gre konumunu bulan program.


#include <iostream> #include <stdlib.h> // cout,cin,endl // EXIT_SUCCESS

using namespace std; typedef struct point_s { float x, y; } point_t; typedef struct circle_s { point_t center; float radius; } circle_t; int main(void) { circle_t circle1; point_t point1; float p, deltaX, deltaY; cout << "Daire merkezinin koordinatlarn yazn (x y): "; cin >> circle1.center.x >> circle1.center.y; cout << "Dairenin yarapn yazn: "; cin >> circle1.radius; cout << "Noktann koordinatlarn yazn (x y): "; cin >> point1.x >> point1.y; deltaX = point1.x - circle1.center.x; deltaY = point1.y - circle1.center.y; p = deltaX * deltaX + deltaY * deltaY; if (p < circle1.radius * circle1.radius) cout << "Nokta dairenin iinde." << endl; else { if (p > circle1.radius * circle1.radius) cout << "Nokta dairenin dnda." << endl; else cout << "Nokta dairenen zerinde." << endl; } return EXIT_SUCCESS;

83

Tretilmi Veri Tipleri

Bir noktann konumunun belirtilmesinden sonra programdan kmadan kullancnn ayn daireye gre baka noktalarn da konumlarn sorabilmesi iin programda gerekli deiiklikleri yapn.

Merkez koordinatlar ve yaraplar kullancdan alnan iki dairenin kesiip kesimediklerini belirleyen bir program yazn.

Sorular
1. rnek 11'da

equiv

deikenine farkl bir balang deeri verilebilir miydi? rnein

deiken tanmlama komutu

rational_t res, equiv = { 0, 0 };


eklinde olsayd program doru alr myd? 2. Ayn rnekte kullanc ilk diren deeri olarak 0 verirse programn davran nasl olur? Gerekiyorsa programda dazeltmeler yapn. 3. rnek 10'da uygulamas yaplan barbut oyunu adil bir oyun mudur? Yani oyuncunun kazanma olasl ile kaybetme olasl ayn mdr?

Yaplar

84

Blm 5
Diziler

Bu blmde programlamada ska gereken dizi tiplerinin (bkz. Blm 1.1.3) C dilinde nasl kullanlaca zerinde durulacaktr.

rnek 13. statistik Hesaplar


Kullancdan ald snav notlarnn ortalamasn, varyansn, standart sapmasn ve mutlak sapmasn hesaplayan bir program yazlmas isteniyor. Programn rnek bir almas ekil 5.1'de verilmitir. renci says sapma

n, i.

rencinin notu

si ,

ortalama

m,

varyans

v,

standart sapma

sd,

mutlak

ad

ile gsterilirse:

m = v = sd = ad =
Bu problemde drt dng ilemi grlebilir:

n i=1 si

n
n i=1 (si

m)2 n1 m|

v
n i=1 |si

1. Kullancnn girdii notlar okumak iin bir dng. 2. Ortalama iin gereken, notlarn toplamn hesaplamakta kullanlan dng (birinci eitlikteki iaretine kar der).

3. Varyans ve standart sapma iin gereken, her bir notun ortalamayla farklarnn karelerinin toplamn hesaplamakta kullanlan dng (ikinci eitlikteki iaretine kar der).

4. Mutlak sapma iin gereken, her bir notun ortalamayla farklarnn mutlak deerlerinin toplamn hesaplamakta kullanlan dng (drdnc eitlikteki 85 iaretine kar der).

86

rnek 13 eitli istatistik hesaplar yapan program.


#include <iostream> #include <stdlib.h> #include <math.h>

// cin,cout,endl // EXIT_SUCCESS // fabs,sqrt

using namespace std; #define MAXSTUDENTS 100 int main(void) { int score[MAXSTUDENTS]; int no_students = 0; float mean, variance, std_dev, abs_dev; float total = 0.0, sqr_total = 0.0, abs_total = 0.0; int i = 0; cout << "Ka renci var? "; cin >> no_students; for (i = 0; i < no_students; i++) { cout << i + 1 << ". rencinin notu: "; cin >> score[i]; total = total + score[i]; } mean = total / no_students; for (i = 0; i < no_students; i++) { sqr_total = sqr_total + (score[i] - mean) * (score[i] - mean); abs_total = abs_total + fabs(score[i] - mean); } variance = sqr_total / (no_students - 1); std_dev = sqrt(variance); abs_dev = abs_total / no_students; cout << "Ortalama: " << mean << endl; cout << "Varyans: " << variance << endl; cout << "Standart sapma: " << std_dev << endl; cout << "Mutlak sapma: " << abs_dev << endl; return EXIT_SUCCESS;

87

Diziler

Ka renci var? 5 1. rencinin notu: 65 2. rencinin notu: 82 3. rencinin notu: 45 4. rencinin notu: 93 5. rencinin notu: 71 Ortalama: 71.2 Varyans: 329.2 Standart sapma: 18.1439 Mutlak sapma: 13.04

ekil 5.1: rnek 13 ekran kts

Burada birinci ve ikinci dngler tek bir dngde birletirilebilir, kullanc notlar girdike bunlar toplama eklenebilir. Ancak nc ve drdnc dngler bu dngye eklenemez, nk o dnglerde her bir notun ortalamayla farkna gereksinim vardr ve bu ortalama ancak birinci dng sona erdiinde elde edilmektedir. Dng sayac ayn snr deerleri arasnda deitiinden ve her yinelemede ayn renci notu zerinde ilem yapldndan nc ve drdnc dngler de kendi aralarnda tek bir dngde birletirilebilirler. rnek 11'da kullancnn girdii diren deerleri toplama eklendikten hemen sonra yitiriliyorlard. Oysa bu rnekte renci notlarnn birinci dngnn knda unutulmamas gerekir, nk ikinci dngde de bunlar gerekecektir. Yani bu notlarn bir yerde tutulmas gerekir. Ayn tipten ok sayda eleman bulunan deikenler iin en uygun yapnn diziler olduu Blm 1.1.3'de grlmt. rneimizde de renci notlar bir dizi olarak temsil edilmektedir.

5.1

Tek Boyutlu Diziler

Dizi tanmnn yazm

veri_tipi dizi_ad [dizi_boyu ];


eklindedir. Burada rnekte

ka eleman bulunduunu,

dizi_ad dizi tipinden tanmlanan deikenin adn, dizi_boyu bu dizide veri_tipi ise her bir elemann hangi tipten olduunu belirtir.

int score[MAXSTUDENTS];
komutu, her biri tamsay tipinden

dizi iin bellekte birbirini izleyecek ekilde

MAXSTUDENTS elemanl, score adnda bir dizi tanmlar. Bu MAXSTUDENTS * sizeof(int) sekizli yer ayrlr.

Dier deikenlerde olduu gibi, dizilere de tanm srasnda balang deeri verilebilir. rnein:

Tek Boyutlu Diziler

88

int score[4] = { 85, 73, 91, 66 };


tanm 4 elemanl bir dizi tanmlar ve elemanlara srasyla 85, 73, 91 ve 66 deerlerini atar. zel bir durum olarak, btn diziye 0 balang deeri verilmek isteniyorsa u komut kullanlabilir:

int score[50] = { 0 };
Derleyicinin dizi iin bellekte ne kadar yer ayrlacan bilmesi gerekir, yani derleme aamasnda dizinin ka elemannn olaca belli olmaldr. Bunun iin iki yntem kullanlabilir:

ak belirtim

Dizinin ka eleman olduunun tanm srasnda ak olarak belirtildii, yuka-

rda da rnekleri grlen yntemdir. Boy olarak deimez bir deer vermek zorunludur. rnekte snftaki renci says

no_students

no_students

deikeniyle gsterilmektedir, yani dizinin

eleman olmas gerekli ve yeterlidir. Ancak

no_students

deikeninin de-

erinin ne olaca programn almas srasnda belirlendiinden derleyici bu deeri dizi boyu olarak kullanamaz, yani

int score[no_students];
eklinde bir dizi tanm yaplamaz. Baka bir deyile, dizi boyu iin yazlacak deyimde yalnzca saylar ve deimezler yer alabilir, deikenler yer alamaz. Bu durumda, dizinin ka eleman olaca batan bilinmiyorsa gerekebilecek en byk eleman says boy olarak belirtilmelidir. rnekteki

MAXSTUDENTS

deimezi bu ilevi grmektedir. Burada

belirtilen say, bir yandan gereksiz bellek kullanmna yol aabilir, dier yandan da programn bir kstlamas haline gelir. rnek programn yapt iin aklamasn u ekilde dzeltmek gerekir: Bu program, en fazla 100 rencili bir snfta, renci notlarnn ortalamasn, varyansn ve standart ile mutlak sapmalarn hesaplar.

rtl belirtim
tur, yani

Diziye balang deeri verilirse eleman saysn belirtmek zorunluluu yok-

int score[] = { 85, 73, 91, 66 };


tanm da drt elemanl bir tamsay dizisi tanmlar ve sylenen balang deerlerini atar. Bu durumda derleyici balang deeri olarak verilen dizideki eleman saysn sayarak boyu kendisi belirler. Dizideki eleman says ileride artmayacaksa bu yazm kullanmann bir sakncas yoktur, ancak artmas olasl varsa yine gerekebilecek en byk eleman saysnn dizi tanmnda ak olarak belirtilmesi gerekir nk aksi durumda sonradan gelen elemanlar iin yer ayrlmam olur.

Dizinin bir eleman zerinde ilem yapmak iin o elemann kanc eleman olduunu belirtmek gerekir. Bu belirtim de dizi adnn yannda elemann sra numarasnn keli ayralar iine yazlmasyla yaplr, yani

score[i], score dizisinin i. eleman anlamna gelir. Bu yazm

89

Diziler

dizi tanmndaki yazmla ayn olmakla birlikte anlam olarak tamamyla farkldr: tanmda keli ayralar iine yazlan say dizinin tutabilecei eleman saysn gsterirken burada kanc eleman zerinde ilem yapldn gsterir. C dilinde dizilerin ilk elemannn sra numaras her zaman 0'dr; yani ilk elemann sra numaras 0, ikinci elemann sra numaras 1 olacak ekilde ilerler (ekil 5.2a). Bu durumda n elemanl bir dizinin son elemannn sra numaras n - 1 olur. Bu zellik nedeniyle zerinde ilem yapacak tipik bir C dngs

elemanl bir dizi

for (i = 0; i < n; i++)


eklinde balar. lk elemann sra numaras 0 olduundan

for

blouna ilk girite dizinin ilk

eleman ile ilem yaplr. Son ilem de n - 1 sra numaral elemanla yaplr, dng sayac n deerini aldnda dngden klr. Burada dizinin tanmda belirtilen boyuyla gerekten kullanlan eleman says arasndaki ayrma dikkat edilmelidir. rnekte tanmda belirtilen boy geerli elemann sra numaras

MAXSTUDENTS olsa da dng 0. elemandan MAXSTUDENTS - 1. elemana kadar gitmez nk son no_students - 1 olacaktr: for (i = 0; i < no_students; i++)
score

MAXSTUDENTS-1

(a)
score

MAXSTUDENTS

(b)

ekil 5.2: Dizi elemanlarnn sra numaralar. Derleyici dizilerin elemanlarna eriimde dizi snrlarnn denetimini yapmaz; yani n elemanl bir dizinin n. ya da daha sonraki elemanlarna eriilmeye kalklrsa hata vermez. Dizi snrlarndan tamamak programcnn sorumluluundadr. Dizi snrndan taacak bir sra numaras verilirse bellekte ilk elemandan balanarak istenen sayda eleman kadar ilerlenip orada ne bulunursa o deerle ilem yaplmaya allr (ekil 5.2b). Byle bir eriim alma annda iki tr soruna yol aabilir:

1. Gelinen bellek gz, baka bir deiken iin ayrlm bir blgeye debilir. Bu durumda, baka bir deikenin deeri istenmeden deitirilmi olur ve programn almas zerinde beklenmedik etkiler yaratabilir. 2. Eriilmek istenen bellek blgesi kullancnn izni olan blgeler dnda bir yere debilir. Bu durumda bir bellek hatas oluur.

Tek Boyutlu Diziler

90

rnek 14. Tmce Tersine evirme

Kullancnn yazd tmceyi tersine evirerek ekrana kartan bir program yazlmas isteniyor. Programn rnek bir almas ekil 5.3'de verilmitir.

Tmce: Deneme bir ... Tersi: ... rib emeneD

ekil 5.3: rnek 14 ekran kts.

rnek 14 Tmceyi tersine eviren program.


#include #include #include #include <iostream> <stdlib.h> <stdio.h> <string.h> // // // //

cin,cout,endl EXIT_SUCCESS gets strlen

using namespace std; #define MAXLENGTH 80 int main(void) { char sentence[MAXLENGTH]; int len, i; char tmp; cout << "Tmce: "; gets(sentence); len = strlen(sentence); for (i = 0; i < len / 2; i++) { tmp = sentence[i]; sentence[i] = sentence[len - 1 - i]; sentence[len - 1 - i] = tmp; } cout << "Tersi: " << sentence << endl; return EXIT_SUCCESS;

rnek program, batan ve sondan ayn srada olan simgelerin yerlerinin takas edilmesi algoritmasn kullanr. Yani ilk simgeyle son simge, ikinci simgeyle sondan bir nceki simge v.b. takas edilir. Bu algoritmann doru almas iin takasn katarn ortasna kadar srmesi ve katar ortasn gememesi gerekir. (Neden?)

91

Diziler

5.2

Katarlar

C dilinde katarlar birer simge dizisi olarak deerlendirilir ve sonlarna konan '\0' simgesiyle sonlandrlrlar. Bu nedenle katar iin bellekte ayrlmas gereken yer, katarn ierdii simge saysnn bir fazlasdr. rnekteki

char sentence[MAXLENGTH];
tanm, her biri simge tipinden, 80 elemanl, uzunluunda olabilir. Katar tipinden bir deikenin tanmlanmas srasnda ift trnaklar iinde balang deeri belirtilebilir. Tanmlanan boyun katar iin gereken yeri ayrmasna dikkat edilmelidir. stenirse boyut belirtilmeyebilir; bu durumda derleyici gerekli yeri kendisi ayrr. Aadaki iki tanm ayn ii grrler (ekil 5.4a):

sentence adnda bir katar oluturur. Bu eleman-

lardan biri '\0' simgesi iin kullanlacandan kullancnn yazaca tmce en fazla 79 simge

char sentence[15] = Deneme bir ...; char sentence[] = Deneme bir ...;
sentence D e n e m e b i r . . . \0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

(a)
sentence D e n ....... . . . \0 0 1 2 11 12 13 14 15 ........ 79 80

(b)

ekil 5.4: Katarlara balang deeri atanmas. Tam gerektii kadar yer ayrmak riskli bir davrantr. Programn iinde katarn uzamas szkonusu olabilecekse gerekebilecek maksimum alan gznne alnmal ve tanm srasnda bu boy belirtilmelidir.

char sentence[MAXLENGTH] = Deneme bir ...;


komutu

MAXLENGTH

simgelik yer ayrr ancak yalnzca ilk 15 simgeyi doldurur (ekil 5.4b).

Katarlarn elemanlarna dizilerde olduu gibi teker teker eriilebilir. Dizilerde olduu gibi, ilk elemann, yani katarn ilk simgesinin sra numaras 0 olacaktr. Son elemann sra numaras da ayrlan yerin bir eksiidir. Yukardaki rnekte ' ',

sentence[13]

eleman '.',

sentence[14]

sentence[0] eleman 'D', sentence[6] eleman


eleman '\0' deerlerini alrlar.

Katar Kitapl

92

Katar tipinden deikenlerin sorun olmazken,

cout birimi yardmyla ktya gnderilmelerinde herhangi bir cin ile girdi aamasnda sorun kabilir. Kullancnn yazd katarda boluk simgesi varsa, cin birimi birden fazla deikenin girildiini dnerek yalnzca ilk bolua kadar olan blm deikene aktaracaktr. rnekte bu amala katarn girdi ilemi gets kitaplk
fonksiyonuyla gerekletirilmitir.

1 Bu komutun yerine

cin > > sentence;


komutu kullanlm olsayd programn almas ekil 5.5'de grld gibi olurdu.

Tmce: Deneme bir ... Tersi: emeneD

ekil 5.5: rnek 14 hatal ekran kts.

5.3

Katar Kitapl

Katarlar birer dizi olduklarndan katarlar arasnda atama yapmak ya da katarlar karlatrmak iin katar kitaplndaki fonksiyonlarn kullanlmas gerekir. rnek programda, katarn uzunluunu belirlemek zere bu kitaplktaki

strlen

fonksiyonundan yararlanlmtr.

Katar tipinden iki deikenin birbirine atanmas ya da karlatrlmas ilemleri standart ileler kullanlrsa beklenmedik sonular dourabilir. Baka bir deyile, atama iin

str1 = str2;
ya da karlatrma iin

if (str1 == str2)
gibi yaplar kullanlmaz.

Katarlar zerinde ska kullanlan temel ilemler iin bir katar kitapl tanmlanmtr. Bu fonksiyonlarn kullanlabilmesi iin programlarn banda gerekir. Katar kitaplnn en sk kullanlan fonksiyonlar Tablo 5.1'de verilmitir. Katar uzunluu fonksiyonu sondaki

string.h balk dosyasnn alnmas

'\0'

simgesini gznne almaz.

strlen(computer) 8
1 2
Gvenlik nedenleriyle

gets

kitaplk fonksiyonunun kullanlmas tehlikelidir. Bu komutun yerine

fgets

fonksiyonunun kullanlmas nerilir (bkz. Blm 8). Daha ayrntl aklama iin bkz. Blm .7.3.

93

Diziler

Ad

levi katar uzunluu katar kopyalama katar karlatrma katar bititirme

strlen(s) strcopy(dest,src) strncpy(dest,src,n) strcmp(s1,s2) strncmp(s1,s2,n) strcat(dest,src) strncat(dest,src,n)

Tablo 5.1: Katar kitapl fonksiyonlar.

Katar kopyalama fonksiyonlar ikinci giri parametresi olan katar, birinci giri parametresi olan katarn stne yazarlar. Bititirme fonksiyonlarysa ikinci giri parametresi olan katar, birinci giri parametresi olan katarn ardna eklerler. Her iki fonksiyon grubu da sonu katarnn sonuna konmas gereken '\0' simgesini kendileri koyarlar. Katar ilemi yapan fonksiyonlarn bazlarnda uzunluk denetimi yaplr, bazlarnda yaplmaz. Szgelimi

strcpy

fonksiyonu

src

katarnn deerini

fonksiyonu da ayn ilevi grr, ancak en fazla

n simgeyi kopyalar. Gvenlik asndan uzunluk


3

dest

katarnn stne yazarken,

strncpy

denetimi yapan fonksiyonlarn kullanlmas nerilir.

Katar karlatrma fonksiyonlar giri parametresi olan katarlar arasnda ngilizce dilinin kurallarna gre szlk sras karlatrmas yaparlar. ki katar eitse 0, birinci katar ikinciden nce geliyorsa -1, sonra geliyorsa 1 deerini dndrrler.

strcmp(abc, ad)

-1 1 0

strcmp(abcd, abc)

strncmp(abcd, abcde, 4)

Kopyalama ve bititirme fonksiyonlarnda dikkat edilmesi gereken bir nokta, hedef katarn yeterli uzunlukta olmasnn salanmasdr. rnein, aadaki program paras hataya yol aabilir:

char author1[] = Brian, author2[] = Dennis; ... strcpy(author1, author2);


Derleyici sonra

author1 katarna 6 simgelik, author2 katarnaysa 7 simgelik yer ayracaktr. Daha author1 katarnn stne author2 katar yazlmaya kalkldnda author1 katarnda

yeterli yer olmad iin bu deikenin snrlarndan talr. Benzer ekilde, bititirme ilemlerinde de hedef katar iin iki asl katarn toplam uzunluklarn tutmaya yetecek kadar yer ayrlm olmaldr.

Uzunluk denetimi yapmayan katar fonksiyonlar tampon tarma ad verilen saldrlara yol aan kaynaklar

arasnda en byk yeri tutar.

ok Boyutlu Diziler

94

Uygulama: Tek Boyutlu Diziler


rnek 15. Polinom Hesab

p(x) = an xn + an1 xn1 + + a1 x + a0


eklinde yazlan

n.

dereceden bir polinomda verilen bir

deeri iin

p(x)'in

hesaplanmas

n(n+1) adet arpma ve 2


bu say azaltlabilir.

adet toplama ilemi gerektirir. ie arpma ve toplama yntemiyle

Polinomu u ekilde yeniden yazalm:

p(x) = (((an x + an1 )x + an2 )x + + a1 )x + a0


O halde bir gidilirse olur.

b deeri, balangta b = an ve i. admda b = bx+ani olacak ekilde hesaplanarek a0 katsaysnn da toplanmasyla elde edilecek b deeri hesaplanmak istenen p(x) deeri Yaplmas gereken ilem says da n arpma ve n toplamaya iner.
kts verilen program kullanarak

p(x) = 13x7 9x6 + 12x4 4x3 + 3x + 5


polinomunun

p(4), p(2.5)

ve

p(19)

deerlerini hesaplatn.

rnek 16. Matris arpm


Bu blmde zerinde allacak program, boyutlar ve elemanlar kullancdan alnan iki matrisi arparak sonucu ekrana kartr. Programn rnek bir almasnn ekran kts ekil 5.6'da verilmitir.

5.4

ok Boyutlu Diziler

ok boyutlu bir dizi tanmlanmasnda her boyut ayr bir keli ayra ifti iinde belirtilir. rnekteki

int left[MAXSIZE][MAXSIZE];
komutu, 30 satrl ve 30 stunlu bir matris tanmlar. Bu matrisin, her biri birer tamsay olan, 30*30=900 eleman olacaktr, yani bellekte 900 tamsay tutacak kadar yer ayrlmasna neden olur. Daha ok boyutu olan bir dizi tanmlanmak istenseydi boyutlar yanyana srdrlebilirdi:

int m[30][20][7][12];

95

Diziler

rnek 15 Polinom deeri hesaplayan fonksiyon.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; #define MAXDEGREE 50 int main(void) { float a[MAXDEGREE]; float x, b; int n, i; char response = 'E'; cout << "Polinomun derecesi: "; cin >> n; cout << "Katsaylar: " << endl; for (i = n; i >= 0; i--) { cout << "a" << i << ": "; cin >> a[i]; } while (true) { cout << "x: "; cin >> x; b = a[n]; for (i = n - 1; i >= 0; i--) b = b * x + a[i]; cout << "p(x): " << b << endl; cout << "Devam etmek istiyor musunuz (E/H)? "; cin >> response; if ((response == 'H') || (response == 'h')) break; } } return EXIT_SUCCESS;

ok Boyutlu Diziler

96

Sol matrisin satr says: 5 Sol matrisin stun says: 3 Sa matrisin stun says: 4 Sol matris: [1,1]: 2 [1,2]: 7 [1,3]: -1 [2,1]: 3 [2,2]: 5 [2,3]: 2 [3,1]: 0 [3,2]: 4 [3,3]: 1 [4,1]: 9 [4,2]: 0 [4,3]: -3 [5,1]: 4 [5,2]: 7 [5,3]: 2 Sa matris: [1,1]: 0 [1,2]: 5 [1,3]: 2 [1,4]: -4 [2,1]: 1 [2,2]: 7 [2,3]: 3 [2,4]: 2 [3,1]: 5 [3,2]: 2 [3,3]: 0 [3,4]: -1 arpm sonucu: 2 57 25 7 15 54 21 -4 9 30 12 7 -15 39 18 -33 17 73 29 -4

ekil 5.6: rnek 16 ekran kts.

97

Diziler

rnek 16 ki matrisi arpan program.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; #define MAXSIZE 30 int main(void) { int left[MAXSIZE][MAXSIZE], right[MAXSIZE][MAXSIZE]; int product[MAXSIZE][MAXSIZE] = { 0 }; int rl, cl, cr; int &rr = cl; int i, j, k; cout << "Sol matrisin satr says: "; cin >> rl; cout << "Sol matrisin stun says: "; cin >> cl; cout << "Sa matrisin stun says: "; cin >> cr; cout << "Sol matris: " << endl; for (i = 0; i < rl; i++) { for (j = 0; j < cl; j++) { cout << " [" << i + 1 << "," << j + 1<< "]: "; cin >> left[i][j]; } } cout << "Sa matris: " << endl; for (j = 0; j < rr; j++) { for (k = 0; k < cr; k++) { cout << " [" << j + 1 << "," << k + 1 << "]: "; cin >> right[j][k]; } } for (i = 0; i < rl; i++) { for (j = 0; j < cr; j++) { for (k = 0; k < cl; k++) product[i][j] = product[i][j] + left[i][k] * right[k][j]; } } cout << "arpm sonucu:" << endl; for (i = 0; i < rl; i++) { for (k = 0; k < cr; k++) cout << "\t" << product[i][k]; cout << endl; }

Bavurular

98

Bu ilem sonucunda da bellekte 30*20*7*12=50400 tamsay tutacak kadar yer ayrlr. Tek boyutlu dizilerde olduu gibi, ok boyutlu dizilerde de balang deeri verilebilir. Bunun iin her bir boyutun kendi iinde ssl ayralar iine alnmas gerekir:

int m[2][3] = { { 1, 2, 1 }, { 3, 5, 1 } };
1 2 1 3 5 1

tanm

m=

matrisini oluturur. Tek boyutlu dizilerdekine benzer ekilde

{ 0 }

balang deeri btn elemanlara 0 balang deerini atar. ok boyutlu dizilerde ilki dnda btn boyutlarn belirtilmesi zorunludur. Szgelimi bir isim dizisi oluturulmak isteniyorsa

char names[][] = { Dennis, Brian, Ken };

tanmlamas derleyicinin hata vermesine neden olur. Birinci boyut dndakiler belirtilerek yazlrsa

char names[][10] = { Dennis, Brian, Ken };

her bir eleman en fazla 10 simge uzunluunda olabilen 3 elemanl bir katar dizisi tanmlanm olur. Yani derleyici isim dizisinin eleman saysn sayar ancak belirtilen balang katarlarnn uzunluklarn hesaplamaya almaz. Yine de belirtilen uzunluktan daha uzun bir balang katar yazlrsa (diyelim 15 uzunluklu) derleyici bir hata retebilir.

5.5

Bavurular
4 rnekte sol matrisin satr

Bavurular, ayn deikene ikinci bir isim verilmesini salarlar. deikenle temsil etmek yeterli grlm ve anlalrl artrmak amacyla

says ile sa matrisin stun saylarnn ayn olmas zorunluluu nedeniyle bu bilgiyi tek bir

rr

deikeninin

cl

cl deikeni tanmlanmtr. Ancak dnglerde rr deikeninin de tanmlanmasnn yararl olaca dnlerek

deikenine bavurmas salanmtr. Bu iki deiken bellekte ayn gzde

bulunurlar ve dolaysyla birinde yaplan deiiklik dorudan doruya dierini etkiler. rnekte

durumda

rr deikeni bavuru olmak yerine ikinci bir deiken olarak da tanmlanabilirdi. Bu cl deikeni kullancdan okunduktan sonra rr = cl eklinde bir atamayla ilem sr-

drlebilirdi. Bu yaklamda, iki deiken birbirinden ayrlm olaca iin birindeki deiiklik dierini etkilemezdi, ancak programda boyut deikenleri zerinde bir deiiklik olmad iin bir sorun kmazd. Tek fark, gereksiz yere ikinci bir deiken tanmlanm olmas olurdu.

Bavurular, C++ ile gelmi bir yeniliktir, C dilinde yoktur.

99

Diziler

Uygulama: Matrisler

rnek 17. Gauss Eliminasyon Yntemi

ax = b eklinde yazlan n bilinmeyenli bir lineer denklem takmnda a katsay matrisini, b deimezler vektrn ve x zm vektrn gsterir. Bu denklem takmnn zm iki
aamaldr:

1.

a matrisi baz dnmlerle bir gen matris haline getirilir. Bunun iin nce sistemin ai1 i = 2, 3, . . . , n. denklemlerinden x1 yok edilir (birinci denklem a11 ile arplp i. denklemden karlr). Benzer ekilde, i = 3, 4, . . . , n. denklemlerden x2 yok edilerek devam edilir. Birinci denklemin birinci eleman olan a11 'e pivot ad verilir ve x1 yok edilip ikinci denkleme geildiinde a22 eleman pivot olur. Yntemin alabilmesi iin btn pivotlarn
sfrdan farkl olmas gerektii aktr.

2.

xn

deeri

nursa

n. denklemden dorudan hesaplanr. Bu deer n 1. denklemde yerine koxn1 bulunur ve bylece geriye doru yerine koyma ilemleriyle btn bilinmeyen

deerler hesaplanabilir.

Denklem takm u ekilde verilmi olsun:

x1 + x2 = 3.5 x1 x2 + 5x3 = 11 2x1 x2 + x3 = 3.3 a


matrisi ve

vektrnn deerlerini adm adm izlersek:

balangta:

1 1 0 3.5 a = 1 1 5 b = 11 2 1 1 3.3 1 1 0 3.5 a = 0 2 5 b = 7.5 0 3 1 3.7 1 1 0 3.5 5 b = 7.5 a = 0 2 0 0 6.5 14.95


x1 'in

yok edilmesinden sonra:

x2 'nin

yok edilmesinden sonra:

Son denklemden

7.5

denkleminden

x3 = 2.3 elde edilir. Bu deer ikinci denklemde yerine konursa:2x2 + 5x3 = x2 = 2 ve bu deer birinci denklemde yerine konursa x1 + x2 = 3.5 denklebulunur.

minden

x1 = 1.5

Gauss eliminasyon yntemini kullanarak rnek 17'da verilmitir.

bilinmeyenli bir denklem takmn zen program

Bavurular

100

rnek 17 Gauss eliminasyon yntemiyle denklem takm zen program.


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; #define MAXEQUATIONS 5 int main(void) { float a[MAXEQUATIONS][MAXEQUATIONS], b[MAXEQUATIONS]; float x[MAXEQUATIONS]; float pivot, f; int n; int i, j, k; cout << "Denklem says: "; cin >> n; for (i = 0; i < n; i++) { cout << "Denklem " << i + 1 << ": "; for (j = 0; j < n; j++) { cin >> a[i][j]; } cin >> b[i]; } for (j = 0; j < n - 1; j++) { pivot = a[j][j]; for (i = j + 1; i < n; i++) { f = a[i][j] / pivot; for (k = j + 1; k < n; k++) a[i][k] = a[i][k] - f * a[j][k]; b[i] = b[i] - f * b[j]; } } x[n-1] = b[n-1] / a[n-1][n-1]; for (i = n - 2; i >= 0; i--) { f = b[i]; for (k = i + 1; k < n; k++) f = f - a[i][k] * x[k]; x[i] = f / a[i][i]; } for (i = 0; i < n; i++) cout << "x" << i + 1 << ": " << x[i] << endl; } return EXIT_SUCCESS;

101

Diziler

Sorular
1. Kullancnn girdii bir tmcedeki szck saysn sayan bir program yazn. Szcklerin nnde ve arkasnda boluk olduu varsaylacaktr. Ancak szck arasnda istendii sayda boluk olabilecei gibi tmcenin banda ve sonunda da istendii kadar boluk olabilir. rnek olarak kullanc

the

world

is not

enough

 tm-

cesini girerse programn kts 5 olacaktr. 2. Eratosthenes kalburu yntemini kullanarak ilk 10000 say iindeki asal saylar ekrana kartan bir fonksiyon yazn. 3. Kullancdan alnan bir sayy yaz olarak ekrana kartan bir program yazn. rnein kullanc 21355 saysn girerse program ekrana Yirmibirbinyzellibe yazacaktr. 4. Kullancnn verdii sayy Roma rakamlarna evirerek ekrana kartan bir program yazn. rnein kullanc 523 saysn girerse ekrana DXXIII katar karlmaldr. 5. Verilen bir tarihin haftann hangi gnne geldiini bulan bir program yazn. rnein kullanc 24-09-2002 tarihini girerse ekrana Sal katar karlmaldr. 6. Kullancdan alnan iki tarih arasnda geen gn saysn hesaplayan bir program yazn. 7. Kullancdan ald bir tarihin haftann hangi gnne geldiini bulan bir program yazn.

Bavurular

102

Blm 6
Fonksiyonlar

u ana kadar yaplan rneklerde btn ilemler tek bir fonksiyonda (main fonksiyonu) gerekletiriliyordu. Gereken yerlerde kitaplk fonksiyonlarndan yararlanlmakla birlikte, kendi yazdmz kod tek bir fonksiyonla snrlyd. Oysa blok yapl programlamada soyutlama kavramnn neminden Blm 1.4'de sz edilmi, ileri alt-ilere, alt-ileri alt-alt-ilere blerek yazlan programlarn hem gelitirme hem de bakm aamalarnda salayaca kolaylklar grlmt. Bu blmde de programcnn kendi fonksiyonlarn nasl yazacan inceleyeceiz. C dilinde her i ya da alt-i bir fonksiyon tarafndan gereklenir. Fonksiyonlar yapacaklar ii belirleyen giri parametreleri alrlar ve ilemin sonucuna gre bir k parametresi retirler. Yani giri parametrelerinin says birden fazla olabilir ancak k parametresi en fazla bir tanedir. imdiye kadar kullanlan kitaplk fonksiyonlarnn bazlarna parametreleri asndan bakarsak:

sqrt: pow:

Kesirli say tipinden bir giri parametresi alr, kesirli say tipinden bir k para-

metresi retir. kisi de kesirli say tipinden iki giri parametresi alr, kesirli say tipinden bir k

parametresi retir.

strlen:
retir.

Katar tipinden bir giri parametresi alr, tamsay tipinden bir k parametresi

rand:

Giri parametresi almaz, tamsay tipinden bir k parametresi retir. aretsiz tamsay tipinden bir giri parametresi alr, k parametresi retmez.

srand:

Bir fonksiyonun bir alt-iini yaptrmak zere baka bir fonksiyonu kullanmasna fonksiyon
ars ad verilir. rnek 7'da,

main

fonksiyonu,

for

blounun ilk komutunda

rand

fonksiyo-

nunu armaktadr. Fonksiyon arsnda st fonksiyona aran fonksiyon, alt fonksiyona da


arlan fonksiyon denir, yani rnekte

main

fonksiyonu aran,

rand

fonksiyonuysa arlan

fonksiyondur. Fonksiyon arsnn sona ermesinden sonra aran fonksiyonda ak bir sonraki komutla devam eder. aran fonksiyon arlan fonksiyona giri parametrelerini gnderir, arlan fonksiyonsa rettii sonucu aran fonksiyona dndrr. Dndrlen deer aran fonksiyonda bir deikene 103

104

atanabilecei ya da bir deyimde kullanlabilecei gibi, dorudan baka bir fonksiyona giri parametresi olarak da gnderilebilir.

1 rnekte

time

fonksiyonunun dndrd deer,

srand

fonksiyonuna parametre olarak gnderilmitir:

number = rand(); number = rand() % 6; srand(time(NULL));

// dorudan atama // deyimde kullanma // baka fonksiyona gnderme rand


fonksi-

k parametrelerinin kullanmnda tip uyumuna dikkat edilmelidir. Szgelimi, yonu tamsay tipinden bir deer dndrdne gre olmaldr, katar tipinden olamaz.

2 Benzer ekilde, bir fonksiyondan gelen bir deer kalan ile-

number

deikeni de tamsay tipinden

mine sokulacaksa bu deerin tamsay tipinden olmasna dikkat etmek gerekir. Giri parametrelerinin aktarm iin aran fonksiyondaki parametreleri yollama ekliyle arlan fonksiyonun parametreleri bekleme ekli uyumlu olmaldr. Bu uyumluluk u ekilde tanmlanabilir:

1. arlan fonksiyon ka parametre bekliyorsa aran fonksiyon o sayda parametre yollamaldr. 2. arlan fonksiyon her bir sradaki giri parametresinin tipinin ne olmasn bekliyorsa aran fonksiyon bu tipe uyumlu bir deer gndermelidir.

rnein

pow

fonksiyonu iki tane kesirli say bekliyorsa bu fonksiyona iki tane kesirli say

(ya da tamsay) deeri yollanmaldr. Bir, ya da daha fazla deer yollanmas, hi deer yollanmamas, yollanan iki deerin say dnda bir tipten (szgelimi katar) olmas hataya yol aar.

rnek 18. Asal arpanlara Ayrma

Kullancnn girdii bir saynn asal arpanlarn ekrana dken bir program yazlmas isteniyor. Gerekli algoritmann ak izenei ekil 1.18'de, rnek bir almasnn ekran kts ekil 6.1'de verilmitir. Programda bir saynn asal olup olmadnn snanmasna ve asal saylarn bulunmasna gerek duyulacaktr. Soyutlama ilkesine gre bu ilemler fonksiyonlarla gerekletirilecek, ana fonksiyon, asal saylar bulan fonksiyondan srayla ald asal saylarn kullancnn verdii sayy blp blmediklerini snayacaktr. rnekte yanl mantksal deerini yollar.

is_prime

fonksiyonu

kendisine gnderilen bir saynn asal olup olmadn belirleyerek geriye asalsa doru, deilse

next_prime fonksiyonu ise kendisine gnderilen saydan daha

byk olan ilk asal sayy bularak kendisini aran fonksiyona dndrr.

1 2

Aslnda bu durumlarn hepsi deyimde kullanma olarak deerlendirilebilir. Eski C derleyicileri bu tip denetimlerde fazlasyla gevek davranabilmektedir. Bu durum programcnn

hata yapmasna zemin hazrlar.

105

Fonksiyonlar

rnek 18 Bir sayy asal arpanlarna ayran program.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; int next_prime(int prime); int main(void) { int number, factor = 2; cout << "Sayy yaznz: "; cin >> number; while (number > 1) { while (number % factor == 0) { cout << factor << " "; number = number / factor; } factor = next_prime(factor); } cout << endl; return EXIT_SUCCESS;

bool is_prime(int cand) { int count; if (cand == 2) return true; if (cand % 2 == 0) return false; for (count = 3; count * count <= cand; count += 2) { if (cand % count == 0) return false; } return true;

int next_prime(int prime) { int cand = (prime == 2) ? 3 : prime + 2; while (!is_prime(cand)) cand += 2; return cand;

Fonksiyon Bildirimi ve Tanm

106

Sayy yaznz: 6468 2 2 3 7 7 11

ekil 6.1: rnek 18 ekran kts.

6.1

Fonksiyon Bildirimi ve Tanm

Bir fonksiyon iki bileenden oluur:

Fonksiyonun bal, fonksiyonun adn ve giri/k parametrelerini belirtmeye yarar. Soyutlamadaki karlyla fonksiyonun NE yaptn anlatr. Fonksiyon balnn belirtilmesi ilemine fonksiyonun bildirimi denir ve baln sonuna bir noktal virgl konarak yaplr. Bildirim komutunun yazm u ekildedir:

k_parametresi_tipi fonksiyon_ad (giri_parametresi_listesi );


rnekte

next_prime

fonksiyonu iin yaplan

int next_prime(int prime);


bildirimine gre,

next_prime

fonksiyonu tamsay tipinden bir giri parametresi alr ve

yine tamsay tipinden bir k parametresi dndrr. k parametresi herhangi bir skalar ya da bileke tipten olabilir ancak dizi olamaz. Giri parametresi listesiyse birbirinden virglle ayrlm

veri_tipi deiken_ad

iftleri

eklindedir. k parametresi dndrmeyen fonksiyonlarn k parametresi tipi listesi parametresine de

void

sakl szcyle belirtilir. Benzer ekilde, giri parametresi almayan fonksiyonlarn giri

void

yazlr. Bu bilgileri gznnde bulundurarsak, kulland-

mz baz kitaplk fonksiyonlarnn sistemde yle bildirilmi olmalar gerektii grlebilir:

double sqrt(double x); double pow(double x, double y); int rand(void); void srand(unsigned int seed);
Giri parametresi listesindeki deikenlerin yazm deiken tanm yazmna benzer ancak ayn tipten deikenler gruplanamaz. Szgelimi aadaki bildirim hataldr:

double pow(double x, y);


Fonksiyon bildirimi, derleyiciye giri parametresi listesi tipinden deikenler alan ve k parametresi tipinden deer reten belirtilen isimde bir fonksiyon olduununun bildirilmesini salar. Bylelikle derleyici bu fonksiyon arsn grd yerde parametrelerin uyumlu olup olmadklarn denetleyebilir. alma annda fonksiyon arsna gelindiinde uygun yere gidilmesini salayacak balantlar kurmak derleyicinin deil balaycnn grevidir.

107

Fonksiyonlar

Fonksiyonun gvdesi, fonksiyonun yapaca ileri belirten bloktan oluur, yani fonksiyonun iini NASIL yaptn anlatr. Bir fonksiyonun btnnn, yani giri/k parametrelerinin yansra gvdesinin de belirtildii yere fonksiyonun tanm denir. rnekte

is_prime fonksiyonu, main fonksiyonunun bitiminden sonra, next_prime fonksiyonu da is_prime fonksiyonunun bitiminden sonra tanmlanmtr.
arlan fonksiyon rettii deeri aran fonksiyona rr.

return komutu yardmyla dndreturn sakl szcnden sonra yazlan deyim fonksiyonun balnda belirtilen veri tipine uygun tipten bir deer retmelidir. rnekte is_prime fonksiyonu mantksal tipten tanmlanmtr ve fonksiyonun eitli noktalarnda false ya da true deerlerini dndrmektedir. next_prime fonksiyonuysa tamsay tipinden tanmlanmtr ve dndrd deeri tutan deiken de (cand) tamsay tipindendir.

Bir fonksiyon arsnn yaplabilmesi iin arlan fonksiyonun ya bildirimi ya da tanm a-

next_prime fonksiyonunu, next_prime fonksiyonu da is_prime fonksiyonunu arr. Birinci ar, next_prime fonksiyonunun bildirimi main fonksiyonunun tanm balamadan yapldndan baarl olur. kinci arysa is_prime fonksiyonu next_prime fonksiyonundan nce tanmlandndan baarl olur. Ancak rnein main fonksiyonu is_prime fonksiyonunu aramaz nk ncesinde is_prime
ran fonksiyondan nce yaplmaldr. rnekte fonksiyonu fonksiyonunun ne tanm ne de bildirimi vardr. Kendi yazdnz fonksiyonlarda olduu gibi, kitaplk fonksiyonlarn da arabilmeniz iin bu fonksiyonlarn bildirimlerinin daha nceden yaplm olmas gerekir. Bu bildirimler kullandnz derleyiciyle gelen balk dosyalarnda yer alr; bir kitaplk fonksiyonunu kullandnzda balk dosyasn belirtmeniz zorunluluu da buradan doar.

main

6.2

Parametre Aktarm

Giri parametrelerinin aktarmnda fonksiyon arsnda belirtilen parametre listesiyle fonksiyonun balnda belirtilen liste uyumlu olmaldr. arda yazlan her deer, arlan fonksiyonun balnda ayn srada yazlm deikene atanr. Bu parametre aktarm yntemine
deer aktarm ad verilir. rnekteki birinci fonksiyon arsnda:

factor = next_prime(factor); main fonksiyonundaki factor deikeninin deeri next_prime fonksiyonunun giri parametresi olan prime deikenine atanr. Dnte de next_prime fonksiyonunun return komutuyla geri yollad cand deikeninin deeri main fonksiyonundaki factor deikenine atanr. Fonksiyonun bir dng iinde arld gznne alnarak, parametre olarak ilk arda 2 deerinin gnderilecei ve 3 deerinin dnecei, ikinci arda 3 deerinin gnderilecei ve 5 deerinin dnecei, ileriki arlarda 5, 7, 11, ... deerlerinin gnderilecei grlebilir. Benzer ekilde, ikinci fonksiyon arsnda fonksiyonunun giri parametresi olan

next_prime fonksiyonundaki cand cand deikenine atanr.

deikeninin deeri

is_prime

Tipi uygun olduu srece parametre olarak herhangi bir deyim belirtilebilir. Szgelimi aadaki arlar geerlidir:

Yerel Deikenler

108

number main 6468

factor 2

prime next_prime

cand

cand is_prime

count

ekil 6.2: Parametre aktarm rnei - 1. adm.

is_prime(13) is_prime(cand + 1)
Benzer ekilde, geri dndrlecek deer iin uyumlu tipten deer reten bir deyim yazlabilir:

return cand + 2;

6.3

Yerel Deikenler

Parametre aktarm anlatlrken  main fonksiyonundaki fonksiyonunun giri parametresi olan deikeninin deeri

factor deikeninin deeri next_prime prime deikenine ,  next_prime fonksiyonundaki cand is_prime fonksiyonunun giri parametresi olan cand deikenine gibi next_prime prime main
fonksiyonun-

szler kullanld. Buradan da grlebilecei gibi, deikenler iinde tanmlandklar fonksiyon ile birlikte deerlendirilirler ve yalnzca bu fonksiyon iinde geerlidirler. daki

factor

deikeni ile

fonksiyonundaki

deikeni farkl deikenlerdir, fonksiyonundaki

bellekte farkl yerlerde bulunurlar; dolaysyla, birinde yaplan deiiklik dierini etkilemez. Deiken adlarnn ayn olmasnn da bir nemi yoktur: deikeniyle

is_prime

fonksiyonundaki

cand

next_prime

cand

deikeni de farkl deikenlerdir.

rnekte ilk fonksiyon arlar yle gerekleir. langta atanm olan 2 deeri

main fonksiyonunda factor deikenine banext_prime fonksiyonunun prime adl giri parametre deikenine aktarlr (ekil 6.2). next_prime fonksiyonunda cand deikeni 3 deerini alr ve bu deer asal olup olunmadnn belirlenmesi iin is_prime fonksiyonunun cand adl giri parametre deikenine aktarlr (ekil 6.3). is_prime fonksiyonunda count deikeni 3 deerini alr ancak dng koulu batan salanmadndan dngden klarak next_prime fonksiyonuna true deeri dndrlr (ekil 6.4). Bu deer !is_prime(cand) koul deyiminin yanl sonucunu retmesine neden olduundan dngden klr ve main fonksiyonuna cand deikeninin o anki deeri, yani 3 dndrlr. Bu deer de main fonksiyonundaki factor deikenine atanr
(ekil 6.5) Fonksiyonun parametre olarak ald ya da fonksiyon gvdesinde tanmlanan deikenlere o fonksiyonun yerel deikenleri ad verilir ve bunlarn tanm blgesi tanmlandklar fonksiyonla

109

Fonksiyonlar

number main 6468

factor 2

prime next_prime 2

cand 3

cand is_prime

count

ekil 6.3: Parametre aktarm rnei - 2. adm.

number main 6468

factor 2

prime next_prime 2

cand 3

!is_prime(cand)

true cand is_prime 3 count 3

ekil 6.4: Parametre aktarm rnei - 3. adm.

number main 6468

factor 2

prime next_prime 2

cand 3

cand is_prime 3

count 3

ekil 6.5: Parametre aktarm rnei - 4. adm.

Genel Deikenler

110

snrlanr. rnekteki btn fonksiyonlarn ikier (main: ve

count, next_prime: prime

ve

cand)

number

ve

factor, is_prime: cand

yerel deikeni vardr. Fonksiyonun sona ermesiyle

tanmlad deikenler de geersiz hale gelir. Baka bir deyile, deikenlere tanm blgeleri dnda eriilemez. Yani szgelimi kullanamaz.

main fonksiyonu number ve factor dnda kalan deikenleri

6.4

Genel Deikenler

Baz durumlarda birden fazla fonksiyonun ayn deikeni kullanabilmeleri istenir. Bu tip deikenlere genel deiken ad verilir ve tanm blgeleri btn fonksiyonlar olarak belirlenir. Genel deikenler btn fonksiyonlarn tanmlarndan nce tanmlanrlar.
DKKAT

Genel deikenlere rnek vermek iin programda baz deiiklikler yaplabilir. BU DEKLKLERN SONUCUNDA OLUACAK PROGRAM Y BR PROGRAM OLMAYACAKTIR. BU RNEK YALNIZCA GENEL DEKEN KULLANIMINI AIKLAMAK AMACIYLA VERLMTR. fonksiyonunun ilevi metre olarak aktarmak yerine ortak bir bellek gznde paylaabilirler. Bu durumda

next_prime ve is_prime fonksiyonlar aslnda cand deikenini parais_prime bu deikenin deerinin asal olup olmadn belirlemek, next_prime

fonksiyonunun ileviyse bu deikenin deerini kendisinden byk ilk asal sayya ilerletmek olarak dnlebilir. Benzer ekilde, ana fonksiyon da arpan aday olan sayy parametre aktarmyla almak yerine ayn genel deikende erierek renebilir. Deiiklikler sonucu oluan program rnek 19'de verilmitir. Bir fonksiyon bir genel deikenle ayn isimde bir yerel deiken tanmlarsa o fonksiyonun almas boyunca yerel deiken genel deikeni ezer. Diyelim

is_prime

fonksiyonu

int count, cand;


eklinde bir deiken tanm yapm olsayd, genel olan yerel olan

cand

deikeni oluurdu ve

is_prime

cand

deikeninin yannda bir de

fonksiyonunun iindeyken genel olan

cand

deikenine ulalamazd. Genel deikenler parametre aktarm yerine kullanlabilecek bir yntem olmakla birlikte programn anlalrln azalttklar ve fonksiyonlar birbirlerine baml kldklar iin gerekmedike kullanlmamalar nerilir. Soyutlamann kazandrdklarndan birinin ileride bir fonksiyonda deiiklik yapld zaman bunu aran fonksiyonlarn deiiklikten etkilenmemesi olduu sylenmiti; oysa fonksiyonlarn deiken paylarlarsa bir fonksiyonda yaplan deiiklikler dier fonksiyonlar etkileyebilir.

6.5

Bavuru Aktarm

Deer aktarm yntemiyle parametre aktarlmas baz ilemlerde yeterli olmaz. Szgelimi, kendisine giri parametresi olarak gnderilen iki tamsay deikenin deerlerini takas eden bir fonksiyonun rnek 20'daki gibi yazldn dnelim. Bu program altrldnda ekran kts u ekilde olur:

111

Fonksiyonlar

rnek 19 Genel deiken kullanarak bir sayy asal arpanlarna ayran program.
#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; int cand = 2; void next_prime(void); int main(void) { int number; cout << "Sayy yaznz: "; cin >> number; while (number > 1) { while (number % cand == 0) { cout << cand << " "; number = number / cand; } next_prime(); } cout << endl; return EXIT_SUCCESS;

bool is_prime(void) { int count; if (cand == 2) return true; if (cand % 2 == 0) return false; for (count = 3; count * count <= cand; count += 2) { if (cand % count == 0) return false; } return true;

void next_prime(void) { cand = (cand == 2) ? 3 : cand + 2; while (!is_prime()) cand += 2; }

Bavuru Aktarm

112

rnek 20 ki sayy takas eden fonksiyon ve kullanm (hatal).


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; void swap(int x, int y) { int tmp; tmp = x; x = y; y = tmp;

int main(void) { int m = 32, n = 154; cout << m << " " << n << endl; swap(m, n); cout << m << " " << n << endl; return EXIT_SUCCESS;

113

Fonksiyonlar

x swap 32

y 154

tmp xxx

m main 32

n 154 (a)

x swap 154

y 32

tmp xxx

m main 32

n 154 (b)

ekil 6.6: Takas fonksiyonunda parametre aktarm.

32 154 32 154 main fonksiyonundaki m deikeninin deeri swap fonksiyonundaki x deikenine, n deikeninin deeri de y deikenine aktarlr (ekil 6.6a). swap fonksiyonunda x ve y deikenlerinin deerleri takas edilir ancak aran fonksiyondaki m ve n deikenleri bu takastan etkilenmezler ve fonksiyon arsndan dnldnde
Programn neden istendii gibi almadn inceleyelim: eski deerlerini koruyor olurlar (ekil 6.6b). Bu sorunun zm iin yaplmas gereken, arlan fonksiyonda girdi parametrelerini bavuru tipinden tanmlamaktr (bkz. Blm 5.5). Bylelikle arlan fonksiyonun girdi parametresi, aran fonksiyonun gnderdii parametreye verilmi ikinci bir isim haline gelir ve stnde yaplan deiiklikler aran fonksiyondaki deikeni dorudan etkiler: Bu parametre aktarm yntemine bavuru aktarm ad verilir. Bir parametrenin bavuru olarak aktarldn gstermek zere yaplmas gereken tek ey arlan fonksiyondaki girdi parametre deikeninin adnn bana

&

simgesi koymaktr. Yani rnekteki tek deiiklik

swap

fonksiyonunun balk

satrnn u ekle getirilmesi olacaktr:

void swap(int &x, int &y)


Uygulama: Fonksiyonlar
rnek 21. Kombinasyon Hesab
Bu rnekte

m Cn =

m! n!(mn)! deerinin hesaplanmas istenmektedir.

Bavuru Aktarm

114

rnek 21 Kombinasyon hesab (yava).


#include <iostream.h> #include <stdlib.h> using namespace std; int combin(int a, int b); int fact(int x); int main(void) { int n, r;

// cout,cin // EXIT_SUCCESS

cout << "n ve r deerlerini yaznz: "; cin >> n >> r; cout << combin(n, r) << endl; return EXIT_SUCCESS;

int combin(int a, int b) { int f1, f2, f3; f1 = fact(a); f2 = fact(b); f3 = fact(a - b); return f1 / (f2 * f3);

int fact(int x) { int fx = 1; int i; for (i = 2; i <= x; i++) fx = fx * i; return fx;

115

Fonksiyonlar

rnek 22 Kombinasyon hesab (hzl).


#include <iostream.h> #include <stdlib.h> using namespace std; int combin(int a, int b); int main(void) { int n, r;

// cout,cin // EXIT_SUCCESS

cout << "n ve r de?erlerini yaz?n?z: "; cin >> n >> r; cout << combin(n, r) << endl; return EXIT_SUCCESS;

int combin(int a, int b) { int f1 = 1, f2, f3; int first = b, second = a - b; int i; if (b > a - b) { first = a - b; second = b; } for (i = 2; i <= first; i++) f1 = f1 * i; f2 = f1; for (i = first + 1; i <= second; i++) f2 = f2 * i; f3 = f2; for (i = second + 1; i <= a; i++) f3 = f3 * i; return f1 / (f2 * f3);

Giri Parametreleri zerinden Deer Dndrme

116

rnek 23. En Byk Ortak Blen Bulma

Blm 1.4'de anlatlan algoritmalar kullanarak iki saynn en byk ortak blenini hesaplayan bir program yazlmas isteniyor. Bunun iin rnek 18'de bir sayy asal arpanlarna ayran programn benzeri bir fonksiyon (factorize) olarak yazlacak ve bu fonksiyon kendisine parametre olarak gnderilen saynn asal arpanlarn bir dizide oluturacaktr. Fonksiyon yine ayn rnekte yazlm olan zere

next_prime

ve

is_prime

fonksiyonlarn hibir deiiklik olma-

dan kullanacaktr. Asal arpan dizilerinden en byk ortak blenin asal arpanlarn bulmak

gcd_factors

fonksiyonu kullanlacak, bu fonksiyonun oluturduu arpanlar dizisinden

en byk ortak bleni ana fonksiyon kendisi hesaplayacaktr.

rnek 23 ki saynn en byk ortak blenini bulan program (ana fonksiyon).

int main(void) { int number1, number2; factor_t factors1[MAXFACTOR], factors2[MAXFACTOR], factors3[MAXFACTOR]; int n1, n2, n3; long int gcd = 1L; int i; cout << "Saylar yaznz: "; cin >> number1 >> number2; factorize(number1, factors1, n1); factorize(number2, factors2, n2); gcd_factors(factors1, n1, factors2, n2, for (i = 0; i < n3; i++) gcd = gcd * (long int) pow((double) (double) cout << "En byk ortak blen: " << gcd return EXIT_SUCCESS;

factors3, n3); factors3[i].base, factors3[i].power); << endl;

6.6

Giri Parametreleri zerinden Deer Dndrme

Asal arpanlara ayrma iini yapan Burada iki sorunla karlalr:

factorize

fonksiyonunun giri parametresinin arpan-

larna ayrlacak say, k parametresinin de arpanlar dizisi olmas gerektii grlmt.

1. C dilinde k parametresi olarak geriye dizi dndrlemez. 2. Dizinin elemanlarn dndrmek yeterli deildir, dizide ka tane geerli eleman olduunu da dndrmek gerekir. Oysa C fonksiyonlar aran fonksiyona birden fazla deer dndremez.

117

Fonksiyonlar

Birden fazla deerin dndrlmesi gerektii durumlarda bu deerler giri parametrelerinde deiiklik yapma yntemiyle ana fonksiyona aktarlabilir. Buna gre, ilevi yle aklanabilir:

factorize

fonksiyonunun

Birinci giri parametresi olarak gnderilen saynn arpanlarn ikinci giri parametresi olan dizide oluturur ve bu dizinin ka eleman olduunu nc giri parametresine yazar. Geriye bir deer dndrmez.

Buna gre koddaki

factorize(number1, factors1, n1);


fonksiyon arsnn ilevi:

number1 saysn asal arpanlarna ayr, sonular factors1 dizisinde olutur ve bu dizideki geerli eleman saysn n1 deikenine yaz.

6.7

Dizilerin Fonksiyonlara Aktarlmas

Bir giri parametresinin dizi tipinden olduunun belirtilmesi iin fonksiyon balnda deiken adnn ardna boyut belirtmeden keli ayralar konur. Dizi deikenlerinin giri parametresi olarak aktarmlarnda en nemli zellik, aksi belirtilmedike dizi elemanlarnn deitirilebilir olmalardr. Yani dizi elemanlar deitirilmek isteniyorsa dizi deikeninin ad olduu gibi yazlr, bavuru aktarm kullanlmaz (deiken adnn bana resi tanm

&

iareti konmaz).

3 Aksine, dizi

elemanlarnn deer deitirmemesi isteniyorsa nlem almak gerekir. Bu amala giri paramet-

const

sakl szcyle balatlr.

rnekte sonularn olutuu

factors1

dizisi ve

n1

deikeninin ana fonksiyonun yerel de-

ikenleri olduuna dikkat edilmelidir. Fonksiyon arsndan nce bu deikenlerde herhangi anlaml bir deer yer almazken ardan dnldkten sonra anlaml deerlerle doldurulmu olmalar beklenmektedir. Bu nedenle, yukarda belirtilen yazm kurallarna gre, fonksiyonunun bal yle olmaldr:

factorize

void factorize(int number, factor_t factors[], int &n)


biimindedir. Bu fonksiyonun tam kts rnek 24'de verilmitir. Ortak arpanlar bulan fonksiyon ise iki tane asal arpan dizisi alacak ve ortak arpanlardan bir asal arpan dizisi oluturacaktr. Dizilerin eleman saylar da parametre olarak gnderilmesi gerektii iin her arpan dizisi, bir eleman dizisi ve bir eleman says ile gsterilecektir. Buna gre

gcd_factors

fonksiyonunun ilevi u ekilde yazlabilir:

Bunun nedeni Blm 7'de aklanacaktr.

Dizilerin Fonksiyonlara Aktarlmas

118

rnek 24
siyonu).

ki saynn en byk ortak blenini bulan program (asal arpanlara ayrma fonk-

void factorize(int x, factor_t factors[], int &n) { int factor = 2; n = 0; while (x > 1) { if (x % factor == 0) { factors[n].base = factor; factors[n].power = 0; while (x % factor == 0) { factors[n].power++; x = x / factor; } n++; } factor = next_prime(factor); }

Birinci parametrede verilen arpanlar ieren ve ikinci parametrede verilen sayda eleman olan arpan dizisiyle, nc parametrede verilen arpanlar ieren ve drdnc parametrede verilen sayda eleman olan arpan dizilerinden ortak arpanlar bulur. Bu dizinin elemanlarn beinci parametrede verilen dizide oluturur ve bu dizinin eleman saysn altnc parametreye yazar. Geriye bir deer dndrmez.

Bu fonksiyonda ilk drt parametre gerek anlamda giri parametresiyken son iki parametre aslnda kt parametresi olup kstlamalar nedeniyle giri parametresi olarak gnderilen deerlerdir Yani ilk drt parametre deimeyecek, son iki parametre deiecektir. Buna gre

gcd_factors

fonksiyonunun bal yle olmaldr:

void gcd_factors(const factor_t factors1[], int n1, const factor_t factors2[], int n2, factor_t factors[], int &n);
Burada

const szcklerinin kullanlmamas programn doru almasna etki etmez, yalnzca

programcnn aslnda deimemesi gereken bir deeri yanllkla deitirmesine engel olmak iin konmutur. Fonksiyonun tanm rnek 25'de verilmitir.

Uygulama: Dizilerin Fonksiyonlara Aktarlmas


Bu uygulamada proler kullanm gsterilecektir (gprof ).

119

Fonksiyonlar

rnek 25
siyonu).

ki saynn en byk ortak blenini bulan program (ortak arpanlar bulma fonk-

void gcd_factors(const factor_t factors1[], int n1, const factor_t factors2[], int n2, factor_t factors[], int &n) { int i1 = 0, i2 = 0; n = 0; while ((i1 < n1) && (i2 < n2)) { // iki dizi de bitmedi if (factors1[i1].base < factors2[i2].base) i1++; else if (factors1[i1].base > factors2[i2].base) i2++; else { factors[n].base = factors1[i1].base; if (factors1[i1].power < factors2[i2].power) factors[n].power = factors1[i1].power; else factors[n].power = factors2[i2].power; i1++; i2++; n++; } }

Dizilerin Fonksiyonlara Aktarlmas

120

rnek 26. Newton-Raphson Yntemiyle Polinom Kk Bulunmas

f (x) fonksiyonunun kk, f (x) = 0 koulunu salayan x deeridir. Bu deere x f (x) fonksiyonunun x civarnda Taylor almnn ilk iki terimi yle yazlabilir
Bir

dersek

f (x) = f (xi ) + (x xi )f (xi )


Bu deer 0 olmas gerektiinden denklem

f (xi ) + (x xi )f (xi ) = 0
ekline getirilebilir ve buradan da

x = xi
yazlabilir. Bu formlde

f (xi ) f (xi )

yerine

xi+1

konursa, fonksiyonun kk ardl yerine koyma yn-

temiyle hesaplanabilir. Yani her admda o admdaki konarak bir sonraki admda kullanlacak Bu yntemin

deeri formldeki

xi

deerinin yerine

deeri hesaplanr. eklinde

p(x) = an xn + an1 xn1 + + a1 x + a0

n.

dereceden bir polinoma

uygulandn varsayalm. O halde yineleme forml

xi+1 = xi

p(xi ) p (xi )

olacaktr. Bir polinomun hesaplanmasnn iie arpma ve toplama yntemiyle nasl hzlandrlaca rnek 15'de grlmt. O rnekteki

bdeerleri

bir dizide tutularak hesaplanrsa:

bn = an bn1 = bn xi + an1 b0 = b1 xi + a0
Bu durumda,

p (x)

polinomu u ekilde yazlabilir (Neden?):

p (x) = bn xn1 + bn1 xn2 + + b2 x + b1


Bu da bir polinom olduundan, hesabnda yine iie arpmlar yntemi kullanlabilir:

cn = bn cn1 = cn xi + bn1 c1 = c2 xi + b1
Bu yntemi kullanarak katsaylarn kullancnn girdii bir polinomun kklerini hesaplayan program rnek 26'de verilmitir.

121

Fonksiyonlar

rnek 26 Polinom kk hesaplayan fonksiyon.


#include <iostream> #include <stdlib.h> #include <math.h>

// cin,cout,endl // EXIT_SUCCESS // fabs

using namespace std; #define MAXDEGREE 50 float newton_raphson(float x, const float a[], int n); int main(void) { float a[MAXDEGREE]; int n, i; float xi, xj, error; cout << "Polinomun derecesi: "; cin >> n; for (i = n; i >= 0; i--) { cout << "a" << i << ": "; cin >> a[i]; } cout << "Hata: "; cin >> error; cout << "x0: "; cin >> xi; while (true) { xj = newton_raphson(xi, a, n); if (fabs(xj - xi) < error) break; xi = xj; } cout << "Kk: " << xj << endl; return EXIT_SUCCESS;

float newton_raphson(float x, const float a[], int n) { float b[MAXDEGREE], c[MAXDEGREE]; float xn; int i; b[n] = a[n]; c[n] = b[n]; for (i = n - 1; i > 0; i--) { b[i] = b[i+1] * x + a[i]; c[i] = c[i+1] * x + b[i]; } b[0] = b[1] * x + a[0]; xn = x - b[0] / c[1]; return xn;

E simli Fonksiyonlar

122

Bu program kullanarak

p(x) = 13x7 9x6 + 12x4 4x3 + 3x + 5


polinomunun kkn ekilde bulun.

x0 = 1

deerinden balayarak,

0.001

hatadan daha kk olacak

6.8

E simli Fonksiyonlar

C++ dilinde giri parametre listeleri farkl olduu srece birden fazla fonksiyonun isimlerinin ayn olmas bir sorun yaratmaz.

4 rnein, iki giri parametresini takas eden fonksiyonlarda

swap_int, iki kesirli sayy takas edecek fonksiyona swap_float, iki katar takas edecek fonksiyona swap_str
isimlerin ayn olmasna izin verilmese iki tamsayy takas edecek fonksiyona gibi isimler vermek gerekir. Oysa giri parametreleri farkl tiplerden olduu iin fonksiyona da

swap

ad verilebilir:

void swap(int &x, int &y) { int tmp; tmp = x; x = y; y = tmp;

void swap(float &x, float &y) { float tmp; tmp = x; x = y; y = tmp;

void swap(char s1[], char s2[]) { char tmp[MAXSIZE]; strcpy(tmp, s1); strcpy(s1, s2); strcpy(s2, tmp);

}
4

C dilinde ayn isimde birden fazla fonksiyon olamaz.

123

Fonksiyonlar

6.9

Varsaylan Parametreler

Fonksiyonlar tanmlanrken istenirse baz giri parametrelerine varsaylan deerler verilebilir. Varsaylan deer giri parametresi listesinde ilgili deikenden sonra atama komutunda olduu gibi yazlr. Bu durumda, aran fonksiyon o parametre iin bir deer gndermezse varsaylan deer kullanlr. rnein bir katar iinde bir simgenin kanc srada olduunu belirten bir fonksiyon yazalm. Normal durumda simge katarn bandan balanarak aranr ve simgeye ilk raslanlan konum belirlenir. Szgelimi Dennis Ritchie katarnda 'e' simgesinin sra numaras 1'dir. Ancak bazen de bir noktadan ileriye doru arama yapmak istenebilir. Ayn rnek zerinde ayn simge 4. konumdan balanarak aranrsa sonu 13 olacaktr. Bu durumda, yazlacak fonksiyonun bal yle olur:

int find_char(char s[], char c, int start);


nc parametrenin ou zaman kullanlmayacandan programclar gerek duymadklar bir parametreyi gndermek zorunda brakmak yerine varsaylan deer kullanmak daha esnek bir zmdr:

int find_char(char s[], char c, int start = 0) { int index = -1, i; for (i = start; s[i] != '\0'; i++) { if (s[i] == c) { index = i; break; } } return index;

}
rnekte

start

parametresine 0 varsaylan deeri verilir. Bylelikle bu deiken, fonksiyon

arlrken belirtilmezse 0 deerini, belirtilirse verilen deeri alr. lk iki parametrenin arda belirtilmesi zorunludur; yani fonksiyon iki ya da parametreyle arlabilir:

find_char(Dennis Ritchie, 'e') find_char(Dennis Ritchie, 'e', 4)


Sorular

// 1 // 13

1. Kendisine parametre olarak gnderilen bir katarda, yine kendisine parametre olarak gnderilen bir simgenin ilk ve son pozisyonlar arasnda ka simge olduunu bularak sonucu dndren bir fonksiyon yazn. Szgelimi, giri katar

Varsaylan Parametreler

124

the world is not enough


ve giri simgesi

'o'

ise, fonksiyon 13 deerini dndrmelidir (rld

is not en).

2. Bir katardaki bir simgenin yerine -o simgenin bulunduu her noktada- baka bir simge geirilmek isteniyor. rnein 2002-04-10 katarnda '-' simgesi yerine '/' simgesi konacaksa 2002/04/10 katar elde edilecektir. (a) Bu ilemi gerekletiren bir fonksiyon yazn. (b) Verilen rnek tarih zerinde bu ilemi gerekletirmek zere (a) kknda yazdnz fonksiyonu kullanan bir ana fonksiyon yazn. 3. ki tamsay dizisindeki ortak elemanlarn says bulunmak isteniyor. rnein birinci dizi 21 10 9 13 15, ikinci dizi 10 7 1 13 15 8 ise ortak elemanlarn says 3'tr (10, 13, 15). rnekten de grlebilecei gibi, dizilerin ayn sayda elemanlar bulunmas zorunlu deildir. Bunun iin: (a) Bir saynn bir dizide bulunup bulunmadn snayan bir fonksiyon yazn. Fonksiyonun giri parametreleri dizi, dizinin boyu ve aranan say olmaldr. Geriye say dizide varsa 1, yoksa 0 deeri dndrlmelidir. (b) Yukarda yazdnz fonksiyonu kullanarak, iki dizideki ortak elemanlarn saysn belirleyen bir fonksiyon yazn. Fonksiyonun giri parametreleri her iki dizinin kendileri ve boylar olmaldr. Fonksiyon geriye ortak elemanlarn saysn dndrmelidir. (c) Yukarda yazdnz fonksiyonlar kullanarak, boyunu ve elemanlarn kullancdan ald iki dizinin ortak eleman saysn bularak ekrana kartan bir ana fonksiyon (main) yazn. 4. Bir dizinin kipi, dizide en ok yinelenen elemandr. Szgelimi

75 32 45 43 75 66 43 88 66 92 66 27
dizisinin kipi 66'dr. Buna gre, bir snavdaki renci notlarnn kipi bulunmak isteniyor. (a) Bir dizinin en byk elemannn dizideki srasn dndren bir fonksiyon yazn. (b) Yukarda yazdnz fonksiyonu kullanarak bir dizinin kipini dndren bir fonksiyon yazn. (Yol gsterme: Elemanlar ilgili notun ka kere getiini gsteren 101 elemanl bir tamsay dizisi kullann. rnein gstersin.) (c) Yukarda yazdnz fonksiyonlar kullanarak, renci saysn ve notlarn kullancdan alarak notlarn kipini bulan ve ekrana kartan bir ana fonksiyon (main) yazn. 5. Polar sistemde dzlemde bir nokta kutuptan olan uzakln belirten yapt ise

counts[55], ka rencinin 55 aldn

deerleriyle belirtilir. Ayn noktann kartezyen x = r cos ve y = r sin eitlikleri geerlidir.

sistemdeki

r ve kutup eksenine koordinatlar x ve y

(a) Noktann polar ve kartezyen koordinatlarn temsil etmek zere birer kayt tanm yazn.

125

Fonksiyonlar

(b) Yukarda yazdnz kayt tanmlarn kullanarak, parametre olarak bir noktann polar koordinatlarn alan ve geriye kartezyen koordinatlarn dndren bir fonksiyon yazn. (c) Kayt yaplar kullanmadan polar koordinatlar kartezyen koordinatlara evirecek bir fonksiyon yazn. (d) (b) ve (c) klarnda yazdnz fonksiyonlarn kullanmlarna birer rnek verin.

Varsaylan Parametreler

126

Blm 7
aretiler

u ana kadar yaplan rneklerde skalar, bileke ya da vektrel tipten olsun, btn deikenlerin bellekte kaplayacaklar alan batan belliydi. Szgelimi, 100 elemanl bir tamsay dizisi tanmlanrsa bu diziye bellekte 100 adet tamsayy tutacak kadar yer ayrlaca derleme aamasnda biliniyordu. Bu tip deikenlere statik deiken ad verilir. Statik bir deikenin saklanaca bellek alan program almaya baladnda ayrlr ve programn sonuna kadar braklmaz. Bu durumun baz sakncalar vardr:

Statik dizilerde grld gibi (bkz. Blm 5), dizinin eleman says derleme aamasnda belli deilse gerekebilecek en byk miktarda yer ayrlmak zorunda kalnr. rnein, deiik snardaki rencilerin notlarn tutmak zere bir tamsay dizisi tanmlanacak olsun. Bu durumda bir snftaki maksimum renci says konusunda bir varsaym yapp (diyelim 100) dizi bu boyutta almaldr. Verilen bu boyut hem programn bir snrlamas olacak, hem de renci says bunun altnda kald zamanlarda gereksiz bellek harcanmasna yol aacaktr.

Programnzda kullanmak istediiniz deikenlerin kaplayaca toplam bellek alan altnz bilgisayarda bulunmayabilir. Dier yandan, bu deikenlerin hepsine birden ayn anda gereksinim duymuyor olabilirsiniz, yani bir deiken iin ayrlan yerin programn btn ileyii boyunca tutulmas gerekli olmayabilir. Szgelimi bir dizi belli bir noktada kullanlmaya balyor ve bir noktadan sonra da kullanlmyor olabilir. Byle bir durumda diziye gerekli olduu zaman yer ayrmak, ii bittikten sonra da ayrlan yeri geri vermek programn toplam bellek gereksinimlerini azaltr.

aretiler, bellekte kaplanacak yerin derleme srasnda deil alma srasnda belirlenmesini

salarlar. Bylelikle gerektii zaman gerektii kadar yer almak ve gerek kalmad zaman da geri vermek olanakl hale gelir. Bir ekilde kullanlan deikenlere dinamik deiken ad verilir. Dinamik deikenlerin zorluu, bellek alanlarnn ynetimi programcya brakldndan programlarn en sk hata yaplan blmleri olmalardr. areti, bir bellek gzne iaret eden bir deikendir. Bunun anlam, iareti deikeninin o bellek gznn adresini tutmasdr. Baka bir deyile, iareti deikeninin deeri, bellek gznn adresidir. Dolaysyla, bir iareti iin iki deerden sz edilebilir: 127

128

kendi deeri: iaret edilen bellek gznn adresi iaret ettii deer: iaret edilen bellek gznn ierii

ekil 7.1a'da iareti deikeniyle iaret edilen bellek gz arasndaki iliki simgesel olarak gsterilmitir. Burada

deikeni, iinde

422

yazan bir bellek gzne iaret etmektedir. e-

kil 7.1b, ayn durumun rnek adres deerleriyle nasl salandn gsterir. zl olduu bellek gznn adresinin

8000

olduu varsaymyla,

tad grlr. Adres deerlerinin (bu rnekteki bir varsaymda bulunamaz.

8000

422

deerinin ya-

deikeninin

8000

deerini

says) ne olduklar programcy ilgi-

lendirmez, bunlar iletim sistemi belirler. Programc adres deerlerinin ne olaca konusunda

p p 422 422 8000 8000 12000

(a)

(b)

ekil 7.1: areti tipinden deikenler. aretinin iaret ettii bellek gznn ieriinin okunmas iin rnekte rnein

deyiminin deeri komutu

8000, *p

deyiminin deeriyse

422'dir.

ileci kullanlr. ekildeki

aretilerle ilem yaparken,

iaretinin kendisiyle mi, yoksa iaret ettii alanla m ilem yapldna dikkat edilmelidir.

p++

neden olur. Oysa

422

iaretisinin bir sonraki (diyelim

deerinin bir artrlmas isteniyorsa

8001) bellek gzne iaret etmesine (*p)++ komutu kullanlmaldr. &


ilecidir. Adres ileci ad verilen

aretilerle ilgili ilemlerde kullanlan dier bir ile de olduundan

bu ile, bir deikenin adresinin renilmesini salar. rnekte

&p

deikeninin adresi 12000

deyiminin deeri 12000'dir. rnekteki deerleri toparlarsak:

&p: p:

12000

8000 422

*p:

areti deikenleri iin iareti deikeninin

NULL

adnda zel bir deer tanmlanr. Bu deerin anlam, o ia-

retinin geerli bir bellek gzne iaret etmiyor olduudur. Dolaysyla, deeri

NULL

olan bir

ileciyle ieriinin okunmaya allmas derleyicinin farkedemeyecei

ama alma annda bellek hatasna yol aacak bir programlama hatasdr.

rnek 27. Dinamik Diziler


Bu blmdeki program, rnek 13'de yazlan istatistik programnn aynsdr. Dolaysyla ekran kts ekil 5.1'de verilenle ayndr. Programn ileyiindeki tek fark, statik diziler yerine di-

129

aretiler

score NULL

ekil 7.2: areti tipinden deiken tanmlama.

namik diziler kullanlmasdr. Bylece snftaki renci says kullancdan renildikten sonra, tam gerektii kadar eleman tutacak bir dizi tanmlanabilmitir.

7.1

areti Tipinden Deikenler

aretiler, deerleri birer adres (bir tr tamsay) olan deikenlerdir, dier deiken tiplerinden bir farklar yoktur. Dolaysyla, dier deikenlerde olduu gibi, iareti tipinden bir deiken tanmlandnda bellekte bir adres tutmaya yetecek kadar yer ayrlr. aretinin kendi deeri her zaman bir adrestir ama iaret ettii bellek gznn nasl yorumlayacann belirtilmesi gerekir. Bu nedenle, iareti tanm u ekilde yazlr:

veri_tipi * deiken_ad ;
Bu tanmn anlam, ad verilen deikenin bir iareti olduu ve gsterdii bellek gznde belirtilen tipten bir deer bulunacadr. Buradaki ierii anlamna gelen

* iareti, iaretinin gsterdii bellek gznn

ileciyle kartrlmamaldr. rnekteki

int *score = NULL;


tanm,

score

deikeninin tamsay barndran bir bellek gzne iareti olduunu belirtir

(ekil 7.2). aretilere balang deeri olarak genellikle

NULL

atanr.

7.2

Bellek Ynetimi

Programda kullanlacak her trl bellek blgesinin kullanlaca i iin ayrlmas gerektii grlmt. Yani iaretinin iaret edecei bellek alannn da ayrlmas gerekir. Ayrlacak bu alan tek bir eleman boyunda olabilecei gibi, birden fazla elemandan oluan bir dizi olarak da kullanlabilir. Dinamik dizi kullanrken iareti tanmnda belirtilen veri tipi dizinin her bir elemannn tipi olarak dnlebilir. Yer ayrma ilemini gerekletiren

new

ileci istenen byklkte, birbirini izleyen gzlerden

oluan bir bellek alann ayrarak balang adresini verir. Yer alma giriimi baarszlkla sonulanrsa, rnein bellekte yer kalmadysa, geriye NULL deerini dndrr. Yazm u ekildedir:

new veri_tipi [eleman_says ]

Bellek Ynetimi

130

rnek 27 rnek 13'in dinamik dizilerle gereklenmesi.


#include <iostream> #include <stdlib.h> #include <math.h>

// cin,cout,endl // EXIT_SUCCESS // fabs,sqrt

using namespace std; int main(void) { int *score = NULL; int no_students = 0; float mean, variance, std_dev, abs_dev; float total = 0.0, sqr_total = 0.0, abs_total = 0.0; int i = 0; cout << "Ka renci var? "; cin >> no_students; score = new int[no_students]; for (i = 0; i < no_students; i++) { cout << i + 1 << ". rencinin notu: "; cin >> score[i]; total = total + score[i]; } mean = total / no_students; for (i = 0; i < no_students; i++) { sqr_total = sqr_total + (score[i] - mean) * (score[i] - mean); abs_total = abs_total + fabs(score[i] - mean); } variance = sqr_total / (no_students - 1); std_dev = sqrt(variance); abs_dev = abs_total / no_students; cout << "Ortalama: " << mean << endl; cout << "Varyans: " << variance << endl; cout << "Standart sapma: " << std_dev << endl; cout << "Mutlak sapma: " << abs_dev << endl; delete score; return EXIT_SUCCESS;

131

aretiler

score 6500

no_students*sizeof(int)

6500

ekil 7.3: Yer ayrlmasndan sonraki durum.

rnekte renci notlarn tutacak dizi iin

score = new int[no_students];


komutuyla yer alnmtr. Bu komut sonucunda bellekte lk bir alan ayrlr ve bu alann balang adresi

score

no_students * sizeof(int)

kadar-

iaretisine atanr (ekil 7.3).

Tek bir elemanlk blge ayrlacaksa eleman saysnn belirtilmesine gerek yoktur. rnein, ekil 7.1'de izilen durum u komutlarla yaratlabilir:

int *p = NULL; p = new int; *p = 422; // 8000 olduu varsaylyor

Ayrlan yerin geri verilmesi

delete ileciyle gereklenir. Bu ile, bir iareti iin alnan btn

blgeyi geri verir; blgenin bir ksmn geri vermek gibi bir seenek yoktur. Bu nedenle, ilece yalnzca iaretinin adn vermek yeterlidir, geri verilecek eleman says yeniden belirtilmez. Yukarda yazlan her iki (birden fazla eleman ya da bir eleman) yer ayrma ileminin de geri vermesi benzer ekildedir:

delete score; delete p;


areti tipinden deikenler iin her zaman yer ayrlmas zorunluluu yoktur. Zorunlu olan DKKAT nokta, iaretilerin her zaman geerli bellek gzlerine iaret etmeleridir. Bu bellek gzleri rneklerde olduu gibi dinamik olarak ayrlm olabilecekleri gibi, baka bir iareti deikeni tarafndan ayrlm ve hatta statik olarak tanmlanm bile olabilirler. rnein ekil 7.1'de izilen durum u komutlarla da yaratlabilirdi:

int x = 422; int *p = &x;


Bu durumda 422 deerini tutan bellek gzne programn banda statik olarak yer ayrlr; iaretisi ise bu bellek gznn adresini tar. nemli olan durulmasdr. rnekte

ile

*p

deikenlerinin ayn bellek

gznde bulunduklarnn ve birinin deimesiyle brnn de deieceinin gznnde bulun-

deikeni iin yer ayrlmadndan burann

delete

ile geri verilmesi

de szkonusu deildir; byle bir deneme hataya neden olacaktr.

areti - Dizi likisi

132

Bellek ynetimi iin

ilemleri yapmak iin

new ve delete ileleri C++ dilinde getirilmi yeniliklerdir. C dilinde ayn malloc ve free fonksiyonlarn kullanmak gerekir. Buna gre rnekteki

programn ilgili satrlar u ekilde deitirilebilir

score = (int *) malloc(no_students * sizeof(int)); ... free(score); malloc


fonksiyonu

new

ileciyle ayn ekilde yer ayrr. Aralarndaki yazm farklar u ekilde

aklanabilir:

1.

new

ilecinde eleman tipi ve says belirtilir,

malloc

fonksiyonunda ise ayrlacak alann

boyunu sekizli cinsinden vermek gerekir. 2.

malloc

fonksiyonu geriye

void *

tipinden bir deer dndrr (ham iareti). Bu deer

deikene atanrken uygun ekilde tip dnm yaplmas gerekir. 3.

malloc ve free birer fonksiyon olduklarndan parametrelerinin ayralar iinde yazlmas gerekir. Ayn nedenle, kullanlabilmeleri iin bir balk dosyasnn (stdlib.h) alnmas
gerekir.

7.3

areti - Dizi likisi

Statik diziler ile dinamik diziler arasndaki tek fark oluturulmalarndadr, elemanlara eriim her ikisinde de ayndr. Yani u iki tanm arasnda, bellekte oluan durum asndan bir fark yoktur:

int p[10]; ... for (i = 0; i < 10; i++) ...p[i]... ...

int *p; p = new int[10]; ... for (i = 0; i < 10; i++) ...p[i]... ... delete p;

Statik dizilerle dinamik dizilerin ayn ekilde kullanlabilmeleri iki zellie dayanr:

1. Statik bir dizinin ad, dizinin ilk elemanna bir iaretidir. 2. aretinin deeri bir sayyla toplanrsa, iaretinin gsterdii adresten iaret edilen tipten o say kadar ilerlenerek gelinen bellek gznn adresi elde edilir. Benzer ekilde, kartma ileminde bu miktar kadar geriye gidilir.

Bu zellikler nedeniyle, iaretinin tipi ne olursa olsun, aadaki deyimler edeerlidir:

p[0] p[1] p[n]

*p *(p + 1) *(p + n)

133

aretiler

Katarlar da birer dizi olduklarndan katarlar arasndaki atama ve karlatrma gibi ilemlerin neden beklendii gibi almayacaklarna tekrar dnelim. ekil 7.4'deki yapda

str2

deikenleri karlatrlrsa (str1

== str2),

str1

ile

karlatrma sonucu yanl deeri retilir

(3200=9450).

str1 3200 "Dennis Ritchie" 3200 str2 9450 "Dennis Ritchie" 9450

ekil 7.4: Katarlarn karlatrlmas. Benzer ekilde, ayn rnekte masn salamad gibi

str1 = str2

atamas

str1

iaretisinin

str2

iaretisiyle ayn

deeri almas sonucunu dourur (ekil 7.5). Bu durum ayn katarn iki farkl kopyasnn olu-

str1

katarnn nceki iaret ettii bellek blgesinin (Dennis Ritchie

deerinin bulunduu blge) de yitirilmesine yol aar.

rnek 28. Morse Kodlamas


Kullancdan ald bir szc Morse abecesinde kodlayan bir program yazlmas isteniyor. Programn rnek bir almasnn ekran kts ekil 7.6'da verilmitir.

7.4

areti Tipinden Parametreler

Dizilerin fonksiyonlara parametre olarak aktarlmalarnda statik ya da dinamik gsterilimler arasnda bir fark yoktur. Szgelimi, rnek 24'de yazlan asal arpanlarna ayrma fonksiyonunun bildirimi iin u ikisi edeerlidir:

void factorize(int number, factor_t factors[], int &n); void factorize(int number, factor_t *factors, int &n);
str1 9450 "Dennis Ritchie" 3200 str2 9450 "Ken Thompson" 9450 (b)

ekil 7.5: Katarlarn atanmas.

areti Tipinden Parametreler

134

rnek 28 Morse kodlamas yapan program.


#include #include #include #include <iostream> <stdlib.h> <stdio.h> <string.h> // // // //

cin,cout,endl EXIT_SUCCESS gets strcat

using namespace std; #define MAXLENGTH 80 char *encode(const char *s); int main(void) { char word[MAXLENGTH]; char *morse = NULL; cout << "Szc yaznz: "; cin >> word; morse = encode(word); cout << "Morse karl: " << morse << endl; delete morse; return EXIT_SUCCESS;

char *encode(const char *s) { static char encoding[][5] = { ".-", "-...", "-.-.", "-..", "....", "..", ".---", "-.-", "---", ".--.", "--.-", ".-.", "...-", ".--", "-..-", "-.--", char *morse = new char[MAXLENGTH]; int i;

".", "..-.", "--.", ".-..", "--", "-.", "...", "-", "..-", "--.." };

morse[0] = '\0'; for (i = 0; s[i] != '\0'; i++) { strcat(morse, encoding[s[i] - 'a']); strcat(morse, " "); } return morse;

135

aretiler

Szc yaznz: istanbul Morse karl: .. ... - .- -. -... ..- .-..

ekil 7.6: rnek 28 ekran kts.

Fonksiyonun balk satrnda bu iki gsterilimden herhangi biri kullanlabilir, fonksiyonun gvdesinde bir deiiklik yapmak gerekmez. aretiler, dizilerin kt parametresi olarak dndrlememesi kstlamasn da zerler. Statik bir dizi bir btn halinde (btn elemanlarnn kopyas oluturularak) kt parametresi olarak dndrlemez ancak dizinin bana bir iareti dndrlebilir. rnekte bu zellik kullanlarak

encode

fonksiyonu

char *encode(const char *s);


eklinde bildirilmitir. Bunun anlam, bu fonksiyonun deitirilmeyecek bir katar ald ve rettii katar geri dndrddr. Fonksiyonun gvdesinde tanmlanan m szc tutar ve fonksiyon sonunda Burada nemli olan bir nokta,

return

morse deikeni, kodlan-

ile geri dndrlr.

encode fonksiyonunun, geri verme iiniyse main fonksiyonunun yapmasdr. Geri verme ilemi yine encode fonksiyonunca yaplamaz nk katarn ii henz sona ermemitir. Benzer ekilde morse deikeni encode fonksiyonunda statik olarak da (char morse[MAXLENGTH] eklinde) tanmlanamaz nk byle
katar iin yer ayrma iini tanmlandnda bu bir yerel deiken olacandan fonksiyonun sona ermesiyle onun iin ayrlm olan bellek geri verilir ve sonu ana fonksiyona aktarlamaz.

morse

7.5

Statik Deikenler

rnekte

encode

fonksiyonunda tanmlanan

encoding

dizisi bu fonksiyonun bir yerel deike-

nidir, yani fonksiyonun her yaratlnda bu dizi yeniden yaratlr, elemanlarna deerler verilir ve fonksiyonun sona ermesiyle yok edilir. Bu ilemin her defasnda tekrar tekrar yaplmas istenmiyorsa,

encoding

deikeni genel bir deiken olarak tanmlanabilir:

char encoding[][5] = { ... }; int main(void) { ... } char *encode(char *word) { ... }

Adres Aktarm

136

Genel deiken tanmlamak sz edilen sakncay giderir ama yere

encoding deikeninin gereksiz main fonksiyonundan da eriilebilir hale gelmesine yol aar. Daha dzgn bir zm, encoding deikenini encode fonksiyonunun iinde statik olarak tanmlanamaktr: static char encoding[][5] = { ... };
Byle yapldnda

encoding dizisi genel bir deiken gibi srekli yaar ama encode fonksiyonu

dnda kullanlamaz.

7.6

Adres Aktarm

Bavuru aktarm yntemi C++ dilinde gelmi olduundan C dilinde bunun yerine adres aktarm yntemi kullanlr, yani arlan fonksiyona deikenin adresi yollanr. arlan fonksiyon bu adresi iareti tipinden bir deikene alr ve bu iaretinin gsterdii yerde deiiklii yapar. Bylece deiiklik aran fonksiyondaki deikeni dorudan etkiler. Buna gre, rnek 20'da anlatlan ve dzeltilen

swap

fonksiyonu yntemi rnek 29'de olduu gibi de gereklenebilirdi:

rnek 29 ki sayy adres aktarmyla takas eden fonksiyon ve kullanm.


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; void swap(int *x, int *y) { int tmp; tmp = *x; *x = *y; *y = tmp;

int main(void) { int m = 32, n = 154; cout << m << " " << n << endl; swap(&m, &n); cout << m << " " << n << endl; return EXIT_SUCCESS;

Bu rnekte

deikeni tamsayya iareti (yani adres) tipinden bir deiken olurdu ve deeri

deikeninin adresi olurdu. Yani

iaretisinin gsterdii yere yazlan deer

deikenine

yazlm olurdu (ekil 7.7).

137

aretiler

x swap 2000

y 2004

tmp xxx

m main 32 2000

n 154 2004 (a)

x swap 2000

y 2004

tmp xxx

m main 154 2000

n 32 2004 (b)

ekil 7.7: Takas fonksiyonunda parametre aktarm.

Gnmzde neredeyse btn C gelitirme ortamlarnda C++ yetenekleri bulunduundan, giri parametrelerinde deiiklik yapmak istendiinde adres aktarm yntemini kullanmann artk bir gerei yoktur. Adres aktarm programc hatalarna daha elverili olduundan ancak derleyiciniz C++ desteklemiyorsa ya da probleminiz asndan daha uygunsa kullanmanz nerilir.

Uygulama: aretiler
rnek 30. Seerek Sralama
Kullancdan ald say kadar rencisi olan bir snfta kullancnn girdii renci notlarnn ortadeerini bulan bir program yazlmas isteniyor. Bir dizinin ortadeeri, dizi sralandnda dizinin ortasnda yer alan deerdir. ift sayda eleman olan dizilerde dizinin ortasnda bir eleman olmadndan ortadaki iki elemann aritmetik ortalamas ortadeer kabul edilir. Dizinin ortadeerini bulmak iin ncelikle diziyi sralamak gerekir. rnekte kullanlan seerek sralama yntemi, en basit sralama algoritmalarndan biridir. Bu yntemde, kkten bye doru sralama yaplaca varsaymyla, bu algoritmann her admnda dizinin en byk eleman bulunur ve sondaki elemanla yeri karlkl deitirilir. Bylece en byk eleman en sona alnr ve dizinin boyu bir azaltlarak ileme devam edilir. geen ilem

elemanl bir dizide sz

n1

kere yinelenecektir. rnek bir dizi zerinde seerek sralama algoritmasnn

almas ekil 7.8'de verilmitir.

Sralama ilemini kabarck sralama algoritmas kullanacak ekilde dzenleyin.

Adres Aktarm

138

rnek 30 renci notlarnn ortadeerini bulan program.


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; void selsort(int *numbers, int count); int main(void) { int *score = NULL; float median; int no_students, i; cout << "renci says: "; cin >> no_students; score = new int[no_students]; for (i = 0; i < no_students; i++) { cout << i + 1 << ". rencinin notu: "; cin >> score[i]; } selsort(score, no_students); median = (no_students % 2 == 1) ? score[no_students/2] : (score[no_students/2] + score[no_students/2-1]) / 2.0; cout << "Orta deer: " << median << endl; delete score; return EXIT_SUCCESS;

void selsort(int *numbers, int count) { int round, max, i; int tmp; for (round = 0; round < count - 1; round++) { max = 0; for (i = 1; i < count - round; i++) { if (numbers[max] < numbers[i]) max = i; } tmp = numbers[max]; numbers[max] = numbers[count - 1 - round]; numbers[count - 1 - round] = tmp; }

139

aretiler

4 4 3 1 1

5 2 2 2 2

1 1 1 3 3

3 3 4 4 4

2 5 5 5 5

ekil 7.8: Seerek sralama rnei.

Adres Aktarm

140

Sorular
1. Sezar ifrelemesi ynteminde ifrelenecek szckteki her harn yerine (ngilizce) abecede kendisinden 3 sonra gelen harf konur (A yerine D, B yerine E, ..., V yerine Y, W yerine Z, X yerine A, Y yerine B, Z yerine C). Buna gre HUNGRY szcnn karl KXQJUB olur. (a) Bildirimi aada verildii ekliyle bir szck alan ve bunun ifrelenmesi sonucu oluan yeni katar dndren bir fonksiyon yazn:

char *caesar(const char s[]);


(b) Kullancdan ald bir szc yukardaki fonksiyon yardmyla ifreleyen ve sonucu ekrana yazan bir ana fonksiyon yazn. (c) (a) kknda yazdnz fonksiyonu teleme miktar da bir parametre olacak ekilde genelletirin ve (b) kknda yazdnz fonksiyonu da uygun biimde dzenleyin. 2. ngilizce'de 'q' harnden sonra ou zaman 'u' har gelir. Buna gre kendisine parametre olarak gnderilen katarda 'q' harnden sonra 'u' har geliyorsa 'u' harni silen bir fonksiyon yazn. Szgelimi, fonksiyona you must be quick katar parametre olarak gelirse bu fonksiyon katar you must be qick diye deitirmelidir (yeni bir katar retmiyor, geriye bir deer dndrmyor). Bu fonksiyonu denemek zere bir ana fonksiyon yazn.

Blm 8
Giri-k

Bu blmde ncelikle giri-k kitaplndaki fonksiyonlar kullanarak giri-k ilemlerinin nasl yapld gsterilecektir. Daha sonra dosyalar zerinde okuma-yazma ilemlerinin nasl yapld anlatlacaktr.

8.1

k

C dilinde

cout

birimi yoktur. Bunun yerine

printf

fonksiyonu kullanlr. Bu fonksiyonun

yaps u ekildedir:

printf(biim katar, deyim1, deyim2, deyim3, ...);


Biim katarnn temel ilevi yazdrlmas istenen iletileri belirtmektir. Szgelimi:

cout < < Merhaba dnya! < < endl;


komutunun C'deki karl yledir:

printf(Merhaba dnya!\n);
Bu rnekte ekrana herhangi bir deiken ya da deyim deeri yazdrlmamakta, yalnzca bir ileti grntlenmektedir. Katarn sonundaki salar (C++'daki

endl

'\n' simgesi katar sona erdiinde alt satra geilmesini

karl).

Bir deyim deerinin ekranda gsterilmesi isteniyorsa bu deerin tipi de biim katarnda belirtilmelidir. Her veri tipinin kendine zg bir belirteci vardr. (bkz. Tablo 8.1). Buna gre rnek 1'de geen

cout < < Alan:  < < area < < endl;
komutunun karl u ekilde olur: 141

k

142

Veri Tipi Onlu dzende tamsay Onlu dzende uzun tamsay Onaltl dzende tamsay Noktal gsterilimde kesirli say Bilimsel gsterilimde kesirli say Simge Katar

Belirte

%d %ld %x %f %e %c %s

Tablo 8.1: Biim belirteleri.

printf(Alan: %f\n, area);


ktnn nasl oluturulacan biim katar belirler. Belirteler dnda kalan blmler olduu gibi ka aktarlr; bir belirte ile karlaldnda deyim listesinde sradaki deyim hesaplanarak elde edilen deer ka aktarlr. Dolaysyla, biim katarnda geen belirteler ile deyim listesindeki deyimlerin say ve tiplerinin birbirini tutmas gerekir.

rnek. radius

deikeninin kesirli say tipinden olduu ve kullancnn giri srasnda

2.4

deerini yazd varsaymyla

printf(Yarap %f olan dairenin alan: %f\n, radius, 3.14 * radius * radius);


fonksiyonunun ileyii u ekilde olur:

Biim katarnda ilk

nceki boluk dahil):

% iaretine kadar grlen her simge ekrana kartlr (belirteten Yarap  2.4  olan dairenin

Biim katarndan sonraki ilk deyimin deeri kesirli say biiminde ekrana kartlr (nce ve sonraki boluklar hari):

Bir sonraki belirtece kadar grlen her simge ekrana kartlr:

alan: 
tlr:

Biim katarndan sonraki ikinci deyimin deeri kesirli say biiminde ekrana kar-

18.07

\n

simgesi nedeniyle sonraki satra geilir.

Yzde ve ters bl iaretleri biim katarnda zel anlam tadklarndan bunlarn ka gndekarmak iinse '\\' simgeleri kullanlmaldr. rilmesi istendiinde zel bir yazm gerekir. Yzde iaretini karmak iin '%%', ters bl iaretini

Biim katar deiken deerlerinin ka gnderilmesinde ayrntl denetim olana da salar. rnein say deerlerinin belli bir uzunlukta olmas salanabilir. %5d eklinde belirtilen bir tamsay deeri be haneliyse boluksuz, drt haneliyse bir boluk ve say, haneliyse iki boluk ve say v.b. eklinde deerlendirilerek ka gnderilir. Bu yntem dzgn ekilde altalta gelmi ktlar oluturmak iin yararldr. Kesirli saylarda da noktadan nce ve sonra

143

Giri-k

ka hane bulunduu belirtilebilir. Szgelimi %20.12f  belirteci saynn toplam 20 hane (nokta dahil) yer tutacan ve bunun 12 hanesinin noktadan sonra olacan gsterir. DZELT: daha fazla ayrnt

8.2

Giri

k biriminde olduu gibi, C dilinde giri iin kullanlabilecek yerine

scanf

cin

birimi de yoktur. Bunun

fonksiyonu kullanlr. Bu fonksiyonun yaps u ekildedir:

scanf(biim katar, &deiken1, &deiken2, &deiken3, ...);


Biim katar,

printf

fonksiyonundakine benzer bir ilev grr ve okunacak deerlerin tipinin

ne olacan belirler. Kullanlan veri tipi belirteleri de ayndr. Giri yaplrken kullancnn yazd deerin alnaca deiken

scanf

fonksiyonunda deer

deitireceinden fonksiyona bu deikenin adresi gnderilir (bkz. Blm 7.6). Bu nedenle,

scanf fonksiyonuna gnderilen deikenlerin adlarnn bana adres ileci olan & simgesi konur.
rnein

cin > > radius;


komutunun C dilindeki karl u ekildedir:

scanf(%d, &radius);
Katar tipinden olan deikenlerde katarlar bir dizi olduklarndan ve adlar zaten dizinin ilk elemanna bir iareti olduundan katar tipinden bir

word

& simgesi kullanlmaz. Szgelimi, kullancnn yazd szc

deikenine almak iin aadaki komut kullanlr:

scanf(%s, word);
rnek 31. statistik Hesaplar
Bu rnekte, rnek 13'de yaplan renci notlar zerindeki istatistik hesaplar dosyalar yardmyla gereklenecektir. renci notlar bir dosyadan okunacak, ilem sonular da yine bir dosyaya yazlacaktr. Notlarn hangi dosyadan okunaca ve sonularn hangi dosyaya yazlaca program altrlrken komut satrndan belirtilecek, bylelikle program almas srasnda kullancya hibir ey sormayacak, rettii hibir sonucu da ekranda gstermeyecektir. Bu programn yazl olduu dosya dosyann ad

stat3

stat3.cpp ve derleme ile balama sonucu oluan altrlabilir

olursa program

stat3 notlar.txt sonuclar.txt


gibi bir komutla arlmaldr. Burada ilk belirtilen isim (rnekte dosyay, ikinci isim (rnekte iletisi grntler.

sonuclar.txt) sonularn yazlaca dosyay gsterir ve herhangi

notlar.txt)

okunacak

birinin eksik olmas durumunda program nasl altrlmas gerektiine ilikin bir kullanm

Giri

144

rnek 31 Dosyalar ile giri/k ilemleri yaparak renci notlar zerinde istatistik hesaplar
yapan program (okuma blm).

#include #include #include #include

<iostream> <stdio.h> <stdlib.h> <math.h>

// // // //

cin,cout,cerr,endl fopen,fclose,fprintf,fscanf,feof exit,EXIT_SUCCESS,EXIT_FAILURE fabs,sqrt

using namespace std; #define MAXSTUDENTS 100 int main(int argc, char *argv[]) { int score[MAXSTUDENTS]; int no_students = 0; float mean, variance, std_dev, abs_dev; float total = 0.0, sqr_total = 0.0, abs_total = 0.0; int i = 0; FILE *infile, *outfile; if (argc != 3) { cout << "Kullanm: " << argv[0] << " giri_dosyas k_dosyas" << endl; return EXIT_FAILURE; } infile = fopen(argv[1], "r"); if (infile == NULL) { cerr << "Giri dosyas alamad." << endl; exit(EXIT_FAILURE); } no_students = 0; while (true) { fscanf(infile, "%d", &score[no_students]); if (feof(infile)) break; total = total + score[no_students]; no_students++; } fclose(infile); ... } return EXIT_SUCCESS;

145

Giri-k

rnek 32 Dosyalar ile giri/k ilemleri yaparak renci notlar zerinde istatistik hesaplar
yapan program (yazma blm).

#include #include #include #include

<iostream> <stdio.h> <stdlib.h> <math.h>

// // // //

cin,cout,cerr,endl fopen,fclose,fprintf,fscanf,feof exit,EXIT_SUCCESS,EXIT_FAILURE fabs,sqrt

using namespace std; #define MAXSTUDENTS 100 int main(int argc, char *argv[]) { int score[MAXSTUDENTS]; int no_students = 0; float mean, variance, std_dev, abs_dev; float total = 0.0, sqr_total = 0.0, abs_total = 0.0; int i = 0; FILE *infile, *outfile; ... mean = total / no_students; for (i = 0; i < no_students; i++) { sqr_total = sqr_total + (score[i] - mean) * (score[i] - mean); abs_total = abs_total + fabs(score[i] - mean); } variance = sqr_total / (no_students - 1); std_dev = sqrt(variance); abs_dev = abs_total / no_students; outfile = fopen(argv[2], "w"); if (outfile == NULL) { cerr << "k dosyas alamad." << endl; exit(EXIT_FAILURE); } fprintf(outfile, fprintf(outfile, fprintf(outfile, fprintf(outfile, fprintf(outfile, fclose(outfile); } return EXIT_SUCCESS; "renci says: %d\n", no_students); "Ortalama: %f\n", mean); "Varyans: %f\n", variance); "Standart sapma: %f\n", std_dev); "Mutlak sapma: %f\n", abs_dev);

Ana Fonksiyona Parametre Aktarma

146

8.3

Ana Fonksiyona Parametre Aktarma

Ana fonksiyon da dier fonksiyonlar gibi bir fonksiyon olmakla birlikte giri ve k parametrelerinin aktarm bakmndan farkllk gsterir. Bir fonksiyonun giri parametreleri almas ve k parametresi dndrmesi, o fonksiyonun arlabilmesi anlamna gelir. Oysa ana fonksiyon almann balad fonksiyon olduundan dier fonksiyonlarca arlmaz. Ana fonksiyonu aran iletim sistemidir, yani ana fonksiyonun arlmas programn iletim sistemince yrtlmeye balanmasna kar der. Bu durumda ana fonksiyon giri parametrelerini iletim sisteminden alr, k parametresini de iletim sistemine dndrr. Ana fonksiyonun k parametresinin nasl belirtildii u ana kadarki btn rneklerde grlmt. Bu parametre programn almas sonucu oluan durumun iletim sistemine bildirilmesi anlamn tar ve baar durumunda

return EXIT_SUCCESS;
baarszlk durumunda

return EXIT_FAILURE;
komutlaryla belirtilir. Ana fonksiyonun giri parametreleriyse kullancnn program altrrken belirttii parametrelerdir. Giri parametrelerinin okunabilmesi iin ana fonksiyonun giri parametresi listesi

int argc, char *argv[]


eklinde verilir. Burada

argc

parametre saysn,

argv

ise parametre dizisini gsterir. Para-

metre dizisinin her bir eleman, balktan da grlebilecei gibi, bir katardr. Programn ad da parametreler arasnda sayldndan parametre says en az 1 olabilir. Yani

argc

deikeni program yalnzca

stat3

komutuyla arlrsa 1, yukarda verilen ekilde a-

rlrsa 3 deerini alr. Parametre deerleri de rnek zerinden gidersek:

argv

dizisinin elemanlarn olutururlar. Yine

argv[0] = stat3 argv[1] = notlar.txt argv[2] = sonuclar.txt


rnekteki

if (argc != 3)
komutu programn doru sayda parametreyle altrlp altrlmadn snamak iin konmutur. Parametre saysnn hatal olduu durumda programn ekrana bir kullanm iletisi basp sonlanmasn salar. Btn giri parametrelerinin birer katar olduuna dikkat edilmelidir. Komut satrndan verilen deerlerin say olarak kullanlabilmesi iin uygun kitaplk fonksiyonlaryla (tamsaylar iin

atoi,

kesirli saylar iin

atof)

sayya evrilmeleri gerekir.

147

Giri-k

8.4

Dosyalar

Dosyalar zerinde ilem yapmak iin ncelikle dosyay programda temsil edecek bir deiken tanmlanmaldr. C dilinde bu deiken dosya iaretisi olarak adlandrlr ve tanmlanr. rnekte biri giri dosyasn (infile) dieri de k dosyasn (outfile) temsil etmek zere iki dosya iaretisi tanmlanmtr. Dosya iaretisi sradaki okuma ya da yazma ileminin dosya zerinde hangi noktada yaplacan belirler ve yaplan her ilemle ileri ya da geri doru hareket eder.

FILE * tipinden

8.4.1

Dosya Ama - Kapama

Bir dosya zerinde ilem yapmadan nce ilk yaplmas gereken dosyann almasdr. Ama ilemi bildirimi aada verilmi olan

fopen

fonksiyonu yardmyla yaplr:

FILE *fopen(const char *path, const char *mode );


Fonksiyon balnda grlen

path

parametresi, alacak dosyann sistemdeki tam adnn be-

lirtilmesini salar. kinci parametre olan

mode ise dosya zerinde ne ilem yaplmas istendiini

belirtmeye yarar. Bu parametre iin verilebilecek rnek deerler yledir:

 r :  w :

dosya yalnzca okunacak (dosya varsa sfrlanmaz, yoksa yaratlmaz) dosyaya yalnzca yazlacak (dosya varsa sfrlanr, yoksa yaratlr) dosyada hem okuma hem yazma yaplacak (dosya varsa sfrlanmaz, yoksa yaratl-

 r+ :
maz)

 w+ :  a :

dosyada hem okuma hem yazma yaplacak (dosya sfrlanr, yoksa yaratlr)

dosyann sonuna ekleme yaplacak (dosya varsa sfrlanmaz, yoksa yaratlr)

Fonksiyon balndan da grlebilecei gibi bu fonksiyon geriye at dosya iin bir iareti dndrr, dosya zerinde sonraki ilemlerde bu iareti kullanlacaktr. Ekleme kipinde ama dndaki kiplerde dosya ama ilemi dosya iaretisini dosyann bana konumlandrr; yani ilk okuma ya da yazma dosyann bandan yaplr. Dosya zerindeki ilemler bittikten sonra da dosyann kapatlmas gerekir. Bu amala bildirimi aada verilmi olan

fclose

fonksiyonu kullanlr:

int fclose(FILE *stream );


Bu fonksiyon parametre olarak verilen dosya iaretisinin gsterdii dosyay kapatr. Baarl olursa 0, baarsz olursa

EOF

deerini dndrr.

Standart Giri / k Birimleri

148

8.4.2

Dosyada Okuma-Yazma

Her okuma ya da yazma ilemi iaretiyi okunulan ya da yazlan miktar kadar ilerletir; bylelikle pepee okuma ilemleri dosyann srayla okunmasn salar (yazma iin de benzer ekilde). Okuma-yazma ilemleri iin yonlarn kullanmlar

scanf

ve

fscanf ve fprintf fonksiyonlar kullanlabilir. Bu fonksiprintf fonksiyonlar ile ayndr; tek farklar ek olarak en baa

bir dosya iaretisi parametresi almalardr. Dosyadan baka birimlerde okuma yapmak da istenebilir. rnein bir satrn btn halinde okunmas amacyla

gets fonksiyonuna benzer fgets fonksiyonu kullanlabilir. Bu fonksiyonun

bildirimi u ekildedir:

char *fgets(char *s, int size, FILE *stream );


Bu fonksiyon duklarn

fazla okumaz. Baarsz olursa

gets

s parametresi ile belirtilen katara yazar. Satr sonu ya da dosya sonuna raslarsa daha NULL, baarl olursa s deerini dndrr. Gvenlik asndan fgetc fonksiyonu kullanlabilir. Bu fonksiyonun bildirimi

stream parametresi ile belirtilen dosyadan en fazla size - 1 simge okur ve oku-

fonksiyonu yerine bu fonksiyonun kullanlmas nerilir.

Dosyadan tek bir simge okumak iin u ekildedir:

int fgetc(FILE *stream );


Bu fonksiyon

stream parametresi ile belirlenen dosyadan okuduu sradaki simgeyi bir tamsay feof
fonksiyonundan yararlanlr. Bu

olarak geri dndrr. Dosya sonuna gelinip gelinmediini renmek amacyla

fonksiyon kendisine parametre olarak gnderilen dosya iaretisinin ilgili dosyann sonu olup olmadn snar ve sona gelindiyse doru deerini dndrr.

8.5

Standart Giri / k Birimleri

Standart giri, k ve hata birimleri de birer dosya gibi davranrlar. Standart giri birimi

stdin adnda nceden tanmlanm zel bir deikende tutulur. Benzer ekilde standart k iin stdout, standart hata iin de stderr deikenleri tanmlanmtr. Basit bir rnek verecek
olursak

printf(biim katar, deyimler);


komutu

fprintf(stdout, biim katar, deyimler);


komutuyla ayn anlama gelir. Benzer ekilde aadaki ikisi de giri ilemleri iin edeerlidir:

scanf(biim katar, deikenler); fscanf(stdin, biim katar, deikenler);

149

Giri-k

8.6

Hata letileri

Hata iletilerinin standart k iletilerinden ayrlmasnn yararl bir alkanlk olduu Blm 1.5'de sylenmiti. Bir C++ programnda bu ilem iletinin tilerde bu ilem grlebilir:

cout

deil,

cerr

birimine

ynlendirilmesiyle salanabilir. rnekte dosyalarn alamamas durumunda grntlenen ile-

cerr < < Giri dosyas alamad. < < endl;


C dilinde ise

cerr

birimi olmadndan ayn ilem aadaki komutla gerekletirilmelidir:

fprintf(stderr, .Giri dosyas alamad.\n);


Hata olutuunda programn ne yapaca durumdan duruma deiebilir. Dzeltilemeyecek bir hata olutuysa programlar

exit

fonksiyonuyla sonlandrlrlar. Bu fonksiyona

EXIT_FAILURE

deeri gnderilirse programn baarsz sonland iletim sistemine bildirilmi olur. Bu ilemin

return

ile dnmeden fark hangi fonksiyondan arlrsa arlsn programn derhal sonlan-

masdr; return ise yalnzca aran fonksiyona dn salar. Hata iletilerini standartlatrmak amacyla

perror

fonksiyonu tanmlanmtr. Bu fonksiyon

son oluan hataya gre uygun bir mesaj standart hata birimine gnderir. Kullanmnda gelenek olarak hatann hangi fonksiyonda ortaya kt belirtilir. rnekte giri dosyas alamadnda

cerr

birimine ynlendirme yerine

perror(main: giri dosyas alamad);


komutu kullanlsayd ve programn altrlmas srasnda belirtilen giri dosyas sistemde bulunamasayd alma annda yle bir ileti grnrd:

main: giri dosyas alamad: No such file or directory


8.7 Katarlar ile Giri-k

Standart giri-k kitaplndaki

ile yaplmasn salar. Bu fonksiyonlarn

sprintf ve sscanf fonksiyonlar ayn ilemlerin katarlar printf ve scanf fonksiyonlarndan farklar, ilk pa-

rametrelerinin okuma ya da yazma yaplacak katarlar belirtmeleridir. rnein dosyadan bir satr btn olarak okuyup, zerinde belki baz denetlemeler yaptktan sonra deerlerin deikenlere aktarlmas isteniyorsa teknik kullanlabilir:

fscanf ile dorudan deikenlere aktarmak yerine aadaki

// fp dosyasndan bir satr line katarna oku // ilk deeri x tamsay deikenine, // ikinci deeri y kesirli deikenine aktar fgets(line, fp); ... sscanf(line, %d %f, &x, &y);

kili Dosyalar

150

sprintf fonksiyonu da ktnn ekrana baslmadan bir katarda oluturulmas ileminde yararl olur. Szgelimi, x saysn strx katarna evirmek iin aadaki basit komut kullanlabilir: sprintf(strx, %d, x);
8.8 kili Dosyalar

'b' bayra fread, fwrite, fseek

Uygulama: Dosyalar
rnek 33. Graarn Enlemesine Taranmas
DZELT: YAZILACAK graf tip tanm:

struct graph_s { int nodes; int adjacency[MAXNODES][MAXNODES]; }; typedef struct graph_s graph_t;
okuma fonksiyonu bildirimi:

void read_matrix(FILE *fp, graph_t &g);

Sorular
1. Bitiiklik matrisini komut satrnda belirtilen bir dosyadan okuduu grafn balant matrisini Warshall algoritmas yardmyla hesaplayan bir program yazn.

151

Giri-k

rnek 33 Bir graf enlemesine tarayan program (ana fonksiyon).


int main(int argc, char *argv[]) { FILE *fp; graph_t graph; int vertices[MAXNODES]; bool visited[MAXNODES]; int start_vertex, next_vertex; int count, index, i;

if (argc != 3) { cerr << "Kullanm: " << argv[0] << " matris_dosyas balang_dm" << endl; return EXIT_FAILURE; } fp = fopen(argv[1], "r"); if (fp == NULL) { cerr << "Matris dosyas alamad." << endl; exit(EXIT_FAILURE); } sscanf(argv[2], "%d", &start_vertex); read_matrix(fp, graph); for (i = 0; i < graph.nodes; i++) visited[i] = false; vertices[0] = start_vertex; visited[start_vertex] = true; count = 1; index = 0; while ((index < graph.nodes) && (count < graph.nodes)) { next_vertex = vertices[index]; for (i = 0; i < graph.nodes; i++) { if ((graph.adjacency[next_vertex][i] == 1) && (!visited[i])) { vertices[count] = i; visited[i] = true; count++; } } index++; } for (i = 0; i < graph.nodes; i++) cout << vertices[i] << endl; fclose(fp); return EXIT_SUCCESS;

kili Dosyalar

152

rnek 34 Bir graf enlemesine tarayan program (matris okuma fonksiyonu).


void read_matrix(FILE *fp, graph_t &g) { int c; int i = 0, j = 0; fscanf(fp, "%d\n", &g.nodes); while (true) { c = fgetc(fp); if (c == EOF) break; if (c == '\n') { i++; j = 0; continue; } g.adjacency[i][j] = c - '0'; j++; }

Blm 9
nilemci

Bir C kaynak dosyasndan altrlabilir dosya oluturulmas iin geilen aamalar derleme ve balama olarak belirtilmiti. Aslnda kaynak dosyas, derleyiciye verilmeden nce bir de nilemciden geirilir. nilemcinin yaptklar yle zetlenebilir:

Aklamalar ayklar:

/*

ile

*/ #

arasnda kalan ya da

//

iaretinden satr sonuna kadar

olan blmleri koddan siler; yani bu blmler derleyiciye hi gitmez. nilemci komutlarn iler: simgesiyle balayan komutlar nilemci komutlardr ve

nilemci tarafndan ilenirler.

En sk kullanlan nilemci komutlarn yeniden grelim:

#dene

Deimez ya da makro tanmlamakta kullanlr. Kodun iinde deimezin adnn

getii her yere deerini yazar. Szgelimi yazan her yere grmez.

3.14

yazarak derleyiciye

#define PI 3.14 nilemci komutu, kodda PI o haliyle gnderir; yani derleyici PI szcn #include <stdlib.h>

#include

Belirtilen dosyay o noktada kodun iine ekler. Szgelimi

nilemci komutu,

stdlib.h

isimli dosyay bularak kaynak kodun iine yerletirir. Kod

derleyiciye geldiinde bu dosyann ieriini de barndrr.

9.1

Makrolar

Programn iinde ska yinelenmesi gerekebilecek, ancak bir fonksiyon haline getirmeye de demeyecek kk kod paralar makrolar yardmyla gereklenir. Makrolar da deimez tanmlarna benzer ekilde

#define szcyle yaplrlar. leyileri de yine deimez tanmlarna

benzer ekilde olur, yani makronun adnn getii yere alm konur. rnek 13'de geen

sqr_total = sqr_total + (score[i] - mean) * (score[i] - mean);


153

Projeler

154

komutunu basitletirmek zere bir deyimin karesini alan

#define sqr(x) (x) * (x)


makrosunu kullanarak komutu u ekle getirebiliriz:

sqr_total = sqr_total + sqr(score[i] - mean);


Bunun sonucunda makro tanmndaki

score[i] - mean

simgesinin yerine makronun kullandld yerdeki

deyimi konur (programc kendisi bu ekilde yazm gibi).

Bu ilem bir szck ya da szck grubunun yerine baka bir szck ya da szck grubunun yerletirilmesi eklinde yrdnden kullanmna dikkat etmek gerekir. rnekteki makro

#define sqr(x) x * x
eklinde tanmlansayd makro almyla oluacak (hatal) kod u ekilde olurdu:

sqr_total = sqr_total + score[i] - mean * score[i] - mean;


rnek 35. Projeler
Bir saynn asal arpanlarnn ekrana dklmesini ve iki saynn en byk ortak blen ve en kk ortak katlarnn hesaplanmas ilemlerini yapan bir program yazlmas isteniyor. Programn rnek bir almas ekil 9.1'de verilmitir. Bu rnekte kaynak kodu birden fazla dosyaya blnecek, kullancyla etkileim ksmn yrten fonksiyon (ayn zamanda siyonu)

project.cpp

dosyasna (rnek 35), ilemleri yapan fonksiyonlar

(rnek 36) konacaklardr.

ops.cpp

main fonkdosyasna

9.2

Projeler

Yazlan programn kapsam bydke btn kaynak kodunun tek bir dosyada toplanmas zorlamaya balar. Binlerce satrlk bir kaynak kodunun tek bir dosyada tutularak program gelitirilmesi son derece zordur. Byle projelerde kaynak kodu farkl dosyalara blnr. Birden fazla kaynak dosyasna blnm bir proje derlenirken nce her kaynak dosyas ayr ayr derlenerek ara kodlar oluturulur, sonra balayc bu ara kodlar ve varsa kullanlan kitaplklar arasndaki balantlar kurarak altrlabilir kodu retir (ekil 9.3). Derleme sresi balama sresinden ok daha uzun olduundan kaynak kodun bu ekilde blnmesi altrlabilir dosyann retilmesi iin gereken zaman da azaltr. Tek bir byk dosyadan oluan projelerde herhangi bir yordamdaki herhangi bir deiiklikte btn yordamlarn yeniden derlenmeleri ve balanmalar gerekir. Oysa kaynak dosyalar blnrse yalnzca deitirilen

Bu rnein nasl derleneceini Ek B.2'de grebilirsiniz.

155

nilemci

Say 1: 0 Say 2: 0 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 1 Sayy yaznz: 9702 Say 1: 9702 Say 2: 0 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 2 Sayy yaznz: 945

ekil 9.1: Proje rnei ekran kts.

Projeler

156

Say 1: 9702 Say 2: 945 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 3 2^1 3^2 7^2 11^1 Say 1: 9702 Say 2: 945 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 4 En byk ortak blen: 1323 Say 1: 9702 Say 2: 945 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 5 En kk ortak kat: 145530 Say 1: 9702 Say 2: 945 1. 2. 3. 4. 5. 6. Say 1'i deitir Say 2'yi deitir Say 1'in arpanlarn gster En byk ortak blen bul En kk ortak kat bul k

Seiminiz: 6

157

nilemci

rnek 35 Giri/k fonksiyonlarn ieren kaynak dosyas.


#include <iostream> #include <stdlib.h> #include "ops.h" // std::xxx // EXIT_SUCCESS // gcd,lcm,...

int main(void) { int num1 = 0, num2 = 0; factor_t factors[MAXFACTOR]; int n, i; int choice; while (true) { std::cout << "Say 1: " << num1 << std::endl; std::cout << "Say 2: " << num2 << std::endl << std::endl; std::cout << "1. Say 1'i deitir" << std::endl; std::cout << "2. Say 2'yi deitir" << std::endl; std::cout << "3. Say 1'in arpanlarn gster" << std::endl; std::cout << "4. En byk ortak blen bul" << std::endl; std::cout << "5. En kk ortak kat bul" << std::endl; std::cout << "6. k" << std::endl << std::endl; std::cout << "Seiminiz: "; std::cin >> choice; if (choice == 6) exit(EXIT_SUCCESS); switch (choice) { case 1: case 2: std::cout << "Sayy yaznz: "; if (choice == 1) std::cin >> num1; else std::cin >> num2; break; case 3: factorize(num1, factors, n); for (i = 0; i < n; i++) std::cout << factors[i].base << "^" << factors[i].power << " "; std::cout << std::endl; break; case 4: std::cout << "En byk ortak blen: " << gcd(num1, num2) << std::endl; break; case 5: std::cout << "En kk ortak kat: " << lcm(num1, num2) << std::endl; break; } std::cout << std::endl; } return EXIT_SUCCESS;

Projeler

158

rnek 36 Hesap fonksiyonlarn ieren kaynak dosyas.


#include <math.h> #include "ops.h"

// sqrt,pow // struct factor_s

#define max(x, y) (x) > (y) ? (x) : (y) #define min(x, y) (x) > (y) ? (x) : (y) void gcd_factors(const factor_t factors1[], int const factor_t factors2[], int factor_t factors[], int &n); void lcm_factors(const factor_t factors1[], int const factor_t factors2[], int factor_t factors[], int &n); int gcd(int number1, int number2) { ... } int lcm(int number1, int number2) { ... } bool is_prime(int cand) { ... } int next_prime(int prime) { ... } void factorize(int x, factor_t factors[], int &n) { ... } void gcd_factors(const factor_t factors1[], int n1, const factor_t factors2[], int n2, factor_t factors[], int &n) { ... } void lcm_factors(const factor_t factors1[], int n1, const factor_t factors2[], int n2, factor_t factors[], int &n) { n1, n2, n1, n2,

159

nilemci

derleme kaynak kodu 1 ara kod 1

baglama alistirilabilir kod

kaynak kodu 2

ara kod 2

kaynak kodu n

ara kod n

kitapliklar

ekil 9.3: Birden fazla kaynak kodlu projelerin derleme aamalar.

yordamn bulunduu kaynak dosyas yeniden derlenir ve balama ilemi yaplr; deimeyen kaynak kodlarnn yeniden derlenmelerine gerek kalmaz. Byle bir almada, dosyalardan yalnzca birinde

main fonksiyonu bulunabilecei aktr; aksi

durumda balama ilemi belirsizlik nedeniyle baarsz olur. Ayrca farkl dosyalardaki fonksiyonlarn birbirlerini arabilmeleri, dosyalar arasnda deiken paylaabilmeleri gibi konular iin baz dzenlemeler yapmak gerekir. Datmann yararl olabilmesi iin fonksiyonlar, amalarna gre gruplanarak dosyalara blnmelidir. rnekte olduu gibi, kullancyla etkileimi salayan (giri/k ilemlerini yapan) fonksiyonlarn hesaplamalar yapan fonksiyonlarla ayr dosyalara toplanmas sk kullanlan bir blmleme tekniidir. Hesap ilemlerini yapan

factorize, gcd, lcm fonksiyonlar project.cpp dosyasnda bulunma-

dklarndan bu dosyann derlenmesi srasnda sorun kar. Derlenebilmesi iin bu fonksiyonun bildirimleri dosya bana eklenmelidir. Bildirimler elle yazlabilir ancak daha doru olan yntem, lelikle

ops.cpp

dosyasn bir kitaplk gibi dnp tanmlad fonksiyonlarn bildirimlerini

ieren bir balk dosyas hazrlamak ve bu balk dosyasn dier dosyann iine almaktr. By-

ops.cpp ve ops.h dosyalar baka projelerde de kullanlabilirler. rnek projede ops.cpp dosyas iin ops.h balk dosyas hazrlanm (rnek 37) ve bu dosya #include ops.h
nilemci komutuyla her iki kaynak dosyasnn da iine alnmtr. Burada



<>

simgeleri yerine

simgeleri kullanlmas, nilemcinin balk dosyasn sistem klasrlerinden nce bulunulan

klasrde aramasn salar. Balk dosyas, ilgili kitapln arayzdr; baka dosyalardaki fonksiyonlarn gerek duyabilecekleri bilgileri barndrr. Bir fonksiyon yalnzca o dosya iinde kullanlyorsa ve dardan

Projeler

160

rnek 37 Hesap fonksiyonlar iin balk dosyas.


#ifndef OPS_H #define OPS_H

#define MAXFACTOR 50 struct factor_s { int base, power; }; typedef struct factor_s factor_t; void factorize(int x, factor_t factors[], int &n); int gcd(int number1, int number2); int lcm(int number1, int number2); #endif

fonksiyonlar tarafndan arlmayacaksa (rnekteki gibi) bildirimi balk dosyasna yazlmaz.

next_prime

ve

is_prime

fonksiyonlar

Balk dosyalar, fonksiyon bildirimlerinin dnda, tip tanmlar da ierebilirler. rnekte arpanlar gstermek iin kullanlan

factor_t

tipi

project.cpp

dosyasnda da gerek duyulan

bir tip olduundan balk dosyasna alnmtr. Program bir saynn asal arpanlarn listeleme iini yapmayacak olsayd, bu veri tipi ve

factorize

fonksiyonunun bildirimine

dosyasnda gerek kalmayaca iin balk dosyasna yazlmayabilirlerdi. Bu veri tipi

project.cpp ops.cpp

dosyasnda da kullanldndan bu dosyann da ayn balk dosyasn iermesi gerekir. Benzer ekilde, deimez ve makro tanmlar da balk dosyalarnda yer alabilir. rnekte ana fonksiyon bir saynn asal arpanlarn temsil etmek zere statik bir dizi tanmlamaktadr. Bu dizinin eleman saysna kendisi karar verebilecei gibi, dier fonksiyonlarla uyum asndan bu bilgiyi balk dosyasndan almas daha uygundur. Balk dosyalarnda yaplmamas gereken iki nemli ilem vardr:

Fonksiyon tanmlamak: Balk dosyalarna fonksiyonlarn yalnzca bildirimleri yazlr, gvdeleri yazlmaz. Bir balk dosyas birden fazla C dosyas tarafndan alnabileceinden ayn fonksiyonun birden fazla kere tanmlanmas balama aamasnda hataya neden olur.

Deiken tanmlamak: Benzer ekilde, balk dosyasnda tanmlanan deikenler birden fazla dosya tarafndan alnma durumunda ayn isimli genel deikenler olarak deerlendirilir ve balama hatasna neden olurlar. Farkl dosyalar arasnda paylalacak genel deiken tanmlanmak isteniyorsa bu deiken balk dosyasnda

extern sakl szcyle bildirilmeli ve C kaynak dosyalarndan birinde normal biimde tanmlanmaldr. rnein, balk dosyasnda extern int counter; eklinde bildirilebilir ve dosyalardan biri int counter; komutuyla tanmlayabilir.

161

nilemci

Sorular
1.

x |y z|
(a) bir

ilemini gerekletirmek zere komutu yazn.

if

(b) bir makro tanm yazn. 2. saynn harmonik ortalamas yle tanmlanr:

3
1 x1

1 x2

1 x3

(a) saynn harmonik ortalamasn hesaplamak zere kullanlabilecek harmonic(x, y, z) makrosunun tanmn yaznz. (b) Yazdnz makro

b = harmonic(m - 1, n + 3, p);
eklinde arlrsa bu makronun alm nasl olur?

Projeler

162

Blm 10
Balantl Listeler

rnek 38. En Byk Ortak Blen Bulma


rnek 23'de gereklendii ekliyle, en byk ortak blen bulma programnda bir saynn arpanlar statik bir diziyle temsil ediliyordu. Bu rnekte statik dizi yerine dinamik dizi kullanmak bellek kullanmn etkinletirmek adna bir ie yaramaz; nk dinamik dizilerde yaplan, eleman says belli olduktan sonra gerektii kadar yer ayrmaktr, oysa bu rnekte eleman says ancak arpanlarna ayrma algoritmasnn sona ermesiyle sonra belli olur. Balantl listeler, bu tip algoritmalarda dizilere gre daha uygun bir veri yapsdr. Bir balantl liste, birbirinin ei dmlerden oluur; her dm tutulmak istenen bilgileri tamasnn yansra listede kendisinden sonra gelen dme de bir iareti ierir. Bylece listenin ba biliniyorsa sonraki dm gsteren alanlar zerinden ilerlenerek btn dmlere eriilebilir. Listenin sonunu belirtmek zere son dmn sonraki alanna zel bir deer (NULL) yazlr. Bu yapda, dizilerin aksine, eleman saysn tutmann gerei yoktur. rnek 38 ayn algoritmalar statik diziler yerine balantl listeler zerinde gerekleyen bir programdr. rnekteki balantl liste yapsnn oluturulmas iin kullanlan yap tanm yledir:

struct factor_s { int base, power; struct factor_s *next; }; typedef struct factor_s factor_t;
Grld gibi, bir dmde asal arpann deeri ve ssne ek olarak dmn kendi tipine iaret eden bir iareti alan vardr. Byle bir yap zerinde ilem yapmak iin tek gerekli deiken dizinin ilk elemanna iaret eden bir deiken tutmaktr, rnekteki listenin son dmn (next alannda kullanlmtr. Bu tanma gre oluturulan balantl listelerde 9702 saysnn arpanlarnn nasl gsterildii ekil 10.1'de verilmitir. 163

head tail

deikendeikeni

leri bu amala tanmlanmtr. Listeye ekleme algoritmalarnda kolaylk salamas iin bir de

NULL

yazan dm) gsteren bir de

164

rnek 38 Balantl listeler kullanarak en byk ortak blen hesaplayan program (ana fonksiyon).

int main(void) { int number1, number2; factor_t *factors1 = NULL, *factors2 = NULL, *factors3 = NULL; long int gcd = 1L; factor_t *f = NULL; cout << "Saylar yaznz: "; cin >> number1 >> number2; factors1 = factorize(number1); factors2 = factorize(number2); factors3 = gcd_factors(factors1, factors2); for (f = factors3; f != NULL; f = f->next) gcd = gcd * (long int) pow((double) f->base, (double) f->power); delete_factors(factors1); delete_factors(factors2); delete_factors(factors3); cout << "En byk ortak blen: " << gcd << endl; return EXIT_SUCCESS;

tail head 2 1 3 2 7 2 11 1

ekil 10.1: Balantl liste rnei.

165

Balantl Listeler

Bu veri yaps kullanldnda bir sayy asal arpanlarna ayran fonksiyonun giri parametresi olarak yalnzca asal arpanlarna ayrlacak sayy almas ve k parametresi olarak oluturduu arpanlar listesinin balang elemann dndrmesi yeterlidir:

factor_t *factorize(int x);


Benzer ekilde, ortak arpanlar bulma algoritmas da iki arpan listesini alarak ortak arpanlar listesini dndrr:

factor_t *gcd_factors(factor_t *factors1, factor_t *factors2);


Balantl listeler dinamik olarak oluturulduklarndan ileri bittiinde sisteme geri verilmeleri gerekir. Bu amala tanmlanan

delete_factors

fonksiyonu ilk dmne iareti ald

bir listenin btn dmlerini sisteme geri verir. Burada fonksiyon yle yazlabilir:

head

iaretisi o anda geri veri-

lecek dmn adresini tutarken p iaretisi bir sonraki dmn unutulmamasn salar. Bu

void delete_factors(factor_t *head) { factor_t *p = NULL; while (head != NULL) { p = head->next; delete head; head = p; }

rnek programda kullanlan dier fonksiyonlar olan srasyla rnek 39 ve rnek 40'de verilmitir.

factorize ve gcd_factors fonksiyonlar

10.1

Yaplara aretiler

Bir yapya iaret eden bir deiken tanmlandnda bu yapnn alanlarna erimek iin

->

ileci kullanlr. rnekte ortak arpanlardan en byk ortak blenin hesapland dngdeki

f->base yazm buna bir rnektir. Bunun yerine nce * ile iaretinin bavurduu yere eriilip daha sonra noktal gsterilimle istenen alann deeri de alnabilir: (*f).base gibi. Ancak bu
ikinci gsterilim pek yelenmez.

Uygulama: Balantl Listeler


Bu rnekte, rnek 30'de yaplan ortadeer bulma program seerek sralama algoritmas yerine araya sokarak sralama algoritmasyla gereklenecektir.

Yaplara aretiler

166

rnek 39 Balantl listeler kullanarak en byk ortak blen hesaplayan program (asal arpanlara ayrma fonksiyonu).

factor_t *factorize(int x) { factor_t *head = NULL, *tail = NULL, *f = NULL; int factor = 2; while (x > 1) { if (x % factor == 0) { f = new factor_t; f->base = factor; f->power = 0; while (x % factor == 0) { f->power++; x = x / factor; } f->next = NULL; if (head == NULL) head = f; if (tail != NULL) tail->next = f; tail = f; } factor = next_prime(factor); } return head;

167

Balantl Listeler

rnek 40

Balantl listeler kullanarak en byk ortak blen hesaplayan program (ortak

arpanlar bulma fonksiyonu).

factor_t *gcd_factors(factor_t *factors1, factor_t *factors2) { factor_t *factors = NULL, *head = NULL, *tail = NULL, *p = NULL; while ((factors1 != NULL) && (factors2 != NULL)) { if (factors1->base < factors2->base) factors1 = factors1->next; else if (factors1->base > factors2->base) factors2 = factors2->next; else { factors = new factor_t; factors->base = factors1->base; factors->power = min(factors1->power, factors2->power); factors->next = NULL; if (head == NULL) head = factors; if (tail != NULL) tail->next = factors; tail = factors; factors1 = factors1->next; factors2 = factors2->next; } } return head;

Yaplara aretiler

168

rnek 41. Araya Sokarak Sralama


Araya sokarak sralama algoritmas, temel sralama yntemlerinden biridir. Bu yntemde, her yeni gelen eleman o ana kadar gelen elemanlara gre sral olacak ekilde yerine yerletirilir. rnein 45, 22, 91, 18, 62 saylar sralanacaksa u ekilde ilerlenir:

45 22 22 18 18

45 45 91 22 45 91 22 45 62 91

Bu yntem statik diziler zerinde gereklenmeye uygun deildir nk her yeni gelen eleman eklendiinde ondan byk olan btn elemanlarn bir konum saa kaydrlmalar gerekir. rnekte 18 says dizinin en bana ekleneceinden elemann birden saa kaydrlmasna neden olur. Oysa bu algoritma balantl listeler zerinde gereklenmeye gayet uygundur. rnek 41'de bir diziyi sral bir balantl listeye eviren program verilmitir.

Ekleme ilemini yapan fonksiyonu u durumlar iin inceleyin:

   

liste bo eleman en baa ekleniyor eleman en sona ekleniyor eleman arada bir yere ekleniyor

assert core dump

169

Balantl Listeler

rnek 41 Balantl liste zerinde araya sokarak sralama program (ana fonksiyon).
#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; struct node_s { int value; struct node_s *next; }; typedef struct node_s node_t; node_t *insertsort(int *numbers, int count); void delete_nodes(node_t *head); int main(void) { int *score = NULL; node_t *head = NULL, *f = NULL; float median; int no_students, i; cout << "renci says: "; cin >> no_students; score = new int[no_students]; for (i = 0; i < no_students; i++) { cout << i + 1 << ". rencinin notu: "; cin >> score[i]; } head = insertsort(score, no_students); f = head; for (i = 0; i < no_students / 2 - 1; i++) f = f->next; median = (no_students % 2 == 1) ? f->next->value : (f->value + f->next->value) / 2.0; cout << "Orta deer: " << median << endl; delete_nodes(head); delete score; return EXIT_SUCCESS;

Yaplara aretiler

170

rnek 42 Balantl liste zerinde araya sokarak sralama program (liste fonksiyonlar).
node_t *insert(node_t *head, int v) { node_t *p = head, *newnode = NULL, *last = NULL; newnode = new node_t; newnode->value = v; while ((p != NULL) && (p->value < v)) { last = p; p = p->next; } newnode->next = p; if (last == NULL) return newnode; last->next = newnode; return head;

node_t *insertsort(int *numbers, int count) { node_t *head = NULL; int i; for (i = 0; i < count; i++) head = insert(head, numbers[i]); return head;

void delete_nodes(node_t *head) { node_t *p = NULL; while (head != NULL) { p = head->next; delete head; head = p; }

Blm 11
Rekrsiyon

ki saynn en byk ortak blenini bulmak zere kullandmz Euclides algoritmas,  a ile saylarnn en byk ortak bleni

ile

a % b

saylarnn en byk ortak blenine eittir

ilkesine dayanyordu. Problemin zmnn, bu rnekte olduu gibi, kendisi cinsinden ifade edilmesine rekrsif tanm ad verilir. zlmesi istenen problem, kendisi cinsinden daha kk bir probleme indirgenir. Srekli indirgemeler yoluyla zm bilinen bir duruma (taban durum) ulalmaya allr. Euclides algoritmasnda taban durum kk olan saynn 0'a gelmesi durumuydu; bu durumda dier say en byk ortak blen oluyordu. Aksi halde daha kk saylar zerinde en byk ortak blen aranmaya devam ediliyordu. Bu ilkeyi gerekleyen bir fonksiyon u ekilde yazlabilir:

int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); }


Rekrsiyona en ok verilen rneklerden biri de faktryel hesaplanmasdr. Rekrsif olarak faktryel hesaplayan bir fonksiyon yle yazlabilir:

int factorial(int x) { if (x == 0) return 1; else return x * factorial(x - 1); }


Bu iki rnek, C gibi blok yapl dillerde rekrsif gereklenmeye uygun rnekler deildir; nk yinelemeli olarak gereklendiklerinde daha etkin alrlar. Rekrsif yazm bazen daha gzel grnse ve matematikteki tanma daha yakn olsa da, baarm asndan dezavantajl olabilir. 171

172

rnek 43. Hanoi Kuleleri


Hanoi kuleleri probleminde 3 adet direk ve 64 adet ortas delik disk vardr. Diskler balangta birinci diree geirilmi durumdadr. ap en geni olan disk en altta, en dar olan en stte yer alr ve her disk kendisinden daha geni apl bir diskin zerinde durur. Ama, diskleri teker teker direkler arasnda tayarak ayn dzeni nc direkte oluturmaktr. Burada kural, hibir diskin hibir aamada kendisinden dar bir diskin zerine konamamasdr. ekil 11.1'de direk ve diskli rnek verilmitir. Bu rnein zmn yapan programn kts ekil 11.2'de verilmitir.

A B C

ekil 11.1: Hanoi kuleleri problemi balang durumu. Hanoi kuleleri probleminin genel zmn oluturmaya en geni apl diskin nasl tanacan dnmekle balayalm. Bu disk baka hibir diskin stne konamayaca iin nc diske baka bir direk zerinden aktarlarak geemez, bir kerede gtrlmelidir. Bunun yaplabilmesi iin birinci diskte kendisinden baka disk bulunmamal, nc disk de bo olmaldr (ekil 11.3). Bu durumda zm aamal olarak grlebilir:

1. Dar 63 diski birinci diskten ikinci diske ta. 2. En geni diski birinci diskten nc diske ta. 3. Dar 63 diski ikinci diskten nc diske ta.

Birinci ve nc admlardaki tama ilemi aslnda 63 disk iin ayn problemin zlmesinden baka bir ey deildir. O halde problemimizi

n diskin a direinden b direine c direi zerinden ta. ta. ta. ta. ta. ta. ta.

tanmas eklinde ifade ederek zm u ekilde yazabiliriz:

Bir Bir Bir Bir Bir Bir Bir

diski diski diski diski diski diski diski

1 1 3 1 2 2 1

direinden direinden direinden direinden direinden direinden direinden

3 2 2 3 1 3 3

direine direine direine direine direine direine direine

ekil 11.2: Hanoi kuleleri problemini zen programn ekran kts.

173

Rekrsiyon

A C B

ekil 11.3: Hanoi kuleleri problemi (en geni diskin tanmas).

1. 2. 3.

n - 1 a

diski

direinden

direine

direi zerinden ta.

direinde kalan diski diski

direine ta.

n - 1

direinden

direine

direi zerinden ta.

Her seferinde direk says azaldndan bu algoritma sonlanma koulunu salar. Taban durum, tanacak disk saysnn 0 olduu durumdur, bu durumda hibir ey yaplmayacaktr. O halde bu problemi zen program rnek 43'de grld gibi yazlabilir. Bu algoritmann en gzel yanlarndan biri, deneme-yanlma yntemiyle deil, herhangi bir diski gereksiz yere bir direkten bir diree aktartmadan bir kerede zm bulmasdr.

Uygulama: Rekrsiyon
rnek 44. abuk Sralama
DZELT: YAZILACAK

Sorular

174

rnek 43 Hanoi kuleleri problemini zen program.


#include <iostream> #include <stdlib.h>

// cin,cout,endl // EXIT_SUCCESS

using namespace std; #define DISKS 3 void move(int n, int a, int b, int c); int main(void) { move(DISKS, 1, 3, 2); return EXIT_SUCCESS; } void move(int n, int a, int b, int c) { if (n > 0) { move(n - 1, a, c, b); cout << "Bir diski " << a << " direinden " << b << " direine ta." << endl; move(n - 1, c, b, a); } }

175

Rekrsiyon

rnek 44 abuk sralama algoritmasn gerekleyen program.


#include <iostream> #include <stdlib.h> // cin,cout,endl // EXIT_SUCCESS

using namespace std; void quicksort(int arr[], int first, int last); int main(void) { int numbers[] = { 26, 33, 35, 29, 19, 12, 22 }; int i; quicksort(numbers, 0, 6); for (i = 0; i < 7; i++) cout << numbers[i] << endl; return EXIT_SUCCESS;

void swap(int &x, int &y) { int tmp; } tmp = x; x = y; y = tmp;

int partition(int arr[], int first, int last) { int pivotloc = first; int pivot = arr[first]; int i; for (i = first + 1; i <= last; i++) { if (arr[i] < pivot) { pivotloc++; swap(arr[pivotloc], arr[i]); } } swap(arr[first], arr[pivotloc]); return pivotloc;

void quicksort(int arr[], int first, int last) { int pivotloc; if (first < last) { pivotloc = partition(arr, first, last); quicksort(arr, first, pivotloc - 1); quicksort(arr, pivotloc + 1, last);

176

Ek A
Simgelerin Kodlanmas

Bilgisayarlarda dier her ey gibi simgeler de saylarla gsterilirler. Bunun iin hangi simgenin hangi sayyla gsterilecei (ya da tersine, hangi saynn hangi simgeye kar decei) konusunda bir uzlama olmas gerekir. Bu amala tanmlanan kodlamalar, simgelere birer numara verirler. Yaygn kullanlan ilk kodlamalardan biri ASCII kodlamasyd (ekil A.1). ASCII, 7 bitlik bir kodlama olduundan 128 farkl simgenin kodlanmasna olanak verir. lk kodun numaras 0, son kodun numaras 127'dir. Bunlardan ilk 32 simge (0-31) ve son simge (127) baslamaz simgelerdir (satr sonu, bip sesi v.b.). Aradaki 95 simgeyse (32-126) ngilizce'nin btn kk ve byk hareri, rakamlar, noktalama iaretleri ve tutakm zerinde grdnz her trl zel simgeyi ierir. ASCII kodlamas gnmzde kullanlan btn kodlamalarn temelini oluturur.

+0 32 40 48 56 64 72 80 88 96 104 112 120


( 0 8 @ H P X ` h p x

+1
! ) 1 9 A I Q Y a i q y

+2
" * 2 : B J R Z b j r z

+3
# + 3 ; C K S [ c k s {

+4
$ , 4 < D L T \ d l t |

+5
% 5 = E M U ] e m u }

+6
& . 6 > F N V ^ f n v ~

+7
' / 7 ? G O W _ g o w

Tablo A.1: ASCII kodlama izelgesi. ASCII kodlamas, ngilizce dnda kalan abecelerin harerini iermediinden, her dil iin o dilde bulunan farkl simgeleri de ieren 8 bitlik kodlamalar oluturulmutur; bylelikle 256 farkl simgenin kodlanmasna olanak salanmtr. Btn bu kodlamalarda ilk 128 simge 177

178

ASCII izelgesinde olann aynsdr, dzenlemeler ikinci 128 simge zerinde yaplr. Bu kodlamalarn en bilineni ISO8859 standart ailesinde tanmlananlardr. ISO8859 kodlamalarnda da 128-159 aras saylar kullanlmaz.

ISO8859-1: Bat Avrupa dilleri (latin1 kodlamas adyla da bilinir) ISO8859-2: Dou Avrupa dilleri ISO8859-9: Trke (latin5 kodlamas adyla da bilinir). ISO8859-1 kodlamasyla neredeyse ayndr, yalnzca ISO8859-1'deki zlandaca harerin yerine Trke harerin gelmesiyle oluturulmutur. ki kodlama arasnda deien 6 simge unlardr:  .

Son yllarda, farkl diller konuan, farkl lkelerde yaayan insanlarn ortak kullandklar uygulamalarn says ok byk bir hzla arttndan, btn dillerin btn simgelerini ieren bir kodlamaya gemek bir zorunluluk halini almtr. Bu amala gelitirilen Unicode kodlamas (resmi adyla ISO10646-1), 16 ve 32 bitlik srmleri olan bir kodlamadr. Yeryznde bilinen btn dillerin simgelerini iermenin yansra daha pek ok ek simgenin tanmlanabilmesine de olanak verir. Ancak btnyle bu kodlamaya gemek iin yaygn kullanlan btn programlarda byk miktarlarda deiiklik gerekecektir. Bu nedenle, yeni yazlan uygulamalarda bu kodlamann yaln hali olan UTF-16 ya da UTF-32 kodlamalarna uyulmas ngrlrken, kullanm sren eski uygulamalarla uyum sorununu azaltmak iin bir gei kodlamas olarak UTF-8 gelitirilmitir. Bir deerin bilgisayar belleinde bir gze ham bir veri olarak yazld dnlebilir. Szgelimi, bir bellek gznde 240 says yer alyor olsun. Program bu gz bir tamsay olarak deerlendirirse 240 deerini elde eder ve diyelim bu sayy baka bir say ile toplayabilir. ISO8859-9 kodlamasnda bir simge olarak deerlendiriyorsa '' harni elde eder ve Trke kurallarna gre sralama yapmada kullanabilir. ISO8859-1 kodlamasnda bir say olarak deerlendiriyorsa  harni elde eder ve zlandaca kurallarna gre sralamada kullanabilir. Ksacas, deer bellekte ham haliyle bulunur; nasl anlam verilecei, ne amala kullanlaca programn belirleyecei konulardr.

Ek B
Unix'de Program Gelitirme

B.1

Yardmc Belgeler

Unix iletim sistemlerinde ou zaman syleyecektir. rnek: info KDE: Konqueror ya da Alt-F2 #sqrt

man fonksiyon

komutuyla o fonksiyonla ilgili bilgi

alabilirsiniz. Bu komut fonksiyonun ne i yaptn ve hangi balk dosyasnda yer aldn

man sqrt.

B.2

Derleme

Unix ailesi iletim sistemlerinde C/C++ dilinde gelitirme yapmak iin en ok GNU C Compiler (gcc) derleyicisi kullanlr. Temel kullanm yledir:

gcc kaynak_dosyas -o altrlabilir_dosya


Kaynak dosyanz bir C++ koduysa

g++ kaynak_dosyas -o altrlabilir_dosya


komutuyla altrmanz gerekir. Bu komutun sonucunda kaynak dosya derlenir, balanr ve ismi verilen altrlabilir dosya oluturulur. Derleyici balk dosyalarn kaynak dosyasnn adnn da

/usr/include,

kitaplk dosyalarnysa

/usr/lib

kataloglarnda

arar. Derleyicinin almas baz bayraklar yardmyla denetlenebilir. Aadaki rneklerde

main

main.cpp,

hedef dosya adnn

main.o,

altrlabilir dosya adnn

olduu varsaylrsa:

Kaynak dosyay yalnz derlemek istiyorsanz, yani balamak istemiyorsanz kullanabilirsiniz: 179

-c bayran

Derleme

180

g++ main.cpp -c -o main.o

Derleyicinin btn uyarlarlarn grmek istiyorsanz

-Wall

bayran kullanabilirsiniz:

g++ main.cpp -Wall -o main

Baka kataloglarda da balk dosyas aramasn istiyorsanz bilirsiniz:

-I

bayrayla bunu belirte-

g++ main.cpp -I/usr/X11R6/include -o main

Baka kataloglarda da kitaplk aramasn istiyorsanz

-L bayrayla bunu belirtebilirsiniz:

g++ main.cpp -I/usr/X11R6/include -L/usr/X11R6/lib -o main

Optimizasyon: -O2

Birden fazla kaynak dosyasndan oluan bir projenin derlenmesi birka aamal olur. rnek 35 zerinde bir projenin nasl derleneceini grelim:

project.cpp

dosyasn derle (balamadan):

g++ -c project.cpp -o project.o


ops.cpp
dosyasn derle (balamadan):

g++ -c ops.cpp -o ops.o

bala

g++ project.o ops.o -o project


Kaynak dosyalarnn herhangi birinde bir deiiklik yaplrsa yalnzca o dosyann yeniden derlenmesi ve balama yeterlidir. Her seferinde elle derleme komutlarn yazmak zahmetli bir i olduundan derleme ilemlerini kolaylatrmak iin make arac kullanlr. Bu ara, programcnn yazd, derleme aamalarn belirten

Makefile

isimli bir dosya denetiminde alr.

Makefile

dosyas hedeerden oluur.

Her hedef iin heden nelere bal olduu ve nasl oluturulaca belirtilir. rnek bir hedef yle yazlabilir:

project: project.o ops.o g++ project.o ops.o -o project


Bu yazmn anlam,

project

hedenin

project.o

ve

ops.o

dosyalarna bal olduu ve olu-

turulmas iin ikinci satrda yazlan komutun kullanlacadr.

1 Bir heden bal olduu dos-

yalarda deime olursa (dosyann tarih ve saati hedenkinden yeniyse) heden yeniden oluturulmas gerektiine karar verilir. rnek projedeki dier hedeer de yle yazlabilir:

Hede oluturmakta kullanlacak komutlar satr bandan bir sekme ieriden balamaldr. Bir hede olu-

turmakta birden fazla komut kullanlabilir.

181

Unix'de Program Gelitirme

project.o: project.cpp g++ -c project.cpp -o project.o ops.o: ops.cpp g++ -c ops.cpp -o ops.o make
komutu altrlrken hangi heden oluturulmasnn istendii belirtilir. Hedef belirtildosyalarnn hibirinin olmadn varsayarsak,

mezse dosyada bulunan ilk hedef oluturulmaya allr. Balangta

project

make project

project.o, ops.o

ve

komutunun almas

yle olur:

1.

project
allr.

hede oluturulmaya allr. Bu hedef

project.o

ve

ops.o

hedeerine bal

olduu iin ve bunlar henz oluturulmam olduu iin srayla bunlar oluturulmaya

2.

project.o hede oluturulmaya allr. Bu hedef project.cpp dosyasna bal olduu


iin oluturulmasna geilebilir ve

g++ -c project.cpp -o project.o


komutu yrtlr. 3.

ops.o hede oluturulmaya allr. Bu hedef ops.cpp dosyasna bal olduu iin oluturulmasna geilebilir ve

g++ -c ops.cpp -o ops.o


komutu yrtlr. 4. Artk

project hedenin bal olduu iki dosya da olumu olduundan bu heden olu-

turulmasna geilebilir ve

g++ project.o ops.o -o project


komutu yrtlr.

leride

ops.cpp

dosyasnda bir deiiklik yapldn ve

make project

komutunun yrtld-

n dnelim:

1.

project

hede oluturulmaya allr. Bu hedef

project.o

ve

ops.o

hedeerine bal

olduu iin nce onlara baklr. 2.

project.o hede oluturulmaya allr. Bu hedef project.cpp dosyasna baldr ancak project.cpp dosyasnn saati project.o dosyasndan eski olduu iin bir ilem
yaplmaz.

3.

ops.o

hede oluturulmaya allr. Bu hedef

dosyasnn saati

ops.o

ops.cpp

dosyasna baldr ve

ops.cpp

dosyasndan yeni olduu iin heden yeniden oluturulmas ge-

rektiine karar verilir ve

Editrler

182

g++ -c ops.cpp -o ops.o


komutu yrtlr. 4.

project
ve

hedene dnldnde

ops.o

dosyasnn saati artk

project

dosyasnn sa-

atinden yeni olduu iin bu heden de yeniden oluturulmas gerektiine karar verilir

g++ project.o ops.o -o project


komutu yrtlr.

Makefile

dosyalarnda ayrca baz deimezler tanmlanarak okunulurluk ve esneklik artrla-

bilir. rnek proje iin yazlm bir

Makefile

rnek 45'de verilmitir. Bu dosya ska kullan-

lan, kaynak dosyalar dnda kalan her eyi silen

clean

hedeni de iermektedir;

make clean

komutu sizin yazdnz dnda kalan btn dosyalarn silinmesi iin kullanlr.

rnek 45 rnek bir Makefile dosyas.


CXX=g++ CXXFLAGS=-O2 -Wall -g -pg LDFLAGS=-pg

proje: proje.o ops.o $(CXX) $(LDFLAGS) proje.o ops.o -o proje proje.o: proje.cpp $(CXX) $(CXXFLAGS) -c proje.cpp -o proje.o ops.o: ops.cpp $(CXX) $(CXXFLAGS) -c ops.cpp -o ops.o clean: rm -f *.o proje

nilemci: cpp

B.3

Editrler

nedit kate mcedit: yazm renklendirme, ayra eletirme, makrolar, tab emlasyonu, kendiliinden girintileme

B.4

Hata Ayklayclar

altrlabilir dosya zerinde hata ayklama yapacaksanz

-g

bayran kullanmalsnz:

183

Unix'de Program Gelitirme

g++ main.cpp -g -o main


Hata ayklama bilgilerini silmek iin -s strip gdb ddd: adm adm altrma, deiken deerlerini izleme aretilerle alrken yaplan hatalar sklkla programn kmesine ve o anki bellek grntsnn bir dosyaya yazlmasna neden olurlar (core dump). Bu bellek grnts programnzn neden ktne ilikin nemli bilgiler ierir ve hatann nedenini bulmanza yardmc olabilir. rnek 39'de

if (x % factor == 0) {
satrndan sonraki

f = new factor_t;
komutunu silerek program derleyin ve altrn. Program bellek hatas vererek kecektir. ddd hata ayklaycsnda nce Open Program komutuyla altrlabilir dosyay, sonra da Open Core Dump... komutuyla yaratlan

core

dosyasn an. Programn kt anda

f->base = factor;
satrnda kaldn ve

iaretisinin deerinin

NULL

olduunu greceksiniz.

B.5

Baarm nceleme

Programnzdaki fonksiyonlarn kaar kere arldklarn ve hangi fonksiyonda ne kadar zaman harcandn lmek iin gprof aracn kullanabilirsiniz. gprof 'un kullanlabilmesi iin gcc/g++ derleyicisine hem derleme hem balama aamasnda hangi fonksiyonun ka kere arldn grmek iin:

-pg

bayra verilmelidir. rnek 23'de

g++ -pg lcm.cpp -o lcm


komutuyla program derlendikten sonra altrlr ve en kk ortak kat hesaplanmak istenen deerler girilir. Bu alma sonucunda

gmon.out

isimli bir dosya oluur ve

gprof lcm gmon.out


komutu programn almasyla ilgili bir rapor retir. 32424 ve 563324 deerlerinin girilmesiyle oluan rnek bir raporun baz blmleri aada verilmitir:

% cumulative self self total time seconds seconds calls us/call us/call 95.24 0.20 0.20 70516 2.84 2.84 4.76 0.21 0.01 2 5000.00 105000.00 0.00 0.21 0.00 13127 0.00 15.24 0.00 0.21 0.00 1 0.00 0.00

name is_prime factorize next_prime merge_factors

You might also like