![]() |
|
|||||||
| Donanımlar Bilgisayar donanımları ile ilgili bölüm. |

| ||
![]() |
|
|
Seçenekler | Arama | Stil |
![]() C dersleri 2 | ||||||||||
|
(#1)
|
||||||||||
|
[10]Yeni Üye
![]() ![]() ![]() ![]() ![]() ![]() ![]() >Mesaj Sayısı: 1,487
>Açtığı Konu: 453
Level: 32 [ ![]() ]Paylaşım: 1077 / 1197 Üyelik tarihi: Jan 2008
Rep Puani: 645
Rep Derecesi :
![]() ![]() ![]() ![]() ![]() ![]() |
Konu devamı; DO - WHILE DÖNGÜSÜ: Bu döngü while döngüsünün biraz degistirilmis halidir. Do-while döngüsünde karsilastirma islemi, döngünün sonunda gerçeklesir. Bunun sonucu olarak döngünün içine en az bir defa girilmis olur. Yapisi asagidaki gibidir. do cümle while ( kosul ); do'' nun altindaki cümle kismindaki komut satirlari birden fazla olursa diger döngülerde oldugu gibi " { } " içine aliyoruz. Bunu kullanmamiz kodlari okuma da ve ayirma da daha çok isimize yarayacaktir. do { cümle cümle cümle ... } while ( kosul ); Simdi yukarida demek istedigimizi standart kod satiri üzerinde anlatalim. Kodlari yazdigimizda, komut sirasi do''ya geldigi zaman, do'' dan sonraki komutun döngünün basi oldugunu belirtiyor. Digerlerinden farkli ( for, While ) olarak döngüye giris yapiyor, yani hiçbir kontrol yapmadan en az bir defa döngünün içine girmis oluyoruz. While''e geldiginde ise kosulu kontrol ediyor, eger dogru ise döngünün basindaki komuta giderek yeniden komutlari isliyor. Eger kosul kontrolü yanlis ise while''den bir sonra ki komutu veya komutlari isleyip döngüden çikiyor. Simdi bu söylediklerimizi örnek üzerinde gösterelim. //do.cpp // number echoer //do-while döngüsünü kullandik #include <iostream.h> int main () { unsigned long x; do { cout<< "Bir sayi giriniz ( Durdurmak için 0 ) : "; cin>> x; cout<< "Girdiginiz sayi: " << x << "\n"; } while (x != 0); return 0; } FOR DÖNGÜSÜ For döngüsünün çalismasi, döngünün kontrol degiskenine baslangiç degerinin atanmasi ile baslar. Asagida verecegimiz ilk deger atama cümlesinden kastimizda budur. Yani bu kisimda baslangiç tanimlari yapilir. For döngüsünün baslangiç adimidir. Bu kisimda yapilan bir degisken tanimindaki degiskenin ömrü, for döngüsünün sonunda biter. Sonra döngü kosul kismina gelinir ve bu test edilir. Sayet degeri !0, dogru (1) oldugunda döngü içindeki komutlar uygulanir. Arttirma ise for döngüsü isleminin sonunda meydana gelir. for içindeki tüm deyimler meydana geldikten sonra uygulanir. Genel yapisi: for ( ilk deger atamalar, kosul, arttirma) cümle Bunu daha da genellersek, digerlerinde de oldugu gibi cümleler birden fazla oldugunda komut blogu arasina alinacaktir. for ( ilk deger atamalar, kosul, arttirma) { cümle1 cümle2 cümle3 ... } Bu söylediklerimizi bir örnek üzerinde izah edelim. //for.cpp // for döngüsüyle bir örnek. #include <iostream.h> int main () { for (int n=10; n> 0; n--) { cout << n << " -> "; } cout<< "Bitti!"; return 0; } Ben sadece for (int n=10; n>0; n--) bu kismi anlatacagim, diger kisimlar apaçik gözüküyor zaten. For diyip () imizi açtik. Sonra içine ilk basamagimiz olan degisken tanimlamamizi yaptik. Int n=10; Bu bizim yukarida bahsettigimiz ilk deger atamalar kismi. Daha sonra kosulumuzu yazdik. n>0; bunu test ettik ve !0 yani dogru (1) çikti. Sonrada n-- yi yazdik. Genel tanimda yazdigimiz arttirma kismi. Aslinda buna yenileme komutlari desek daha dogru olur. Biz bu örnekte örnegin azaltma yaptik. Neyse umarim bu for örnegini anlamissinizdir. C++ da yapacagimiz çogu örnekte for u kullanacagiz. C++ ''nin en güçlü yanlarindan biriside for döngüsüdür. For döngüsünün basinda yani ilk deger atama kisminda birden çok degisken tanimlayip deger atiyorsak bunlari virgül ( , ) ile bir birinden ayirmaliyiz. Ilk deger atamadan kosul bölümüne geçtigimizde ve kosul bölümünden arttirma ya geçerken noktali virgül ( ; ) kullanmaliyiz. Tabi kullandigimiz bu üç kisim seçimlidir istersek bos birakabiliriz. Fakat, noktali virgüller ( ; ) konulmasi zorunludur. 1.Örnegimiz: //factoriyel_for.cpp //for döngüsüyle faktöriyel hesap. #include <iostream.h> int main() { int fac, sayi; cout<<"Sayiyi giriniz: "; cin>>sayi; fac=1; for (int j=1; j<=sayi; j++) { fac=fac*j; } cout<<"Sonuc: \a"<< fac; return 0; } Bu örnegimiz oldukça basit. Bildigimiz matematiksel faktöriyel islemini C++ kodlari olarak yazdik. (\a yi kullandim bip! demesi için ). 2.Örnegimiz: //carpim_for.cpp // iç içe for döngüsüyle çarpim tablosu #include <iostream.h> main() { cout<<"Çarpim Tablosu! \n"<<endl; int x,y; for (x=1; x<=10; x++) { for (y =1; y<=10; y++) cout<<" "<<x*y; cout<<"\n"; } } Görüldügü gibi ilk for döngüsünde, birinci bilesen olan x i önce 1 e esitledik sonra birer arttirarak 10'' a kadar götürdük. Sonraki for da da aynisini y için yaptik ve bu iki bileseni çarparak ekrana yazdirdik. Son derece basit bir örnek. 3.Örnegimiz: //asal_for.cpp // for , if ve while ile asal sayi bulma #include <iostream.h> int main() { int sayi; cout << "Bir sayi girinizr: "; cin >> sayi; for (int sayac=1; sayac< sayi; sayac++) { int asal, test; test = sayac; asal = 1; while (test--> 2) if ((sayac % test) == 0) asal = 0; if (asal == 1) cout<< sayac << " bir asal sayidir!\n"; } return 0; } BREAK ve EXIT FONKSIYONLARI BREAK Break komutunu, swtich komutundan çikmak için önceki derslerimizde görmüstük. Komutun kendine özgü bir kullanimi daha vardir. Break komutu bir döngünün içinde çalistirilirsa o an o döngü biter. Bir goto gibi islem gördügünü de söyleyebiliriz. Break kullaninca program döngüyü bitirir ve döngünün sonundaki satirdan çalismaya devam eder. Bir örnek verelim. //break.cpp //break komutunu kullandik. #include <iostream.h> main() { for (int x = 1; x <= 10; x++) { if (x == 7) { break; } cout<< x << " "; } } Iste örnegimizde gördügünüz gibi. X 7''ye esit olunca break; döngüyü bitiriyor ve döngüden sonraki satiri çalistirmaya basliyor. EXIT Hayati hata durumlarini ele almak için exit() fonksiyonundan yararlanilir. Bu hatalar main() fonksiyonunu return ile normal olarak sonlandirilmadan önce olusabilir. Exit() fonksiyonu, durum degerini bir tam sayi parametre olarak döndürür. Exit() ile özel bir degerin gönderilmesi bazi islemler yapmasi için kullanilabilir. Örnegin program komut satirinda kullaniliyorsa ve durum degeri bazi hatalari gösteriyorsa, isletim sistemi bunlari mesaj olarak yazabilir. Exit() fonksiyonu programi sonlandirmanin yaninda, tüm bekleyen yazma islemlerini tamamlar ve açik tüm dosyalari kapatir. Exit() fonksiyonunu kullanirken kullanmamiz gerek kütüphaneler ise process.h ve stdlib.h tir. Fonksiyonlar Bundan sonraki bölümlerdeki kullanacagimiz derleyici Borland Turbo C++ 4.5 tir. Fazla zorlanmayacaginizi umut ediyorum. Kolay anladiginiz yerlere lütfen dikkat ediniz. Hata yapma olasiliginiz daha da çok artmaktadir. Yapacaginiz hatalar programin çökmesine, belki de sistemin zarar görmesine sebep olabilir. Lütfen vermis oldugum uyarilara ve tavsiyelere uymaya çalisin. Sizin de tavsiyeniz olursa bana bildiriniz. Haydi kolay gelsin... 1. Fonksiyonlara Giris: Fonksiyonlarin programlama hayatina girmesi ile daha büyük boyutta sistemlerin tasarimi mümkün hale gelmistir. Fonksiyonlar ile alakali derslerimizde, fonksiyonlarin tanimlanmasi ve kullanimi hakkinda bilgi edineceksiniz. Fonksiyonlar konusu size her ne kadar ilk bakista "Fonksiyon" adi altinda bir konu gibi gelse de, aslinda bir alt programdir. Hatta programimizin içine, kodlamamizin daha kolay ve gelistirilebilir hale gelmesini saglayan programciklar da diyebiliriz. Daha önce baska bir programlama dili gördüyseniz (yüksek seviyeli diller), bu konuda fazla zorlanmayacaksinizdir. Diger yüksek seviyeli dillerdeki fonksiyon kullanimina çok benzemektedir. Hiç bilmediginizi farz ederek konuya giris yapalim. Fonksiyon Nedir? Örnegin, y=F(x) fonksiyonu; Bu matematiksel fonksiyon parametre olarak aldinan deger üzerinde bir islem gerçeklestirip, bir sonuç degerini döndürür. Mesela F(x)=x^3+5 seklinde bir fonksiyonumuz olsun, x=2 için F(x)=13 olur. Burada x fonksiyonun parametresi, 13 ise fonksiyonun geri döndürdügü degerdir. Simdi de bu matematiksel ifadeyi kodlarimizla yorumlayalim. Int x; x=F(2,5) //buradan da " int f(2,5) " gibi görebiliriz... Dikkat edersek ikinci satirda, daha önce islemedigimiz bir kod var. Int x, F(2,5) degerine esitlenmistir. Simdi bir fonksiyonun nasil yazildiginin kalibini çikartabiliriz. <Döndürdügü deger> <Fonksiyonun adi> ( <parametre listesi> ) { <ifadeler> } Buradaki parantezlere ve küme isaretlerine dikkat ediniz. Simdi yukarda yazdigimiz kalibi biraz açalim. <Döndürdügü deger> : Fonksiyon her hangi bir tipte deger döndürebilir. Bu bilesen fonksiyonun döndürecegi degerin tipini ifade eder. (örnegin, int, dounle, float v.s v.s ) <Fonksiyonun adi> : Yapmak istedigimiz islemin adidir. Örnegin bir asal sayi fonksiyonu yazacagiz. Burada yazacagimiz fonksiyonun adini belirtiyoruz. Benim size tavsiyem AsalSayi veya asal_sayi seklinde kullanmanizdir. Okunabilirlik açisindan size avantaj saglayacaktir. <parametre listesi> : Fonksiyonun kullanacaga parametrelerin tipleri ile siralanir. Örnegin, FonksiyonAdi(int x, double y) gibi. <ifadeler> : Fonksiyonun kullanacagi tanimlamalar ve kodlardan olusan kisimdir. Nasil biz main() { kodlar } seklinde kullaniyorsak. Bunu da ona benzetebiliriz. Ama main() i bunlarla karistirmayiniz. Simdi bu fonksiyon kalibina uygun bir kod yazalim. Örnegin, Faktoriyel bulma islemini ele alalim. Biz bir sayinin Faktörüyelini nasil bulurduk? n!=n(n-1)(n-2)...1 Yani, 1 den n e kadar olan sayilarin çarpimidir. long Faktoriyel(int n) { return n*Faktoriyel(n-1); } Evet, burada fonksiyonumuzu tanimladik. Sanirim yukaridaki blokla karsilastirinca, ne kadar kolay oldugunu sizde görmüssünüzdür. Simdi bu Faktoriyel fonksiyonumuzu nasil bir programda kullanacagiz? Hemen devamini yazayim. long Faktoriyel(int n) { return n*Faktoriyel(n-1); } void main() { cout<<"5! (Bes Faktoriyel)= "<<Faktoriyel(5); } Iste gördügünüz gibi ne kadar basit degil mi? J Fonksiyonumuzu tanimladik. Sonra programimizda n`e 5 degerini verdik. Faktoriyel fonksiyonu hesaplayip bize söyledi. Biraz da yaygin yapilan hatalardan ve dikkat etmemiz gereken noktalardan bahsedelim. Kodlama yaparken fonksiyon adini belirttigim sekilde yazarsaniz 30-40 sayfalik kodlarda hata bulmaniz ve de fonksiyonlarin yerini belirlemeniz açisindan büyük kolaylik olucaktir. Yukarida verdigimiz x=F(2,5) fonksiyonununu göz önünde tutalim. Görüldügü gibi F(2,5) degeri x e atanmistir. Hiç bir zaman Fonksiyonun aldigi deger sola yazilmaz. Ayrica bir Fonksiyon çagrisi, baska bir fonksiyonun çagrisi olabilir. Örnegin, x=F(a,F(a,5) gibi. Burada F Fonksiyonun iki parametresi vardir a ve F(a,5) dir. Bu durumda öncelikle parametreler hesaplananacagi için F(a,5) in degeri ile a nin degeri F te parametreler olarak kullanilir. Dizilere Giris Diziler, "indisleri olan degiskenler" olarak adlandirilirlar. Diger bir deyisle, birden fazla tek düze veri tipi içeren degiskenlerdir. Diziler birbirine bitisik bellek gözleri kullanilarak olusturulurlar. Bunu biraz daha açarsak: farz edelim ki elimizde üç tane kutu var, birinde yesil kalemler, birinde kirmizi kalemler ve birinde de mavi kalemler olsun. Bu kutucuklari 1,2,3 diye adlandirdigimizi düsünelim. Biz diziler ile numarasini bildigimiz kutucugun içindeki malzemeyi alabilecegiz. Daha dogrusu numarasini vermis oldugumuz kutunun içindeki bilgiyi bilgisayar okuyacaktir. Not: For döngüsü dizi elemanlarina ulasmak için en çok kullanilan yöntemdir. Dizilerin indislerden olustugunu söylemistik. Diger yüksek seviyeli dillerle karsilastirildiginda arasindaki fark ilk elemanin indisi daima sifir (0) olmasidir. for(int i=0; i<boyut; i++) Burada dikkat etmek istedigimiz "int i=0" kismidir. Görüldügü gibi indisin ilk aldigi degeri sifir (0)`dan baslatiyoruz. Bu kismi unutmayiniz. Genellikle yapilan en büyük hatalardan biridir. Bir dizi tanimlayicisi -adi-, dizinin ilk elemaninin adresini tanimlayan adrestir. Bunu söyle izah edelim; elimizde bir dizi var ve ilk elemani karakter ise biz "char DiziAdi[boyut]" seklinde tanimlariz. Tam sayi ise "int DiziAdi[boyut]" seklinde olur. Dikkat edilmesi gereken diger bir konu da: dizi adi hiçbir zaman (=) isaretinin solunda bulunmaz. Bu yukarida söylediklerimi anlamamis olabilirsiniz. Onun için alt kismi okuyup bir daha tekrar etmenizi tavsiye ederim. Dizilerin Tanimlanmasi ve Deger Atama Int a[10]; Seklinde bir diziyi tanimlayabiliriz. Bunu daha genel bir kaliba dökersek. <tip> <dizi adi> [<boyut>]; halini alir. Birde boyutlarinin arttirilmis halini verelim. <tip> <dizi adi> [<boyut1>][<boyut2>][<boyut3>]....[<boyutn>]; n boyutlu dizi. <tip>: Yukarida söylemis oldugumuz "int DiziAdi[boyut]" olayidir. <dizi adi>: Kurallara uygun herhangi bir isim olabilir. Genellikle dizilerinizin amacina uygun isimler kullaniniz. [<boyut>]: Dizinin kaç eleman içerdigini gösterir. 5 elemanli ise [5] seklinde yazariz. Basta " int a[10]; " almistik. Simdi bunu degisik bir formda yazalim const int boyut=10; Int a[boyut]; Önce boyut adinda bir sabiti tanimladik ve deger atadik sonrada bunu dizi içine çagirdik. Dizilere Deger atama: Bu yöntemleri madde madde verelim, 1. Duragan ve global (erisilen) dizilerde yaratildiklari anda içerik otomatik olarak belirlenebilir. Programin taniminda erisilen tüm degiskenler, otomatik olarak sifir yapilir. 2. Duyuru sirasinda sabit degerler belirtilerek belirlenebilir. 3. Programin çalismasi sirasinda indisler kullanilarak her elemana tek tek veri kopyalanabilir. 1. maddenin örnegi #include <iostream.h> const int boyut=5; int GlobalDizi[boyut]; main() { //"satatic" yerel degiskende tanimlanmasina ragmen tüm program boyunca //geçerlidir. Ancak sadece tanimlandigi fonksiyon tarafindan erisilebilir. static int DuraganDizi[boyut]; for(int i=0; i<boyut;i++) cout<<GlobalDizi; return 0; } Programin çiktisinada göreceginiz gibi, dizi aratilirken indislere ait eleman bloklari temizlenmis ve sifir degerlerini almistir. Burada bir konuya daha dikkat çekmek istiyorum. Çok yaptigimiz hatalardan biri olarak da, dizi duyurusunu yaparken belirttigimiz degerden fazla sayida deger girmemizdir. int DiziAdi[5]={1,8,9,5,4,6};Görmüs oldugunuz gibi bes tane dedik ama alti tane yazdik. !!! hata !!!. Bu tür hatalar için elimizde kullanabilecegimiz bir kalip var. char DiskOkunmuyor[ ] = "Disk okunmuyor"; char DosyaYok[ ]= "Dosya Yok"; Bunu yaptigimizda derleyici, tüm degerleri içerebilecek en büyük diziyi olusturur. Dizi Boylarinin Dinamik Hesaplanmasi "sizeof()" sizeof() fonksiyonu, nesne için bellekte gerekli olan byte`larin sayisini belirtir. Sizeof() fonksiyonu dizilerde kullanilabilir. #include <iostream.h> void main() { int a[5]; float b[10]; cout<<"dizinin boyutu: "<<sizeof(a)<<''\n''; cout<<"dizinin boyutu: "<<sizeof(b); } Evet burda da görmüs oldugumuz gibi dizinin bellekte kaplayacagi byte`lari hesapladi. Birde bu konuyla beraber "&" operatörünün bir dizi bile olsa degiskene nasil uygulandigini görebiliriz. #include <iostream.h> void main() { int a[10]; cout<<"sizeof(int) is"<<sizeof(int)<<endl; for(int c=0; c<10; c++) cout<<"&a["<<c<<"]="<<&a[c]<<endl; } Programi derledikten sonra "sizeof(int) is 2 ya da sizeof(int) is 4" diyecektir. Bu degisiklik int in mikroislemcilere bagli olarak 2 veya 4 byte olabilmesinden kaynaklanmaktadir. Diziler ve Sözcükler (strings) C++ da sözcükler için farkli bir tip yoktur. Sözcükler ile ilgili islemler diziler yardimi ile kolaylikla yapilabilir. Dikkat edilmesi gereken bir kural vardir. Sözcüklerin (strings) son elemanlari "\0" degerini alir (null terminator). Burdan da anlayacagimiz gibi son karakter bos dizgiyi belirtiyorsa stringtir. Suna da dikkat edilmelidir ki string sabitlerinin sonuna "\0" koymamiza gerek yoktur. Derleyici bunu otomatik olarak yapacaktir. Char sozcuk[7]="Deneme"; Char sozcuk[7]=''D'', ''e'', ''n'', ''e'', ''m'', ''e'', ''\0''}; Bu dizilerin içerikleri tamamen aynidir. Hazir söz gelmisken suna da deginelim. ''\n'', ''\t'', ''\0'' v.s, bunlar birer karakter olarak okunur. Ben önceleri iki diye okurdum #include <stdlib.h> #include <iostream> #include <string> using namespace std; int main() { string Cevap = ""; cout << "Hazirmisin?"; cin >> Cevap; if( ( Cevap == "evet" ) || ( Cevap == "Evet" )) { cout << "Ee Tamam... ne gec ti eline? " << endl; } else { cout << "Zorlamaya devam et!" << endl; } cout << "Hazirmisin? " << endl; cin >> Cevap; if( ( Cevap[0] == ''e'' ) || ( Cevap[0] == ''E'' ) ) { cout << "Ee Tamam... ne geçti eline?" <<endl; } else { cout << "Zorlamaya devam et!" << endl; } system("pause"); return 0; } Bu, sanirim bu konudaki en zor örnegimiz. Simdi örnek üzerinde biraz konuyu konusmaya devam edelim. Zaten diger if, else bloklarindan ve cout, cin gibi komutlardan bahsetmeyecegim. string Cevap = ""; bir sabitimizle isleme basladik. if( ( Cevap[0] == ''e'' ) || ( Cevap[0] == ''E'' ) ) burasi sanirim tanidik geldi Evet simdi burda Cevap[1] i çagirmis olsaydik ''v'' veya ''V'' degerlerini alicaktik. Tabi burada index degerinin yani dizideki ilk degerin 0 ile basladigini bir daha gördük. Simdi bu örnekle alakali olarak da Diziler ve Fonksiyonlar konusuna geçelim.... Karakter Katarlari Fonksiyonlari ve Karakter Dizileri Iste buraya biraz dikkat, kafaniz gerçekten karisabilir. Daha dogrusu hangisi hangisiydi diye ugrasir durursunuz strlen() Bu fonksiyon bir karakter dizisinin uzunlugunu verir ve "string.h" kitapliginda tanimlidir. Strlen() fonksiyonu, sözcükler (strings) bölümünde bahsettigimiz string ifadeleri okumak için kullanilir. Fakat sondaki "nul terminator" diger sekliyle ''\0'' degerini okumaz. Örnegimizde de oldugu gibi "Deneme" ve ''d'' ''e'' ''n'' ''e'' ''m'' ''e'' sözcükler kisminda ki biz buna 7 karakter demistik, "null" ile birliktedir ama strlen() bunu bize 6 diye okuyacaktir. int boy = strlen(h); for (int i = 0; i<=boy; i++) y = h ; strcpy() Bu fonksiyonda sözcük kopyalamaya yarar ve "string.h" kitapligindadir. #include <iostream.h> #include <string.h> #define OTUZ 30 void main(void) { char Dosya1[OTUZ]="C:\\belgelerim\\deneme.txt", Dosya2[OTUZ]; strcpy(Dosya2, Dosya1); cout<<Dosya2<<endl; cout<<"\n ikinci dosyayi gir: "; cin>>Dosya1; strcpy(Dosya2, Dosya1); cout<<"\n"<<Dosya2<<"\n"; } strcat() strcat() fonksiyonu iki karakter katarini bir birine ekler. strcmp() Iki sözcügün (iki karakter katarinin) ayni olup olmadigini kontrol etmek için kullanilir. Bu fonksiyon büyük/küçük harf duyarli degildir. atoi() Bazen sayilari karakter dizisi olarak okumamiz gerekebilir. Ancak esas, bu sayilarin sayi degerlerine gereksinmemiz vardir. Atoi fonksiyon, bir karakter dizisini alir ve onu sayiya çevirir. Örnegin; "123456" dizisini alir 123456 sayisina döndürür. strstr() Bunu bir örnekle anlatayim: "C++ dersleri" gibi bir sözcügümüz var, strstr() fonksiyonu ile bu sözcük içinde "d" harfinin varligini sorgulayabiliriz. Isaretçilere Giris Isaretçiler (Pointers) ve bundan önce görmüs oldugumuz diziler (Arrays) ilerde yapacagimiz uygulamalarda kullanimina kesin ihtiyaç duyacagimiz basliklardir. Bunlar bize dinamik bellek kullanimini saglarlar. Dinamik bellek kullanimindan bahsedecek olursak, bellegimizin kutucuklardan olustugunu hayal edin. 100 kutucuklu bir bellegimiz var. Bu kutucuklarin her birinin bir adresi vardir ve biz de bu adresler yolu ile kutucuklara erisiriz. Iste isaretçiler bu erisimi sagliyor. Bu konuya çalisirken, anlamanin gayet kolay oldugunu göreceksiniz. Fakat ben sizi uyarayim, en kolay konular en çok hata yapilanlardir. Isaretçilerde yapilan hatalar programin hatta sistemin çökmesine sebep olabilir, ayni zamanda yapilan hatalari kolay kolay bulamayabilirsiniz. Büyük projelerde bu sizi bayagi sikintiya sokacaktir. Onun için isaretçiler konusunda, kullanim teknigi hakkinda size sik sik tavsiyelerde bulunacagim. Isaretçilerin Tanimlanmasi ve Deger Atanmasi Bir isaretçi tipi, hangi tipe isaret ettigini belirten ve birer adres degeri içeren verilere sahiptir. Bir isaretçi degisken bildirimi, açik olarak hangi tip veriyi kullanacagini bildirerek baslar. Derleyicimizde * isareti ile isaretçi degiskeni tanimladigimizi anlar. <tip> *<isaretçi adi>; Seklinde yazilir. Örnegin, int *IsaretciAdi; Simdi de ayni satirda birden fazla isaretçi tanimlayalim. Int *is1, *is2, *is3; Seklinde tanimlayabiliriz. Benim size tavsiye ettigim budur. Fakat farkli bir yol olarak da (Int *) is1, is2, is3; seklinde de yazilabiliriz. Burda dikkat etmemiz gereken olay ise, int tipinde isaretçileri tanimlarken herhangi bir degiskende tanimlarsak (int *) seklinde tek satirda yapmamiz hatalidir. (Int *) is1, is2, is3, x=4; //hata int *is1, *is2, *is3, x=4; //dogru Sanirim ne demek istedigimi anladiniz. Daha önce görmüs oldugumuz "&" adres operatörünü hatirlayalim, kendisisinden sonra gelen ifadenin adresini gösterir. Int x; Int *is1=&x; x i tanimladik, sonra is1 isaretimize x in adresini atadik. Kisaca is1 in gösterdigi adresteki deger diye biliriz #include <iostream.h> #include <string.h> int main(void) { char *is1="deneme"; int index; for(index=(strlen(is1)-1); index>=0; index--) cout<<is1[index]<<endl; cout<<"\n"<<is1; return 0; } Programin çiktisi --------- e m e n e d deneme --------- Isaretçi Islemleri ve Dinamik Bellek Isaretçilere daha önce görmüs oldugumuz artirma (++), azalatma (--), çikarma (-), toplama (+) islemlerini uygulayabilirsiniz. Bunlarin yaninda iliskisel operatörleri de ( <=, =, !=, >= ) kullanmaniz mümkündür. Iliskisel operatörlerin sadece ayni tip isaretçiler üzerinde uygulanacagini unutmayiniz. Bir dizinin boyutu degisken olabilir, daha dorusu bir program içinde degiskenler ve isaretçiler kullanilarak diziler dinamik bellek yerlesimi ile yapilabilir. C++ da dinamik belles islemleri new ve delete komutlari ile gerçeklestirilir. Genel tanimimiz: new <tür> [<[uzunluk]>] new int new char new double [10] new float[n] new char[strlen(s) + 1] new komutu ile yer tahsis etme islemi yapmaktayiz. new int ->1 int''lik yer tahsis edilmistir. Simdide tahsis ettigimiz yerin serbest birakilisini ele alalim. Bu sirada da delete komutu devreye giriyor. Daha dogrusu delete operatöürü new operatörüyle tahsis edilmis olan bloklari serbest birakmak için kullanilir. Genel tanimimiz: Delete[ ] <isaretçiadi>; Eger yer ayirma islemi tek parça olarak yapilmissa (köseli parantez kullanilmadan yapilmissa) silme islemi de köseli parantez kullanilmadan yapilmalidir. Bir de suna dikkat edelim Delete x+1; //hatalidir Delete (x+1); //dogrudur kullanilacaktir. Simdi bu söylediklerimizi asagidaki örnek üstünde uygulayalim. //dinamik.cpp //dinamik bellek kavrami #include <iostream.h> struct tarih { //struck u daha görmedigimiz int ay; //icin su an buraya egilmeyin. int gun; int yil; }; void main() { int i, *is1, *is2; // i bir sabit ve *is1, *is2 isaretcilerimiz is1 = &i; *is1 = 77; is2 = new int; *is2 = 178; cout << "Degerler "<<i<<" "<<*is1<<" "<<*is2<<"\n"; is1 = new int; is2 = is1; *is1 = 95454; cout << "Degerler "<<i<<" "<<*is1<<" "<<*is2<<"\n"; delete is1; float *float_is1, *float_is2 = new float; float_is1 = new float; *float_is2 = 3.14159; *float_is1 = 2.4 * (*float_is2); delete float_is2; delete float_is1; tarih *tarih_is; tarih_is = new tarih; tarih_is->ay = 10; tarih_is->gun = 18; tarih_is->yil = 1938; cout<<tarih_is->ay<<"/"<<tarih_is->gun<<"/"<<tarih_is->yil<<"\n"; delete tarih_is; char *c_is; c_is = new char[37]; delete [] c_is; c_is = new char[sizeof(tarih) + 133]; delete [] c_is; } Isaretçiler ve Diziler C++ da Isaretçiler ve diziler arasinda çok yakin bir iliski vardir. Bir dizinin ismi, dizideki ilk elemanin adresini içeren sabit bir degiskendi. Bundan diziler bölümünde bahsetmistik. Simdi isaretçiler ile dizileri iliskilendirirsek, dizilerin adlarinin birer isaretçiden olustugunu görmüs olacagiz. *(a+i) a Bu sayede bu iki ifadenin ayni oldugunu söylemis oluruz. Bir de çok boyutlu dizilere uyarlarsak, *(*(a+i)+j) a[j] seklini alir. Int a[100]; Int *is1=&a[100]; Örnegimiz; //isaretçi ve diziler #include <iostream.h> void KareAl(int *sayi) { *sayi *= *sayi; } void KareAlDizi(int *is1) { for (int i=0; i<10; i++) is1 *= is1; } int main() { int x = 50; int intis1[10]; KareAl(&x); cout<<"x = "<<x<<endl; KareAlDizi(intis1); cout<<intis1; return 0; } 5. Isaretçiler ve Fonksiyonlar Isaretçiler ve diziler bölümünde görmüs oldugumuz örnektede oldugu gibi. Biz fonksiyonun adresine onun adi ile ulasiriz. Kareal(x); gibi. Simdi bir fonksiyonu isaret eden bir isaretçiyi ele alalim. Int KareAl( ); fonksiyonumuz olsun. Int (*KareAl)( ); Bu da Fonksiyonu isaret eden bir isaretçimiz oldu. Biz genellikle isaret edilen fonksiyonlari menülerde ve siralamalarda kullaniriz. Asagida bir siralama örnegi verilmistir. //is_ve_fonk.cpp //isaretçiler ve fonksiyonlar #include <stdlib.h> #include <iostream> using namespace std; void YatayYaz(char*); void DikeyYaz(char*); void ismiYaz(char*, void (*Yaz)(char*)); int main() { char isim[] = "Deneme"; ismiYaz(isim,DikeyYaz); ismiYaz(isim,YatayYaz); system("pause"); return 0; } void YatayYaz(char *isim) { if(!isim) return; cout << isim; } void DikeyYaz(char *isim) { if(!isim) return; int i = 0; while(isim != NULL) { cout << isim[i++]; cout << endl; } } void ismiYaz(char *isim, void (*Yaz)(char*)) { Yaz(isim); cout << endl; } Bi teşekkür yeter (verildiyse özür dilerim) |
|||||||||
|
||||||||||
|
|
![]() |
| Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir) | |
| Seçenekler | Arama |
| Stil | |
|
|