|
|
BİLGİSAYAR GENEL EĞİTİM BÖLÜMÜ Bilgisayar hakkında merak ettiğiniz her şeyi ve püf noktaları burada bulabilirsiniz |
|
Seçenekler | Stil |
|
25.09.09, 11:40 | #1 |
Diziler ve Fonksiyonlar
5. Diziler ve Fonksiyonlar Öncelikle dizilerin fonksiyonlara gönderilmesi ile başlayalım. Dizilerde değişken önüne adres operatörünün gelmesine gerek yoktur. Nedeni ise dizi isminin zaten bir adres olmasıdır. İnt dizi[10]; bir dizimiz olsun biz bunu diziye bir değer olarak göndereceksek, Fonksiyon(dizi, 10); olarak yaparız. Bir diziyi parametre olarak alacaksak bir fonksiyon, o da void fonksiyon( int dizi[], int 10) şeklinde olur. ww.uydulife.tv
|
|
25.09.09, 11:40 | #2 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
Karakter Katarları Fonksiyonları ve Karakter Dizileri
6. Karakter Katarları Fonksiyonları ve Karakter Dizileri İşte buraya biraz dikkat, kafanız gerçekten karışabilir. Daha doğrusu hangisi hangisiydi diye uğraşır durursunuz[IMG]http://www.************/images/smilies/smile.gif[/IMG] strlen() Bu fonksiyon bir karakter dizisinin uzunluğunu verir ve "string.h" kitaplığında tanımlıdır. Strlen() fonksiyonu, sözcükler (strings) bölümünde bahsettiğimiz string ifadeleri okumak için kullanılır. Fakat sondaki "nul terminator" diğer şekliyle '\0' değerini okumaz. Örneğimizde de olduğu gibi "Deneme" ve 'd' 'e' 'n' 'e' 'm' 'e' sözcükler kısmında ki biz buna 7 karakter demiştik, "null" ile birliktedir ama strlen() bunu bize 6 diye okuyacaktır. int boy = strlen(h); for (int i = 0; i<=boy; i++) y[i] = h[i] ; strcpy() Bu fonksiyonda sözcük kopyalamaya yarar ve "string.h" kitaplığındadır. #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 katarını bir birine ekler. strcmp() İki sözcüğün (iki karakter katarının) aynı olup olmadığını kontrol etmek için kullanılır. Bu fonksiyon büyük/küçük harf duyarlı değildir. atoi() Bazen sayıları karakter dizisi olarak okumamız gerekebilir. Ancak esas, bu sayıların sayı değerlerine gereksinmemiz vardır. Atoi fonksiyon, bir karakter dizisini alır ve onu sayıya çevirir. Örneğin; "123456" dizisini alır 123456 sayısına döndürür. strstr() Bunu bir örnekle anlatayım: "C++ dersleri" gibi bir sözcüğümüz var, strstr() fonksiyonu ile bu sözcük içinde "d" harfinin varlığını sorgulayabiliriz. ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #3 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
İşaretçilere Giriş
1. İşaretçilere Giriş İşaretçiler (Pointers) ve bundan önce görmüş olduğumuz diziler (Arrays) ilerde yapacağımız uygulamalarda kullanımına kesin ihtiyaç duyacağımız başlıklardır. Bunlar bize dinamik bellek kullanımını sağlarlar. Dinamik bellek kullanımından bahsedecek olursak, belleğimizin kutucuklardan oluştuğunu hayal edin. 100 kutucuklu bir belleğimiz var. Bu kutucukların her birinin bir adresi vardır ve biz de bu adresler yolu ile kutucuklara erişiriz. İşte işaretçiler bu erişimi sağlıyor. Bu konuya çalışırken, anlamanın gayet kolay olduğunu göreceksiniz. Fakat ben sizi uyarayım, en kolay konular en çok hata yapılanlardır. İşaretçilerde yapılan hatalar programın hatta sistemin çökmesine sebep olabilir, aynı zamanda yapılan hataları kolay kolay bulamayabilirsiniz. Büyük projelerde bu sizi bayağı sıkıntıya sokacaktır. Onun için işaretçiler konusunda, kullanım tekniği hakkında size sık sık tavsiyelerde bulunacağım. İşaretçilerin Tanımlanması ve Değer Atanması Bir işaretçi tipi, hangi tipe işaret ettiğini belirten ve birer adres değeri içeren verilere sahiptir. Bir işaretçi değişken bildirimi, açık olarak hangi tip veriyi kullanacağını bildirerek başlar. Derleyicimizde * işareti ile işaretçi değişkeni tanımladığımızı anlar. <tip> *<işaretçi adı>; Şeklinde yazılır. Örneğin, int *İsaretciAdi; Şimdi de aynı satırda birden fazla işaretçi tanımlayalım. İnt *is1, *is2, *is3; Şeklinde tanımlayabiliriz. Benim size tavsiye ettiğim budur. Fakat farklı bir yol olarak da (İnt *) is1, is2, is3; şeklinde de yazılabiliriz. Burda dikkat etmemiz gereken olay ise, int tipinde işaretçileri tanımlarken herhangi bir değişkende tanımlarsak (int *) şeklinde tek satırda yapmamız hatalıdır. (İnt *) is1, is2, is3, x=4; //hata int *is1, *is2, *is3, x=4; //doğru Sanırım ne demek istediğimi anladınız[IMG]http://www.************/images/smilies/smile.gif[/IMG]. Daha önce görmüş olduğumuz "&" adres operatörünü hatırlayalım, kendisisinden sonra gelen ifadenin adresini gösterir. İnt x; İnt *is1=&x; x i tanımladık, sonra is1 işaretimize x in adresini atadık. Kısaca is1 in gösterdiği adresteki değer diye biliriz[IMG]http://www.************/images/smilies/smile.gif[/IMG] #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; } Programın çıktısı --------- e m e n e d deneme --------- Burada bir işaretçi değişkenine değer atamayı kullandık, aynı zamanda dizilerde gördüğümüz strlen() fonksiyonun örneğini de yapmış olduk. ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #4 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
İşaretçi İşlemleri ve Dinamik Bellek
2. İşaretçi İşlemleri ve Dinamik Bellek İşaretçilere daha önce görmüş olduğumuz artırma (++), azalatma (--), çıkarma (-), toplama (+) işlemlerini uygulayabilirsiniz. Bunların yanında ilişkisel operatörleri de ( <=, =, !=, >= ) kullanmanız mümkündür. İlişkisel operatörlerin sadece aynı tip işaretçiler üzerinde uygulanacağını unutmayınız. Bir dizinin boyutu değişken olabilir, daha dorusu bir program içinde değişkenler ve işaretçiler kullanılarak diziler dinamik bellek yerleşimi ile yapılabilir. C++ da dinamik belleş işlemleri new ve delete komutları ile gerçekleştirilir. Genel tanımımız: 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 işlemi yapmaktayız. new int ->1 int'lik yer tahsis edilmiştir. Şimdide tahsis ettiğimiz yerin serbest bırakılışını ele alalım. Bu sırada da delete komutu devreye giriyor. Daha doğrusu delete operatöürü new operatörüyle tahsis edilmiş olan blokları serbest bırakmak için kullanılır. Genel tanımımız: Delete[ ] <işaretçiadı>; Eğer yer ayırma işlemi tek parça olarak yapılmışsa (köşeli parantez kullanılmadan yapılmışsa) silme işlemi de köşeli parantez kullanılmadan yapılmalıdır. Bir de şuna dikkat edelim Delete x+1; //hatalıdır Delete (x+1); //doğrudur kullanılacaktır. Şimdi bu söylediklerimizi aşağıdaki örnek üstünde uygulayalım. //dinamik.cpp //dinamik bellek kavramı #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 << "Değerler "<<i<<" "<<*is1<<" "<<*is2<<"\n"; is1 = new int; is2 = is1; *is1 = 95454; cout << "Değerler "<<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; } ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #5 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
Void İşarerçiler
3. Void İşaretçiler C++ da tip tanımlamaları fazla güçlü olmadığından bu sorunu işaretçileri void * tipi ile tanımlayarak hallediyoruz. Void tipinde bir işaretçi değişken tipi ile, adresin bulunduğu, ancak henüz tipinin belirlenmediği anlaşılmalıdır. Void i kullanırken dikkat etmemiz gereken kurallardan biri karşımıza bazı kısıtlamalar getirmesidir. Bunlardan söz edecek olursak; void işaretçilerde adres aritmetiği işlemlerini derleyici hata olarak gösterecektir. void *is1; İnt *is2; /// İs1=is2; İs1++; Burada dikkat etmemiz gereken is1 yani void ile tanımladığımız işaretçi üzerinde aritmetik işlem yapılmayacağıdır! ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #6 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
İşaretçiler ve Diziler
4. İşaretçiler ve Diziler C++ da İşaretçiler ve diziler arasında çok yakın bir ilişki vardır. Bir dizinin ismi, dizideki ilk elemanın adresini içeren sabit bir değişkendi. Bundan diziler bölümünde bahsetmiştik. Şimdi işaretçiler ile dizileri ilişkilendirirsek, dizilerin adlarının birer işaretçiden oluştuğunu görmüş olacağız. *(a+i) a[i] Bu sayede bu iki ifadenin aynı olduğunu söylemiş oluruz. Bir de çok boyutlu dizilere uyarlarsak, *(*(a+i)+j) a[i][j] şeklini alır. İnt a[100]; İnt *is1=&a[100]; Örneğimiz; //işaretçi ve diziler #include <iostream.h> void KareAl(int *sayi) { *sayi *= *sayi; } void KareAlDizi(int *is1) { for (int i=0; i<10; i++) is1[i] *= is1[i]; } int main() { int x = 50; int intis1[10]; KareAl(&x); cout<<"x = "<<x<<endl; KareAlDizi(intis1); cout<<intis1; return 0; } Örneğimizi adım adım takip edersek: void KareAl(int *sayi) burda sayi adında bir işaretçiyi kullanarak bir fonsiyon tanımlanıyor. Fonksiyonumuzun adı kare alma. İkinci fonksiyonda ise is1 isimli bir işaretçi ile parametresini giriyoruz, fakat işlem diziler üstünde sürüyor. Demiştik ya, dizilerin adları da birer işaretçiden oluşur. Sonraki main() fonksiyonumuzda da, x sabit değişkenimizi ve int tipindeki intis1[ ] dizimizi tanımlıyoruz. Referans yolu ile fonksiyonumuzu sabit değeri gönderiyoruz. Bir diğer işlemle de işaretçi parametresine sahip fonksiyonumuza bir dizi gönderiyoruz. Sanırım gayet basit oldu[IMG]http://www.************/images/smilies/smile.gif[/IMG]. Bu sayede fonksiyonları da konuya ilişkilendirmiş olduk. Yoruldum... Çay yapıp geliyorum[IMG]http://www.************/images/smilies/smile.gif[/IMG] ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #7 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
İşaretçiler ve Fonksiyonlar
5. İşaretçiler ve Fonksiyonlar İşaretçiler ve diziler bölümünde görmüş olduğumuz örnektede olduğu gibi. Biz fonksiyonun adresine onun adı ile ulaşırız. Kareal(x); gibi. Şimdi bir fonksiyonu işaret eden bir işaretçiyi ele alalım. İnt KareAl( ); fonksiyonumuz olsun. İnt (*KareAl)( ); Bu da Fonksiyonu işaret eden bir işaretçimiz oldu. Biz genellikle işaret edilen fonksiyonları menülerde ve sıralamalarda kullanırız. Aşağıda bir sıralama örneği verilmiştir. //is_ve_fonk.cpp //işaretç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[i] != NULL) { cout << isim[i++]; cout << endl; } } void ismiYaz(char *isim, void (*Yaz)(char*)) { Yaz(isim); cout << endl; } ww.uydulife.tv
|
|||||||||
25.09.09, 11:40 | #8 | |||||||||
Üye Numarası: 109
Üyelik tarihi: 20.08.2008
Yaşım: 42
Mesajlar: 5.693
Konular: 4141
Rep Gücü : 32
Rep Puanı : 1000
Rep Seviyesi :
Level: 53 [] Paylaşım: 132 / 1324 |
Fonksiyonlara işaretçi Parametresi
6. Fonksiyonlara işaretçi Parametresi İşaretçiler ve diziler bölümünde yapmış olduğumuz örnekte, void KareAl(int *sayi); şeklinde bir fonksiyon tanımladık. Burada *sayi adında bir işaretçiyi parametre olarak fonksiyona göndermiş olduk. Zaten kullanım şeklini de örnekte olduğu gibi KareAl(&x); x in adresini fonksiyona yazmamız yeterli oldu. Bu sayede ek bir işaretçi tanımlamamıza gerek kalmadı. Farklı bir örnek daha verecek olursak: #include <stdlib.h> #include <iostream> using namespace std; void artan(int is1); void artan2(int *is1); void artan(int is1) { is1 += 5; } void artan2(int *is1) { *is1 += 5; } int main() { int i = 0; artan(i); cout << "i simdi: " << i << endl; artan2(&i); cout << "i simdi: " << i << endl; system("pause"); return 0; } Görülmüş olduğu gibi artan2 adındaki fonkyionumuza int tipindeki *is1 işaretçisini parametre olarak verdik ve main() artan2(&i); şeklinde çağrımızı yaptık. !!!En zor kısmı atlattık sanırım. Lütfen geri dönüp örnekleri yeniden gözden geçirirseniz sizin için yararlı olacaktır. Bir program yazana kadar sizi bırakmayacağım[IMG]http://www.************/images/smilies/smile.gif[/IMG] !!! ww.uydulife.tv
|
|||||||||
18.11.12, 01:39 | #9 | |||||||||
V.İ.P. ÖZEL ÜYE
Üye Numarası: 867
Üyelik tarihi: 12.06.2009
Mesajlar: 23
Konular: 13
Rep Gücü : 0
Rep Puanı : 10
Rep Seviyesi :
Level: 3 [] Paylaşım: 0 / 63 |
Sağolasın, böyle ufaktan okuyup uygulamak lazım. Heves de arttırıyor böyle böyle.
ww.uydulife.tv
|
|||||||||
Bookmarks |
Etiketler |
c++ öğrenmeye başlıyoruz |
Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir) | |
|
|