Professional Documents
Culture Documents
Program Lama Ya Giris Ders Notlari
Program Lama Ya Giris Ders Notlari
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.
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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
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
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
9 nilemci
9.1 9.2 Projeler
153
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Makrolar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
10 Balantl Listeler
163
Yardmc Belgeler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Derleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Editrler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Hata Ayklayclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
INDEKILER
viii
Blm 1
Giri
Bir problemi zmek zere bir bilgisayar program yazarken iki temel soruna zm getirmek gerekir:
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)
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.
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
ettiimiz ehre gre bu deikenlere uygun deerler vermemiz gerekir. Szgelimi, stanbul eh-
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).
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
Veriler
sayi1 32
sayi2 154
say1
ninde ise bir deiiklik olmaz. kinci atama ilemi (ekil 1.4b) ise
say2
say2
say2
deike-
deikenine
say1
sayi1 32
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:
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
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
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)?
etmek istiyor
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
labilir. Bu veri tipinin biri bir katar (ehir ismi), dier ikisi de birer kesirli say olan (enlem
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
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)
tem yol kod ilk_kent isim enlem boylam uzunluk son_kent isim enlem boylam
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
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
kende tutulacaksa, bu deiken simge dizisi tipinden olacaktr (ekil 1.9). rnekte
adsoyad7
adsoyad1
adsoyad D e n n i s R i ... 1 2 3 4 5 6 7 8 9 10
Dizilerle kaytlar birlikte de kullanlabilir. Szgelimi, bir saynn asal arpanlarn temsil etmek zere bir dizi kullanabiliriz (6776
= 23 71 112 ).
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 ... ...
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.
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.
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:
1. 2. 3. 4.
max notlar1 , i2 i 50
ise 3. adma, deilse 5. adma git. ise
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
ii+1
11
Giri
max 43 74 82
i 2 3 4 5 6 7
D D D D D Y
notlari > max D (74 > 43) Y (65 < 74) Y (58 < 74) D (82 > 74) Y (37 < 82)
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.
sylenen sylenen + 1
Algoritma 2.
st
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
sylenen = tutulan
bas: sylenen
dur
alt sylenen + 1
st sylenen - 1
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)
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 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)
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
ko-
goto
bulunmas gerektii dnlebilir (zellikle yineleme yaplar iin). Ancak blok yapl prog-
goto
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/
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
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.
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.
Soyutlama
16
1 * 32 * 72 * 111
3 * 51 * 71
2 * 71
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
2. sayi
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.
a,
kk olanna
dersek:
17
Giri
9702
2 32 72 11 33 5 7
2 32 72 11
32 7
33 5 7
ekil 1.16: rnek saylar zerinde en byk ortak blen hesaplama algoritmasnn ileyii.
a = q 1 b + r1
eklinde yazlabilir. Burada ile
r1 = 0
b'dir.
Deilse
ile
r1
ile
b'nin
rn 'dir.
Yine
a = 9702, b = 945
rneini alrsak:
iaretiyle gsterilsin), bu algoritma bir yineleme yapsyla gereklenebilir. Bir blme ileminde
Soyutlama
18
r'nin
deikeni
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
Y a sayi2 b sayi1
b>0 D ra%b ab br
bas: a
r 252 189 63 0
Uygulama: Algoritmalar
Herhangi bir saynn asal arpanlarna ayrlmas iin kullanlabilecek bir algoritma ekil 1.18'de verilmitir. Bu algoritmada
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
c2
x>1 D
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
2 3
5 7 11
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
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
21
Giri
c1 carpanlar11, c2 carpanlar21 i1 1, i2 1
c1 ve c2 bos deil
D D i1 i1 + 1 c1 carpanlar1i1
i2 i2 + 1 c2 carpanlar2i2
c1 bir carpandir
c2 bir carpandir
i1 i1 + 1, i2 i2 + 1 c1 carpanlar1i1, c2 carpanlar2i2
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
Tasarm
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-
kod
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
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.
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
ne kadar hzl alyor? Dzgn kullanlabilmesi iin ne kadar sistem kayna gerekiyor (hangi ilemci, ne kadar bellek, ne kadar disk, v.b.?).
Salamlk
kendisine bir yl bilgisi sorulduunda kullanc yanllkla (ya da kt niyetle) bir isim yazarsa ne oluyor?
Tanabilirlik
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 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
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):
kitapliklar
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
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.
ekil 2.1: rnek 1 ekran kts. rnek zerinde bir C programnn baz temel zelliklerini grelim:
Aklamalar
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
bir aklamann iinde ikinci bir aklama olamaz. ie aklamalar u ekilde bir yap oluturur:
30
/* 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
/*
oluturur. Bundan sonra gelen blm (d blgesi) normal C kodu gibi deerlendirileceinden hataya yol aar.
*/
ve
/*
g-
blgeleri
kinci yntemde, aklama ift bl ile balar ve satrn sonuna kadar srer. satrdaki cout,cin,endl satrdaki EXIT_SUCCESS
1 Ksa
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
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
c = 24; b = c; a = b;
simler
32
Fonksiyonlar
main
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
Balk dosyalar
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
#include <iostream>
komutu yer almaktadr.
3 Benzer ekilde,
stdlib.h
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
ve
weight_1
, arlk
ve
2weight
.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
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
cout
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
cin, cout
ve
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
Anlaml isimler verilmek istendiinde bazen birden fazla szce gereksinim duyulabilir. Bu durumda ya ismi oluturan iki szck bir altizgi iaretiyle birletirilir (rnein
birth_month)
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
circum
ve
area
35
C Diline Giri
radius
Gelenek
circum
ve
area
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.
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:
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
char
deerler alrlar (bkz. Ek A). rnein 'A' har ASCII kodlamasnda 65. srada olduundan 'A' simgesinin say deeri 65'tir. mantksal
bool
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
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
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
Deimezler
36
2.5
Deimezler
Programda kullanlan baz bilgiler de programn farkl almalar arasnda deer deitirmezler. rnekteki
PI
PI
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.
1.
#define
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
unsigned
ya da
hareri
ya da
eklenirse
tipinden ol-
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-
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
+ -
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
C'de deyimlerin hesaplanmasnda izlenen ncelik sras, matematikten alk olunan sradr. Yksek ncelikliden alak ncelikliye doru ncelik gruplar yledir:
ve
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:
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
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:
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
num2
deikeni, nc ko-
mutta ise her ikisi birden kesirli sayya evrilmektedir. Buna karlk
quotient
num1
2.8
Artrma / Azaltma
Bir atamann sa tarafndaki deyim, atamann sol tarafndaki deikeni ieriyorsa, yani
deiken = deyim;
Matematik Kitapl
40
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:
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
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
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|
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.
abs
2.10
Giri / k
C dilinde kullancyla iletiimi salayan ilemler giri/k birimleri zerinden yaplr (bkz. Blm 1.5). Girdiler
9 gnderilir.
rnekteki
C dilinde
cin, cout ve cerr birimleri yoktur, bunlarn yerine standart girdi/kt kitaplndaki fonksiyon-
Giri / k
42
komutu sonucunda
radius
Birden fazla deiken birlikte okunmak isteniyorsa bunlar birbiri ardna > > iaretleriyle belirtilebilir. Szgelimi, iki tane say deeri okunacak ve kullancnn yazd birinci saynn deeri
num1,
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
Alan: katarn, daha sonra area deikeninin deerini yazar ve yeni circum ve area deikenleri tanmlanmadan ve atama komutlar
cout < < evresi: < < 2 * PI * radius < < endl; cout < < Alan: < < PI * radius * radius < < endl;
komutlaryla da yaplabilirdi.
10
y = ex
formlnde
y'nin
PI deimezinin tanmn 3.14 yerine 3.14159 olarak verin ve ayn x deerinde y'nin ald
deeri gzleyin.
10
Unix iletim sistemlerinde derleme aamalar ile ilgili bilgi iin bkz. Ek B.2.
43
C Diline Giri
rnek 2 y = ex
#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;
float x, y;
satrndaki 'x' harni 'X' ile deitirin ve derleme sonucunda oluan hatay gzleyin.
rnekteki
PI = 3.14159;
komutunu ekleyin ve derleme sonucunda oluan hatay gzleyin.
#define
PI deimezinin tanmland
satrn silin ve
float x, y;
satrnn ardna
Bataki
#include <math.h>
Giri / k
44
Sorular
1. altnz gelitirme ortamnda
int
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)
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.
+ bx + c = 0
b2 4ac
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.
45
46
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
Eitlik:
farklysa yanl sonucunu retir. Farkllk: != ileciyle gereklenir. Eitlik karlatrmasnn tersidir. lecin solundaki deerle sandaki deer farklysa doru, aynysa yanl sonucunu retir. Kklk:
< >
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.
cin solundaki deer sandaki deerden kk veya eitse doru, bykse yanl sonucunu
cin solundaki deer sandaki deerden byk veya eitse doru, kkse yanl sonucunu
rnekler
(year % 4) == 0
age >= 18
Karlatrma ilemleri tam ya da kesirli saylarn karlatrlmasnda kullanlabilecei gibi, harerin abecedeki sralarna gre karlatrlmasnda da kullanlabilir. Szgelimi
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:
katarlar abece srasna gre karlatrlamaz, yani aadaki komut geerli deildir (doru ya da yanl sonucunu retmez, derleyicinin hata vermesine neden olur):
f1 == f2
yerine aadaki gibi bir koul yazlabilir:
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
koul
doru yanl
!(koul)
yanl doru
rnek
Ya 18'den kk deil:
49
Ak Denetimi
koul1
doru doru yanl yanl
koul2
doru yanl doru yanl
VE ilemi:
&&
rnek
||
koul1
doru doru yanl yanl
koul2
doru yanl doru yanl
(koul1) || (koul2)
doru doru doru yanl
rnek
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.
Seim
50
3.2
Seim
if
if/else
else
yrtlr:
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
if (koul ) { blok ; }
2
Birden fazla kouldan oluan mantksal deyimler deerlendirilirken sonu belli olduu zaman deyimin geriye kalan hesaplanmaz. rnein
(year % 4 == 0) koulu yanl deerini verirse deyimin (year % 100 != 0) koulu snanmaz. Benzer ekilde (year % 4 == 0)
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
Seim
52
u ekilde de yazlabilir:
if / else
blok2
koul2
if
blok2 , koul1
else'in
doru ve
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
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 ,
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.
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
if
oklu Seim
54
// 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 == '-') ... 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:
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
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
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
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
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
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
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
3.4
while
szcyle kurulur:
60
// 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
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
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:
while
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,
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
if ile belirtilen koul salanyorsa birtakm ilemlerin gerekletirilmesinden sonra bana dnlr. Yani if bloundan sonra gelen komutlar atlanarak i deikeninin
3.6
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
64
basla
oku: count
i1 heads 0 tails 0
i count
D Tura Yazi
at
heads heads + 1
tails tails + 1
ii+1
Ka kere atlacak? 7 Yaz Tura Tura Yaz Yaz Yaz Yaz Tura says: 2, Yzdesi: %28.5714 Yaz says: 5, Yzdesi: %71.4286
65
Ak Denetimi
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;
66
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.
i deikenine 1 deerini ver ve bu deikenin deeri count deikeninin deerinden i deikeninin deerini
for
dngleri
while
while
for,
koul denetiminde
Dng, belirtilen koul salanmad zaman sonlanr ve programn yrtlmesi dngnn arkasndan gelen komutla srdrlr. rnekte
Artrma ilemi dng gvdesi yrtldkten sonra yaplr. rnekte dngnn gvdesi deikeninin 1, 2, ...,
count
Verilen balang deeri dng koulunu salamyorsa dngnn gvdesi hi yrtlmez. rnein
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.
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
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
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.
68
ex
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
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
xi i! olduu gznne alndnda dizide bir = x olarak hesaplanabilir. Yani her terim, i
ile arplp
i'ye
s alma ve faktryel hesaplama ilemlerine gerek kalmaz ve seri toplam ok daha hzl elde
rnek 9 ex
// 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;
Sorular
1.
mantksal deyimini
deeri verin.
70
(c)
x'in
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.
ekrana dken bir program yazn. 5. nsan bedeninin alann hesaplamakta kullanlabilecek iki forml aada verilmitir. DuBois forml: Boyde forml:
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.
binomi,j =
1 binomi1,j1 + binomi1,j
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
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,
varsayarak 1 ile 6 arasnda reteceiniz rasgele sayda bu alt saynn gelme olaslklar eit midir? Deilse, daha iyi bir yntem nerebilir misiniz?
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
veri_tipi
isimli tipe
yeni_isim
int veri tipine score_t diye yeni bir isim verilmi olur. Daha sonra bu tipten deiken
tanmlamak iin
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
int
int
szcklerinin deimesi, bazlarnn deimemesi anlamna gelir ve programn boyutlarna gre byk zorluklar karabilir.
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
her bir grup iin yaplacak ilemlerin bir kere belirtilmesi salanmtr. Programn rnek bir almasnn ekran kts ekil 4.1'de verilmitir.
5 6 10 11 5
Bu rnek, H.M. Deitel ve P.J. Deitel'in yazdklar C: How to Program kitabndan uyarlanmtr.
75
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
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 { 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
typedef
77
komutu
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.
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
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.
true, false
doru ve yanl byklkleri programlarda ska gereksinim duyulan deerler olduklarndan C programlarnda genellikle bunlar genellikle programn banda deimez olarak tanmlanrlar.
Numaralandrma
78
// 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
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
4.2
Yaplar
Kayt tiplerinin zelliklerinden Blm 1.1.2'de sz edilmiti. C dilinde kaytlara yap ad verilir ve yle tanmlanrlar:
struct knye
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
denom.
struct rational_s
adnda bir veri tipi olumutur. Kullanm kolayl asndan bu veri tipine
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:
rational_s
szc yazlmasa da olurdu. Yine de ounlukla nerilen yntem, belirtilmeleri zorunlu olmasa da knyeleri
Yaplar
80
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:
81
month
month
year
year
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
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
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
Yaplar
84
Blm 5
Diziler
Bu blmde programlamada ska gereken dizi tiplerinin (bkz. Blm 1.1.3) C dilinde nasl kullanlaca zerinde durulacaktr.
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
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
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
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
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:
88
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
rda da rnekleri grlen yntemdir. Boy olarak deimez bir deer vermek zorunludur. rnekte snftaki renci says
no_students
no_students
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
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
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
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
for
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.
90
Kullancnn yazd tmceyi tersine evirerek ekrana kartan bir program yazlmas isteniyor. Programn rnek bir almas ekil 5.3'de verilmitir.
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):
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.
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]
Katar Kitapl
92
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
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
'\0'
strlen(computer) 8
1 2
Gvenlik nedenleriyle
gets
fgets
fonksiyonunun kullanlmas nerilir (bkz. Blm 8). Daha ayrntl aklama iin bkz. Blm .7.3.
93
Diziler
Ad
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
dest
strncpy
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:
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
ok Boyutlu Diziler
94
n.
deeri iin
p(x)'in
hesaplanmas
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(4), p(2.5)
ve
p(19)
deerlerini hesaplatn.
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
// 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
97
Diziler
// 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=
{ 0 }
balang deeri btn elemanlara 0 balang deerini atar. ok boyutlu dizilerde ilki dnda btn boyutlarn belirtilmesi zorunludur. Szgelimi bir isim dizisi oluturulmak isteniyorsa
tanmlamas derleyicinin hata vermesine neden olur. Birinci boyut dndakiler belirtilerek yazlrsa
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
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.
99
Diziler
Uygulama: Matrisler
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.
balangta:
x1 'in
x2 'nin
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
Bavurular
100
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
rand
fonksiyo-
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
srand
k parametrelerinin kullanmnda tip uyumuna dikkat edilmelidir. Szgelimi, yonu tamsay tipinden bir deer dndrdne gre olmaldr, katar tipinden olamaz.
number
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.
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
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
105
Fonksiyonlar
// 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;
106
6.1
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:
next_prime
next_prime
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
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:
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.
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
deikeninin deeri
is_prime
Tipi uygun olduu srece parametre olarak herhangi bir deyim belirtilebilir. Szgelimi aadaki arlar geerlidir:
Yerel Deikenler
108
factor 2
prime next_prime
cand
cand is_prime
count
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
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
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
factor 2
prime next_prime 2
cand 3
cand is_prime
count
factor 2
prime next_prime 2
cand 3
!is_prime(cand)
factor 2
prime next_prime 2
cand 3
cand is_prime 3
count 3
Genel Deikenler
110
ve
cand)
number
ve
tanmlad deikenler de geersiz hale gelir. Baka bir deyile, deikenlere tanm blgeleri dnda eriilemez. Yani szgelimi kullanamaz.
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
cand
deikeni oluurdu ve
is_prime
cand
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;
Bavuru Aktarm
112
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)
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
&
swap
fonksiyonunun balk
m Cn =
Bavuru Aktarm
114
// 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);
115
Fonksiyonlar
// 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);
116
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
dan kullanacaktr. Asal arpan dizilerinden en byk ortak blenin asal arpanlarn bulmak
gcd_factors
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;
6.6
factorize
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.
number1 saysn asal arpanlarna ayr, sonular factors1 dizisinde olutur ve bu dizideki geerli eleman saysn n1 deikenine yaz.
6.7
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
factors1
dizisi ve
n1
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
gcd_factors
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
void gcd_factors(const factor_t factors1[], int n1, const factor_t factors2[], int n2, factor_t factors[], int &n);
Burada
programcnn aslnda deimemesi gereken bir deeri yanllkla deitirmesine engel olmak iin konmutur. Fonksiyonun tanm rnek 25'de verilmitir.
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++; } }
120
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 (xi ) + (x xi )f (xi ) = 0
ekline getirilebilir ve buradan da
x = xi
yazlabilir. Bu formlde
f (xi ) f (xi )
yerine
xi+1
temiyle hesaplanabilir. Yani her admda o admdaki konarak bir sonraki admda kullanlacak Bu yntemin
deeri formldeki
xi
deerinin yerine
n.
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
bn = an bn1 = bn xi + an1 b0 = b1 xi + a0
Bu durumda,
p (x)
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
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
x0 = 1
deerinden balayarak,
0.001
6.8
E simli Fonksiyonlar
C++ dilinde giri parametre listeleri farkl olduu srece birden fazla fonksiyonun isimlerinin ayn olmas bir sorun yaratmaz.
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(char s1[], char s2[]) { char tmp[MAXSIZE]; strcpy(tmp, s1); strcpy(s1, s2); strcpy(s2, tmp);
}
4
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 = 0) { int index = -1, i; for (i = start; s[i] != '\0'; i++) { if (s[i] == c) { index = i; break; } } return index;
}
rnekte
start
arlrken belirtilmezse 0 deerini, belirtilirse verilen deeri alr. lk iki parametrenin arda belirtilmesi zorunludur; yani fonksiyon iki ya da parametreyle arlabilir:
// 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
'o'
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
sistemdeki
(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
kil 7.1b, ayn durumun rnek adres deerleriyle nasl salandn gsterir. zl olduu bellek gznn adresinin
8000
olduu varsaymyla,
8000
422
deerinin ya-
deikeninin
8000
deerini
lendirmez, bunlar iletim sistemi belirler. Programc adres deerlerinin ne olaca konusunda
(a)
(b)
ekil 7.1: areti tipinden deikenler. aretinin iaret ettii bellek gznn ieriinin okunmas iin rnekte rnein
8000, *p
deyiminin deeriyse
422'dir.
iaretinin kendisiyle mi, yoksa iaret ettii alanla m ilem yapldna dikkat edilmelidir.
p++
422
&p
&p: p:
12000
8000 422
*p:
NULL
retinin geerli bir bellek gzne iaret etmiyor olduudur. Dolaysyla, deeri
NULL
olan bir
ama alma annda bellek hatasna yol aacak bir programlama hatasdr.
129
aretiler
score NULL
namik diziler kullanlmasdr. Bylece snftaki renci says kullancdan renildikten sonra, tam gerektii kadar eleman tutacak bir dizi tanmlanabilmitir.
7.1
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
score
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
oluan bir bellek alann ayrarak balang adresini verir. Yer alma giriimi baarszlkla sonulanrsa, rnein bellekte yer kalmadysa, geriye NULL deerini dndrr. Yazm u ekildedir:
Bellek Ynetimi
130
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
score
no_students * sizeof(int)
kadar-
Tek bir elemanlk blge ayrlacaksa eleman saysnn belirtilmesine gerek yoktur. rnein, ekil 7.1'de izilen durum u komutlarla yaratlabilir:
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:
ile
*p
delete
132
new ve delete ileleri C++ dilinde getirilmi yeniliklerdir. C dilinde ayn malloc ve free fonksiyonlarn kullanmak gerekir. Buna gre rnekteki
new
aklanabilir:
1.
new
malloc
malloc
fonksiyonu geriye
void *
malloc ve free birer fonksiyon olduklarndan parametrelerinin ayralar iinde yazlmas gerekir. Ayn nedenle, kullanlabilmeleri iin bir balk dosyasnn (stdlib.h) alnmas
gerekir.
7.3
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; 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.
*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
== str2),
str1
ile
(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
7.4
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)
134
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
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
return
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
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
char encoding[][5] = { ... }; int main(void) { ... } char *encode(char *word) { ... }
Adres Aktarm
136
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
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
deikenine
137
aretiler
x swap 2000
y 2004
tmp xxx
m main 32 2000
x swap 2000
y 2004
tmp xxx
n 32 2004 (b)
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
n1
Adres Aktarm
138
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
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:
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
printf
yaps u ekildedir:
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
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
rnek. radius
2.4
% 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):
alan:
tlr:
Biim katarndan sonraki ikinci deyimin deeri kesirli say biiminde ekrana kar-
18.07
\n
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
scanf
cin
printf
ne olacan belirler. Kullanlan veri tipi belirteleri de ayndr. Giri yaplrken kullancnn yazd deerin alnaca deiken
scanf
fonksiyonunda deer
scanf fonksiyonuna gnderilen deikenlerin adlarnn bana adres ileci olan & simgesi konur.
rnein
scanf(%d, &radius);
Katar tipinden olan deikenlerde katarlar bir dizi olduklarndan ve adlar zaten dizinin ilk elemanna bir iareti olduundan katar tipinden bir
word
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
olursa program
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).
// // // //
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).
// // // //
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);
146
8.3
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
argc
parametre saysn,
argv
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
stat3
argv
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,
atof)
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
Bir dosya zerinde ilem yapmadan nce ilk yaplmas gereken dosyann almasdr. Ama ilemi bildirimi aada verilmi olan
fopen
path
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)
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:
EOF
deerini dndrr.
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
bildirimi u ekildedir:
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-
stream parametresi ile belirlenen dosyadan okuduu sradaki simgeyi bir tamsay feof
fonksiyonundan yararlanlr. Bu
fonksiyon kendisine parametre olarak gnderilen dosya iaretisinin ilgili dosyann sonu olup olmadn snar ve sona gelindiyse doru deerini dndrr.
8.5
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
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
cerr
exit
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
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
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:
// 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
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:
Sorular
1. Bitiiklik matrisini komut satrnda belirtilen bir dosyadan okuduu grafn balant matrisini Warshall algoritmas yardmyla hesaplayan bir program yazn.
151
Giri-k
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
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
//
olan blmleri koddan siler; yani bu blmler derleyiciye hi gitmez. nilemci komutlarn iler: simgesiyle balayan komutlar nilemci komutlardr ve
#dene
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
nilemci komutu,
stdlib.h
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
benzer ekilde olur, yani makronun adnn getii yere alm konur. rnek 13'de geen
Projeler
154
score[i] - mean
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:
project.cpp
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
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
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
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
#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
kaynak kodu 2
ara kod 2
kaynak kodu n
ara kod n
kitapliklar
yordamn bulunduu kaynak dosyas yeniden derlenir ve balama ilemi yaplr; deimeyen kaynak kodlarnn yeniden derlenmelerine gerek kalmaz. Byle bir almada, dosyalardan yalnzca birinde
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
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
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
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
#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
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
bir tip olduundan balk dosyasna alnmtr. Program bir saynn asal arpanlarn listeleme iini yapmayacak olsayd, bu veri tipi ve
factorize
fonksiyonunun bildirimine
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
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
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
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
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:
delete_factors
bir listenin btn dmlerini sisteme geri verir. Burada fonksiyon yle yazlabilir:
head
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.
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.
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
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
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.
liste bo eleman en baa ekleniyor eleman en sona ekleniyor eleman arada bir yere ekleniyor
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
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:
172
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.
1 1 3 1 2 2 1
3 2 2 3 1 3 3
173
Rekrsiyon
A C B
1. 2. 3.
n - 1 a
diski
direinden
direine
direine ta.
n - 1
direinden
direine
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
// 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
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;
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.
+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
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:
/usr/include,
kitaplk dosyalarnysa
/usr/lib
kataloglarnda
main
main.cpp,
main.o,
olduu varsaylrsa:
Kaynak dosyay yalnz derlemek istiyorsanz, yani balamak istemiyorsanz kullanabilirsiniz: 179
-c bayran
Derleme
180
-Wall
bayran kullanabilirsiniz:
-I
Optimizasyon: -O2
Birden fazla kaynak dosyasndan oluan bir projenin derlenmesi birka aamal olur. rnek 35 zerinde bir projenin nasl derleneceini grelim:
project.cpp
bala
Makefile
Makefile
Her hedef iin heden nelere bal olduu ve nasl oluturulaca belirtilir. rnek bir hedef yle yazlabilir:
project
hedenin
project.o
ve
ops.o
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-
181
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,
project
make project
project.o, ops.o
ve
komutunun almas
yle olur:
1.
project
allr.
project.o
ve
ops.o
hedeerine bal
olduu iin ve bunlar henz oluturulmam olduu iin srayla bunlar oluturulmaya
2.
ops.o hede oluturulmaya allr. Bu hedef ops.cpp dosyasna bal olduu iin oluturulmasna geilebilir ve
project hedenin bal olduu iki dosya da olumu olduundan bu heden olu-
turulmasna geilebilir ve
leride
ops.cpp
make project
komutunun yrtld-
n dnelim:
1.
project
project.o
ve
ops.o
hedeerine bal
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
dosyasnn saati
ops.o
ops.cpp
dosyasna baldr ve
ops.cpp
Editrler
182
project
ve
hedene dnldnde
ops.o
project
dosyasnn sa-
atinden yeni olduu iin bu heden de yeniden oluturulmas gerektiine karar verilir
Makefile
Makefile
clean
hedeni de iermektedir;
make clean
komutu sizin yazdnz dnda kalan btn dosyalarn silinmesi iin kullanlr.
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
-g
bayran kullanmalsnz:
183
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
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
gmon.out
% 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