C Dökümanları - Papatyam Forum

Papatyam Forum

Go Back   Papatyam Forum > ..::.BİLGİSAYAR & TEKNOLOJİ.::. > Programlama > C#

Yeni Konu aç  Cevapla
 
Seçenekler
Alt 20 January 2009, 15:48   Mesaj No:1

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart C Dökümanları

C Dökümanları

Temel C dokumanları 1 (Giriş)

Evet C derslerinin ilk dokumanı. Öncelikle C programları yazabilmek için gerekli aletleri temin edelim. Bir adet notpad ve bir C compiler (yada bir linux makine, shell). Pek de bir şey gerekmiyormuş ne güzel. Compiler olarak miracle C, borland yada visual C compilerı öneririm. Compilerın nasıl kullanıldığına sonra değineceğiz.

Çok teorik girişler yapılabilir ama ben pratikten girecem biraz. Direk bir program yazıyorum ve üzerinde temel açıklamaları yapıyorum. Kod yazmaya başlamadan önce belirteyim. C de bir satırda // işaretlerinden sonra yazılanlar kod olarak kale alınmaz. Dokumanlarımızda kodları acıklama amaçlı olarak // işaretleri kullanılacaktır:

#include<stdio.h> // 1.satır
main() // 2.satır
{ // 3. satır
printf("Holey ilk programimi compile ettim" // 4. satır
return 0; // 5. satır
} // 6. satır


Bu programı compile eder çalıştırırsanız, “Holey ilk programımı compile ettim” diye bir yazı verecek ekrana. Simdi bu kodları inceleyelim mantığını öğrenelim. 1. satırda #include<stdio.h> yazıyor. Bunu her programımızın başına yazacaz. Bu komut, compiler'a programımızda kullanacağımız library (kutuphane) dosyalarını gösterir. stdio.h bir kütüphane dosyasıdır. İçinde girdi ve çıktıları yöneten fonksiyonların komut bilgisini tutar."stdio" nun acılımı "standart input output" dur standartın üc harfi, input ve outputun ilk harfleri: stdio.h

sonundaki .h da dosyanın uzantısıdır.C de kütüphane dosyaları hep .h uzantılı olur.Her compiler'la beraber lib klasoru altında hazır vardır bu kütüphane dosyaları. input girdi output da cıktı anlamına gelir. Program ekranımıza bir yazı veriyorsa bu bir outputtur. Program çalışınca durup bir girdi bekliyorsa bu bir inputtur. 4.satırda yazdığımız printf bir output komutudur. Ekrana bilgi verir.

Eğer biz programın başına #include<stdio.h> yazmazsak compiler bu output komutunu tanımaz. Çünkü printf in kullanımı stdio.h dosyasının içinde yazılıdır. ilk satırın mantığı anlaşılmıştır artık sanırım.

Gelelim 2.satıra burada yazan main() bir fonksiyondur. Programımızın ana fonksiyonu. Tüm programın yapacağı iş bu fonksiyonun içinde anlatılır compiler'a. C de fonksiyonlar ismi, yanında açılan parantezler, ve içindekileri belirten { } kısımlarından oluşur.

main()
{

}


seklinde. Burdaki { } lar fonksiyonun içeriğini ve sınırlarını belirler. main fonksiyonun ismidir.main ismi compiler tarafından ana kısım olarak tanınır. Her programda bulunması şarttır. () parantezler ise fonksiyonun bi girdi alıp almadığını gösterir. Şimdilik biz main fonksiyonunu bir girdi almadan kullanıyoruz bu yüzden parantezlerin içi boş. Fonksiyonları sonraki dokümanlarda geniş bir şekilde anlatacam.

4.satırda printf komutunun kullanımı görülmektedir.input ve output komutları sonra detaylı bir şekilde anlatılacak.

5.satırda return fonksiyonun çıktısının ne olacağını belirler. Biz ana fonksiyonumuzun bir çıktı vermesini şu an istemiyoruz.

Zaten printf komutu ile çıktımızı aldık. return 0; diyerek compiler'a main fonksiyonumun baska çıktısı yoktur diyoruz. Bu satırı yazmak da şart değildir. Ama bazı compiler'lar sorun çıkarabilir diye ekledik bu komutu da.

Dikkat edilmesi gereken bir şey de C de her komuttan sonra noktalı virgül ( kullanılmasıdır.Bu, cümlelerden sonra nokta koymak gibidir.

Gelelim compile etme işine. Programımızı bir notpad de yazdıktan sonra bunu mesela "ilkprogramim.c" seklinde uzantısı .c olacak şekilde kaydediyoruz. Sonra shell kullanıyorsak "gcc ilkprogramım.c" komutu ile compile ediyoruz. Bulunduğumuz klasörde a.out diye bir çalıştırılabilir dosya oluşacaktır. ./a.out yazarsanız program çalışır. exploit derleyenler bilirler Eğer windows'da bir compiler kullanıyorsak. Compiler'ın bulunduğu klasöre ilkprogramim.c yi atacaz ve compiler'ımızın kullanımına göre mesela benim kullandığım borland için "bcc32 ilkprogramım.c" yazacaz komut isteminde.(ama komut isteminde compilerın bulundugu klasore gelmemiz lazım once). Sonra ilkprogramım.obj diye bir dosya oluşturacak compiler. Son adım olarak "make ilkprogramım.obj" yazarsak ilkprogramım.exe diye bir çalıştırılabilir dosya oluşacak. Artık ilkprogramım.exe yazarak programı calıstırabiliriz.

İlk ders bu kadar. Her dokümandan sonra bir pratik yapma adına bir ödev veriyorum. Ödev: bir C compiler yada gcc komutu calışan bir shell bulun. Yazdığım programı compile edip çalıştırın.

Moderatöre Bildir Logged



agasarli_3461

Ziyaretçi
Ynt: C Dökümanları
« Yanıtla #1 : Eylül 09, 2007, 10:20:37 ÖS » Alıntı Değiştir Sil Konuyu böl

--------------------------------------------------------------------------------
Temel C Dokümanları 2 (Değişkenler ve Operatörler)

Bundan once degiskenleri, degisken tanıtmayı, operatorleri, if, switch, while yapılarını scanf ve printf in kullanımlarını gorduk. Buraya kadar isledigimiz seylerde komutların kullanımlarına dikkat etmenizi istiyorum. Cunku kullanım sekilleri cok onemlidir. Virguller noktalı virguller parantezler { } ler, " " ler nerelerde nasıl kullanılıyor bunları bir daha tekrar edip iyice oğrenin. Çünkü bunlar yanlış kullanılırsa kodları compile edemeyiz. Bir de compile hatalarını anlamaya çalısın. Bunlar iyice anlanırsa program yazmada fazla sorun yaşamazsınız...

Bir de gecen dersin odevinin cevabını verelim başlamadan once

3. odevin cevabı:

#include<stdio.h>
main()
{
int x,i;

scanf("%d",&x);

i=2;
while(i<x)
{
if(x%i==0)
{
printf("%d asal degil",x);
exit(-1);
}
i++;
}

printf("%d asal",x);

return 0;
}


pek uzun bir program değil aslında dimi Şimdi bu programı biraz anlatayım...

İlk once iki degisken belirliyoruz: i ve x . x girdiyi tutucak. i de while in icinde 2 den baslatılarak surekli x e bolunecek ve her seferinde bir arttırılıcak. Ta ki x den bir kucuk olana kadar. While in icinde bir if var. Bu if “x” i “i” ye boldugunde kalanın 0 a esit olup olmadıgına bakıyor. Eger herhangi bir seferde “x” “i” ye tam bolunmuşse bu sayının asal olmadıgını anlıyor ve ekrana "x asal değildir" yazıp programdan cıkıyor. Programdan cıkmak icin exit(-1) komutunu kullandım. Daha once bu komuttan bahsetmemistik. Bu komut direk programdan cıkar. Altındaki satırları isleme sokmaz... eger while ın icinde hic bi zaman x%i==0 olmamışsa program, while dan cıkar ve alt satırdaki printf("%d asal",x) komutunu isleme sokarak ekrana "x asal" yazar.( x yerine “x” in değerini yazacak)....

Gelelim daha kolay odevler isteyenlere...

ilk basit odev: 2 sayı gireceksiniz. size hangisi büyükse onu verecek...

İkinci basit odevimiz: Program iki sayı alacak. ikinci sayıyı ilkinin kuvveti olarak hesaplıycak. Yani 2 3 girerseniz. 2 üzeri 3 ü bulacak yani 8 verecek ekrana.

Bi kac tavsiye ve hatırlatmadan sonra gelelim bu dersimizde ne işleyecegimize. Bu dersimizde diğer bir dongu olan “for” u ve dizileri(array) işleyecez...

for dongusu:

for dongusu de tıpkı while gibidir. Farkı, kullanım seklidir...

kullanımı:

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

{

}

Bu ornekte goruldugu gibi for parantezlerinin icinde 3 bolum var. Bu bolumler noktalı virgul isareti ile birbirinden ayrılıyor. Bu bolumler for dongusunun kac kere tekrar edilecegini belirlemek icin kullanılıyor. Bunu belirlemek icin de bir degisken kullanıyoruz. Bu örnekte “i” diye bir degisken kullanılmıs. Bunun yerine istediginiz degisken adını kullanabilirsiniz. Birinci bolumde “i” nin ilk degerinin ne oldugu belirleniyor.Bu ornekte 0( i=0 ). Ücüncü bolumde “i” nin dongunun her isleme girdigi seferde “i” ye ne yapılacagı belirleniyor. Bu ornekte “i” her seferinde 1 artırılıyor( i++ ).İkinci bolumde ise for dongusunun devam etmesi icin gereken şart belirleniyor. Bu ornekte “i” 5 den kucuk oldugu surece dongu devam edecek. Yani dongu 5 kere isleme sokulacak.i her seferinde 1 artırılıp en sonunda 5 e eşit olunca program donguden cıkacak.

gecen odevin cevabında kullandıgım while dongusuyle aynı isi yapacak olan bir for dongusu yazayım ornek olarak:

for ( i=2; i<x ; i++ )
{
if(x%i==0)
{
printf("%d asal degil",x);
exit(-1);
}
}


While la arasındaki farka iyi bakın.Bu sefer for un icinde i++; komutunu kullanmadım. Cunku for parantezleri icinde bu islem tanımlanmıs zaten. while dan bir farkı da for dongusunu yazmadan once i=2; komutunu kullanarak i nin ilk degerini atamaya gerek yok. Bu da zaten for un parantezleri icindeki ilk bolumde belirtiliyor...

Gelelim arraylere (diziler)...

Bu diziler de bir takım degiskenlerdir. Degisken dizileridir. Matematikde x1 x2 x3 x4..... xn seklinde diziler vardır. Bilirsiniz biraz. n tane x degiskeni... Yani C de n sayıda aynı isimli segiskenler dizisi belirlemeye yarar. Bu cok kullanıslı ve gerekli biseydir. Mesela 50 tane farklı sayıyı ayrı ayrı degiskenlere atamak istiyoruz. Eger diziler olmasaydı bunun icin kodumuzun icinde 50 tane degisken belirlememiz ve 50 satırda bu degiskenlere degerlerini atamamız gerekirdi. Ama bunun yerine sadece bir degisken dizisi ve bir dongu kullanarak 50 tane sayıyı programa okutabiliriz kolaylıkla...

array(dizi) tanıtmak:

int a[50];

bu satırla a adında 50 tane tam sayı turunde degisken tasıyan bir dizi tanıttık...Matematiksel olarak a1 a2 a3 ... a50 seklinde.

Fakat arrayler de dikkat edilmesi gereken şey dizinin ilk elemanının a[0] olarak gosterilmesidir. 2. eleman a[1], 3. eleman a[2], 50. eleman a[49] seklindedir.

Simdi dizinin ilk elemanına bir deger atayalım...

a[0]=5;

bu satırla dizinin ilk elemanını 5 yaptık. Şu an diger elemanlara bir deger atanmamıs durumda...

mesela...

double B[10];

diye bir satır yazsak virgullu sayı turunde 10 tane degiskeni olan B adında bir dizi belirlemis olurduk...

Simdi array kullanılan basit bir program ornegi vereyim. Bu program 3 tane girdi alacak. Bu girdilerin degerini bir dizide depolayacak ve ekrana dizinin ikinci elemanını verecek:

#include<stdio.h>

main()

{

int x[3];

scanf("%d %d %d",&x[0],&x[1],&x[2]);

printf("%d",x[1]);

return 0;

}


bu programda goruldugu gibi scanf ve printf in icinde normal degiskenleri kullandıgımız gibi dizi degiskenlerini kullandık...

Bu program dizi kullanılmadan da 3 degisken belirlenerek kolayca yazılabilirdi. Ama diyelimki bu program 50 tane degisken alsaydı ve 45 inci degiskeni ekrana verseydi dizi kullanmadan 50 degisken i ayrı ayrı tanıtmak ve scanf in icinde 50 tane degisken yazmak cok sıkıcı olurdu Bu durumu onlemek icin dizi kullanacaz ve scanf le dizinin elemanlarına deger atamak icin bir dongu kullanacaz. Şöyle:

#include<stdio.h>

main()

{

int i;

int x[50];

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

{

scanf("%d" &x]);

}

printf("%d",x[44]);

return 0;

}


Array kullanarak bukadar kısa bir kodla, 50 tane degişkenin ustesinden geldik. for da ne yapıldıgına bakarsak. i degiskeni basta 0 a esitleniyor ve boylelikle once x[0] ın degeri scanf ile okunup atanıyor. Sonra i bir artırılıp a[1] in degeri atanıyor. Bu boyle 49 a kadar giderek en son elemanın da degeri alındıkdan sonra i 50 oluyor ve i<50 şartını saglamadıgı icin for dongusunden cıkılıyor. Sonra printf komutu ile 45. eleman ekrana veriliyor. printf in icine x[44] yazdık ama bize 45. eleman verilecek. Bunun sebebi ilk elemanın x[0] olması... Bu programı compile edip calıstırırsanız 50 kere sayı yazıp enter a basmak zorunda kalacaksınız uyarmadı demeyin

Arrayleri ve donguleri da ogrendiniz. Buraya kadar C ogrenmekte buyuk bir yol kateddiniz. Artık bir cok matematiksel program yapabilirsiniz... Bence kendi kendinize programlar uydurup yapmaya çalısın...

Ama ben gene de bir odev vereyim:

program 10 tane sayı alacak ve bu sayıları toplayıp ekrana sonucu verecek. Programı yapmak icin bir dizi ve iki dongu kullanın. ilk dongu scanf kumutu ile tek tek girdileri okusun. ikinci dongu de gecen dersde verdigim toplama islemi yapan dongu gibi tum array elemanlarını toplam diye bir degiskende toplasın. sonra tek printf komutu ile ekrana toplamın sonucunu versin. 3. dersin sonunda verilen ornek programı iyi inceleyin. Toplama yapan dongunun mantıgını iyi anlayın. Odevi yaparsınız.




__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:49   Mesaj No:2

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 3 (Girdi çıktı fonksiyonları,kontrol operatörleri ve döngüler)

Bu derste printf ve scanf in kullanımları, kontrol operatorleri, if ve switch kontrol statement larını ve while dongusunu ilsiycez...
Once gecen dersin odevinin yorumlarını yapalım. Girdi olarak virgüllü sayı veya harf yazın demistik. Yapanlar gördü ki yanlıs sonuclar veriyor program. Bunun sebebi girdimizi, programa int yani tam sayı olarak tanıtmamız. Girdi virgüllü olunca tam sayı kısmı alınıp öyle işlem yapılıyor dogal olarak. Yada harf girince harfi 61 diye bir tam sayı olarak kabul ediyor. Bu compiler' a ve girdiğiniz harfe gore degisebilir. 61 e takılmayın. Önemli olan burada beklenmedik sonuçlar aldığımızı gozlemlemek ve değişken turlerinin onemini anlamak...

printf ve scanfin kullanımları:

printf("hello&quot: bu ornegi inceleyelim:

prinft her fonksiyon gibi yanında parantezler açılarak kullanılır.parantezlerin içinde iki kısım vardır. Birincisi "" isaretlerinin icinde kalan kısım ikincisi "" isaretlerinin icinde olmayan kısım. ikinci kısım değişkenlerin değerlerini ekrana verirken kullanılır. Bu orneğimizde değişken olmadıgı icin ikinci kısım yok.Birinci kısım yani "" lerin icinde kalan kısım ekrana yazılacak yazıları belirler.Bu örnekte ekrana “hello” yazılır.Birinci kısımda kullanılan bazı özel karakterler vardır. Bunlar olduğu gibi ekrana yazılmaz.Yazılacak yazının formatını belirler.Mesela \n karakteri alt satıra geç demektir.

printf("hello\nhello&quot yazarsak ekrandaki görünümü şöyle olur:

hello

hello

özel karakterlerden biri de % işaretidir. Bu işaret, bir değişkenin değeri ekrana yazdırılacaksa değişkenin turunu ve ekranda yazılacağı yer ve formatı belirlemek için kullanılır . % den sonra gelen kısım degiskenin hangi türde kabul edileceğini söyler. Mesela %d tam sayı demektir. "" işaretlerinin içinde %d olan yere tırnak işaretlerinin dışında kalan değiskenin değeri ekrana yazdırılır. Örnek:

x=3;

printf("degiskenin degeri %d dür",x);

burda ekrana gelecek olan yazı şöyledir:

degiskenin degeri 3 dür

gordugunuz gibi %d yerine x in değeri geliyor. Biz bir önceki dersimizde "" lerin icine başka bir yazı yazmadık. Sadece %d yazdık. Bu yüzden sadece ekrana değişkenin değeri geldi.

printf sadece bir değişkenle kullanılmak zorunda değildir.

x=3;

y=4;

printf("%d %d",x,y);

bu ornekte ekrana

3 4

şeklinde bir output gelir.Gordugunuz gibi her degisken icin bir tane %d yazdık.

printf("x'in degeri %d y'nin degeri %d",x,y); seklinde yassaydık output soyle olacaktı:

x'in degeri 3 y'nin degeri 4



scanf in kullanımı da çok benzerdir. Tek fark "" işaretlerinin içine herhangi bir yazı yazmaya gerek duymamız. Ve değişkenlerden önce

& işareti konulması.

scanf("%d %d",&x,&y);

bu örnekte ekrana 3 5 yazdığımızda “x“e 3 “y” ye 5 atanır. %d lerin arasında boşluk bıraktığımıza dikkat edin. Boşkul bırakmasaydık inputumuzu da 35 seklinde girmemiz gerekirdi...

Şimdi kontrol operatorlerini gorelim:

> : büyük mudur ?

< : küçük mudur ?

== : eşit midir ?

!= : eşit değilmidir ?

>= : büyük veya eşit midir ?

<= : küçük veya eşit midir ?

&& : ve

|| : veya

bu sorguların cevapları doğru ise yanıt 1, yanlış ise yanıt 0 olur. Peki bu sorguları nerde kullanırız ? Bunlar kontrol işlemleriyle kullanılır. Bu islemlerin baslıcaları if ve switch dir:

if in kullanımı:

if ( x==3)

{

}

seklinde kullanılır. if den sonra acılan parantezlerin icine kontrol edilecek durum yazılır. Eger durum dogru (1) ise { } lerin icindeki islemler yaplılır. Degil (0) ise { } lerin icindeki islemler gecilir. Bu ornek eger x degiskeni 3 e esit ise aşağıdakileri yap seklinde acıklanabilir.

if ( x== 3 && y<10) mesela burda eger “x” 3 e esit ise ve “y” de 10 dan kucuk ise assagıdakileri yap demek oluyor. Bu iki durumdan biri bile yanlıs ise durum yanlıs olarak kabul edilir. && yerine || kullansaydık iki durumdan biri bile dogru olsa durum dogru kabul edilirdi. ve ile veya nın farkı budur.

“=” ile “==“isaretlerini karıstırmayalım. Birincisi deger atamak icin kullanılırken ikincisi degerin esitligini kontrol etmek icin kullanılır.

else :

if "eger" demektir else de "degilse" anlamına gelir. Bir if satement ının sonuna else yazarsanız. Durum yanlıs ise yapılacakları belirleyebilirsiniz.

if(x==3)

{

y=y+1;

z=z-1;

}

else

{

y=y-1;

z=z+1;

}

yukarıda: eger x 3 e esitse y ye bir ekle, z den bir cıkar.x 3'e esit degilse(else) y yi bir azalt z ye bir ekle. Demek oluyor. else i kullanmak zorunda degilsiniz. else i kullanmazsanız durum yanlıs ise yapılacak islemleri belirlememis olursunuz. Durum yanlıs ise if in icindekiler kale alınmaz.

switch:

switch bir durumun bir kaç ihtimalini goz onune alarak. Yapılacakların belirlenmesini sağlar.

kullanımı:

switch(x)

{

case 3:

printf("x 3 e esitmis"

case 4:

printf("x 4 e esitmis"

default:

printf("x 3 e de 4 e de esit degilmis"

}

switch in yanına gelen parantezlerin icine kontrol edilecek degisken yazılır. case lerden sonra da x in neye esit olup olmadıgı kontrol edilir. Bu ornekte: x 3 e esit ise ekarana "x 3 e esitmis" yaz, x 4 e esit ise ekrana "x 4 e esitmis" yaz, “x”, yukardaki durumların hicbirine uymuyorsa(default) "x” 3 e de 4 e de esit degilmis" yaz. switch in kullanımı da budur. Ama sadece tek degiskeni ve esitlik durumunu kontrol edebilir. Bu nedenle ben switch i pek sevmem ve kullanmam. daha cok islerimizi if ile gorecez...

C de encok kullanacagımız seylerden biri de dongulerdir. Donguler bi islemi tekrar, tekrar yaptırmaya yarar.

Bu gunluk while dongusunu anlatacam:

while(x<10)

{

}

while ın kullanım formatı bu sekildedir. parantez icindeki durum dogru oldugu surece durmadan { } lerin icindeki islemler gerceklestirilir. Bi ornekle acıklayalım.

y=15;

x=1;

while(x<3)

{

y=y-x;

x=x+1;

}

bunun yapacagı işi acıklayalım:

ilk basta x=1 y=15 dir. program, x<3 mudur diye kontrol etti baktıki dogru. Sonra while in icine girdi. y=y-x; i isleme soktu.

Yani “y” yi “y” eksi “x” e esitledi. Yani y nin yeni degeri 15 - 1=14 oldu. “x” i “x+1” e yani 2 ye esitledi. x in yeni degeri 2 oldu. Sonra tekrar başa dondu. baktı “x<3”(x küçük 3) mudur. 2<3 dür yani dogru. Tekrar while ın icine girdi. y=y-x; i tekrar calıstırdı.”y” 14 olmuştu. “x” de 2. yeni”y” 14-2 yani 12 oldu. “x” de tekrar 1 arttırıldı ve 3 oldu. Sonra tekrar basa dondu. Baktı x<3 mü hayır 3<3 doğru değil.

while döngüsü tamamlandıgında x in degeri 3 y nin degeri de 12 oldu.

Dongulerin mantıgı da boyle... Dongulerin uzunlugunu sınırlamak icin genelde x=x+1 gibi bir satır bulunur. Bu satıra denk gelen bir satır vardır: x++; bu x in degerini bir artır demektir. x--; de x in degerini 1 azalt demektir. Aklımızda bulunsun.

şimdi örnek bir program:

bu program 0 dan verilen bir sayıya kadar olan tüm sayıların toplamını buluyor. Mesela 5 yazarsak bize 1+2+3+4+5 yani 15 veriyor.

#include<stdio.h>
main()
{
int i, x, toplam;
scanf("%d",&x);
toplam=0;
i=1;
while(i<=x)
{
toplam=toplam+i;
i++;
}
printf("%d",toplam);
retırn 0;
}

bu prgramı calıstırıp inceleyin. Gecen dokumandaki ödev kolaydı bu hafta yeni başlayanlar için kazık bir ödev veriyorum. Girdiginiz sayının asal olup olmadıgını bulan bir program yapacaksınız. Girdiginiz sayı asalsa ekrana 1 degilse 0 yazacak.

Biraz ipucu veriyim.Asal sayının ne oldugunu herkes biliodur heralde bi while dongusu yapıp girilen sayıyı 2 den baslayarak girilen sayıya kadar tek tek boldureceksiniz. Ve her seferinde kalanın 0 olup olmadıgını kontrol ettireceksiniz. Butun sayılara bolumunden kalan hic 0 cıkmassa o sayı asaldır demeeki... Yani 1 ve kendisi dışında hic bir sayıya tam bolunmuyo demektir.

Kalanı kontrol etmek icin bir onceki dersimizde verdigimiz % operatorunu kullanacaksınız. Mesela

x=10;

y=3;

z=x%y;

derseniz z = 1 olur...[/b]

__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:49   Mesaj No:3

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 4 (Stringler)

Geçen dersimizde arrayleri gorduk... Artık string lerle ugrasabiliriz. Daha once degisken turlerinden bahsetmistik. Programlarımızda int, double, float gibi sayı tutan degiskenlerden bahsettik ve bunların dizilerde kullanıslarını gorduk. Ama daha once adını verdigimiz char degisken turunden pek bahsetmedik. Hatırlarsak char harfleri tutan bir degiskendi. C de bir kelimeyi yada cumleyi taşıyan bir degisken turu yok. Ve bizi de programlarımızda harflerden cok kelimeler ve cumleler ilgilendirecek. Peki nasıl ustesinden gelecez bu kelime ve cumlelerin ? char turunde yani harf taşıyan diziler kullanarak. Bu tur dizilere C de string deniyor. Yani string kelime ve/veya kelimelerden olusan cumlelere deniyor... Simdi mesela programımızın radres kelimesini aklında tutmasını ve bu kelimeye gerekli değişiklikleri yapmasını istiyoruz.Bunun icin char arrayi kullanacaz... bir int arrayı nasıl yapıyorduk hatırlayalım.

int A[6];

A adında 6 tane tamsayı taşıyabilecek olan bir dizi yaptık...char arrayini de su sekilde yapacaz.

char A[6];

Burda da 6 tane harf tutabilen bir array yapmıs olduk. Simdi ben bu array'ın elemanlarına sırayla radres in harflerini atarsam bu kelimeyi basarıyla programımıza depolatmıs oluruz...

Su sekilde:

A[0]='r';

A[1]='a';

A[2]='d';

A[3]='r';

A[4]='e';

A[5]='s';

A[6]='\0'

Burda dikkat edilecek iki nokta var.

Birincisi = den sona harfleri atarken ' ' isaretlerini kullandık. char turunde bir degiskene deger atarken bu sekilde yapıyoruz. Eger A[0]=r diye yassaydık program “r” nin bir degişken oldugunu sanacaktı. Halbuki r diye bir degişkenimiz yok. Burada r sadece bir harf bunu belirtmek icin 'r' seklinde yazıyoruz.

İkincisi ise A[6]='\0' da kullandıgımız \0 isareti... Burda \ ile ozel bir karakter kullandıgımızı belirtiyoruz. Hatırlarsanız printf in icinde de \n diye bir şey kullanmıstık bu alt satıra geç demek oluyordu. \0 ise A stringimizin( yani A char arrayimizin ) sonuna geldigimizi yani kelimemizin yada cumlemizin bittigini anlatıyor.Her stringin son elemanı \0 dır. Ancak bu isareti gordugu zaman program stringimizin sonuna geldigimizi anlar.

Yukardaki kodlarda bir string yapmanın çok zahmetli oldugunu goruyorsunuz. Tek tek butun elemanları yani harfleri yazdık. Bunu yapmanın daha kolay bir yolu var tabiki... Ben acıklayıcı olması icin boyle yaptım. Normalde bir string oluşturmak için şoyle bir kod kullanılır.

A [] = "radres";

Burdaki tek satırda daha once yaptıgımız uzun işin tam olarak aynısı compiler tarafından yapılır. Burda da dikkat edilecek iki şey var.

Birincisi [ ] lerin içini bos bıraktık. Yani arrayimizin sınırlarını belirlemedik. Aslında dizileri bir şeye eşitlemeden kaç elemanlı oldugunu belirlemezsek compiler hata verir. Ama bu komutta gene compiler bizim yerimize stringimizin kaç harfden olustugunu sayıp arrayimizin sınırları belirliyor.Ve son elemana \0 karakterini gene kendisi atıyor.

İkinci dikkat edilecek şey ise " " isaretleri. String belirlerken tırnak işaterleri kullanıyoruz. Harf ve karakter belirlerken ise ' ' isaretlerini... Bunlar karıştırılmasın....

Simdi elimizde bir stringimiz var ve biz bunu istedigimiz gibi değistirebiliriz. mesela bu stringin 3. harfden sonrasını silelim...

A[3]='\0';

Bu komutla bu işi yaptık bile... A[3] r harfi idi, artık \0 karakteri oldu. Bundan sonra A stringini ver bize dedigimizde program, 3. elemandan sonraki elemanın yani A[3], yani dorduncu elemanın \0 oldugunu gorecek ve gerisini okumayacak. Bize sadece “rad” kısmını verecek. Şimdi de ilk elemanın baş harfini buyuk yapalım..

A[0]='R';

Bu komuttan sonra stringimiz Rad oldu...( unutmayın C buyuk harf kucuk harf ayrımı yapar. Asla R ile r aynı sey degildir.)

Peki biz bu stringleri programa input olarak nasıl okuturuz

? Yada output olarak nasıl verdiririz.

Output:

printf("%s",A);

Bu komut ekrana direk Rad yazar... Burda " " lerin icinde %s kullandık. Cunku A bir stringdir. int turunde bir degisken yazdırırken %d kullanıyorduk. String için de %s kullanacaz...

Eger stringimizin sadece ilk harfini yazdırmak isteseydik şu komutu kullanacaktık..

printf("%c",A[0]);

Bu komutun cıktısı sadece R olacaktır. Bu sefer " " lerin içine %c yazdık, % c char turunde bir cıktı alacagımızı soyluyor. Cunku A[0] bir harftir. Burada kafalar karışmasın. A stringdir. A'nın elemanları ise mesela A[0] bir harftir, char turundedir...

Input:

scanf("%s",A);

printf in tıpkısının aynısı scanf in daha onceki kullanımlarında degiskenden once & isaretini koyuyorduk. String okuturken ise bu isareti kullanmıyoruz. Bunun sebebi çok derin bir konu ileride pointerlar dokümanında anlayacaksınız...

Yukardaki komutun olduğu bir program da ekrana “radres” yazar enter a basarsanız A direk “radres”i alır gerekli şekilde depolar. Ama bu sefer A nın sınırlarını daha onceden belirlememiz gerekecek.

Simdi yukarda yazdıgımız kodları birleştirip basit bir program yapalım:

#include<stdio.h>

main()

{

char A[10];

scanf("%s",A);

A[3]='\0';

A[0]='R';

printf("%s",A);

return 0;

}


Bu programı calıştırıp “radre”s yazar ve entera basarsanız. Ekrana Rad yazacak...

Stringlerde input ve output larla ugrasmak icin printf ve scanfden daha kolay kullanımları olan komutlar var onlardan da haberdar edeyim sizi.

puts ve gets komutları:

printf("%s",A) yerine puts(A) yazarsak aynı işi gorür.

scanf("%s",A) yerine de gets(A) yazmak aynı şey değil. Bir fakı var. gets tüm satırı okurken scanf tüm satırı değil ilk kelimeyi okur. Çünkü scanf her boşluktan sonra gelen şeyi başka bir input olarak alır. gets ise her satırı bir input olarak gorür.

gets(A); kullanılan bir programda ekrana “Rad radres yazarsanız A[]="Rad radres" olur. Ama scanf kullanırsanız A[]="Rad" olur. Bu farkı da aklımızdan cıkarmayalım...

Simdi bu ogrendiklerimizi ve onceki bildiklerimizi kullanarak bir program yazacam bunu compile edip calıstırın programın ne yaptıgını ve mantıgını anlamaya calışın...

#include<stdio.h>

main()

{

char S[250], buf[250];

int string_uzunlugu,i,j;

gets(S);

i=0;

while(S != '\0')

{

i++;

}

string_uzunlugu=i;

i=i-1;

for(j=0; j<string_uzunlugu; j++)

{

buf[j]=S;

i=i-1;

}

buf[string_uzunlugu]='\0';

puts(buf);

return 0;

}


Bu dersin ödevi: bu programı compile edip calıstırın input olarak “radres” yazıp enter'a basın. Bakalım program output olarak ne verecek. Kodları iyice inceleyip nasıl calıştıgını, mantıgını ogrenin.Sonra bakmadan programı kendiniz tekrar yazmayı deneyin... input olarak radres den başka değisik şeyler de deneyin...
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:49   Mesaj No:4

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 5 (Fonksiyonlar)

Bu derste fonksiyonlardan bahsedecem....
Simdiye kadarki yazdıgımız programlarda main() diye bir kısım vardı bilirsiniz... Programın yapacağı islerin hepsini bu main in icine yazıyorduk. Bu main() aslında bir fonksiyon. Programımızın ana fonksiyonu... Biz istersek programı başka fonksiyonlara bolerek de çalıştırabiliriz. Peki bunu niye yapalım ? Baska fonksiyonlar da kullanmak zorundamı kalıyoruz bazen ? Hayır.. sadece main fonksiyonunun icinde her şeyi halledebiliriz ama bazen belli kodları tekrar, tekrar yazmamız gerekebilir. Biz de işimizi kolaylastırmak ve programımızı duzenli bi hale getirmek icin belli isleri yapan kodlardan bir fonksiyon olustururuz ve bu kodlar tekrar, tekrar yazılacagına sadece fonksiyonumuzu cagırarak buyuk bi kufletten kurtulmus oluruz. Kısaca fonksiyonlar belli kod kumelerini tasıyan tek satırlık komutlardır diyebiliriz...

Bir fonksiyon oluşturmak icin temel olarak iki şey yapılmalıdır. Birincisi fonksiyonun adını ve kullanımını belirleyip tanıtmak(decleration) türkçeye de deklare etmek diye gecmiştir. İkincisi fonkiyonun icerdigi kodları yani yaptıgı işleri yazmak. Buna da implementation deniyor. Turkcesini bilmiyorum

Şimdi "yazdır" diye bir fonksiyon yapalım...

void yazdır(); // bu satırda yazdır adında bir fonksiyon tanıttık yani deklare ettik...

void yazdır() // burada da fonksiyonumuzun implementation ını yaptık.. yani fonksiyonun

{ // yapacağı işi { } ler acarak icine yazdık.. burda fonksiyonumuz ekrana

printf("Merhaba" // Merhaba yazıyor... yaptığı iş bu....

}

peki bu fonksiyonun başına yazdıgımız void de neyin nesi ?

Bu sorunun cevabını vermek icin bir fonksiyonun nelerden olustuguna deginmek gerek.

Bir fonksiyonun girdileri ve bir cıktısı vardır. Mesela iki tam sayıyı birbiri ile toplayıp sonucu veren bir fonksiyon duşunelim. Bu fonksiyonun iki tane girdisi olacak ( toplanacak sayılar) ve bir cıktısı ( toplamanın sonucu ). Bir fonksiyonu tanıtırken kac tane girdi aldıgını bu girdilerin turunun ne oldugunu ( tam sayımı, virgullu sayımı yada harf mi ) ve cıktısının turunu belirlememiz gerekir.

Yazdır fonksiyonunda, fonksiyon herhangi bir girdi almıyor ve bir cıktısıda yok. girdi almadıgını belirtmek icin yazdır dan sonra actıgımız parantezlerin icini bos bırakıyoruz yazdır() seklinde.

Cıktısının olmadıgını belirtmek icin de başına void yazıyoruz. void, cıktısının olmadıgını anlatıyor.

Bu noktada fonksiyonun çıktısı ile ekrana yazdırdıgımız yazıyı karıştırmamak lazım. Ekrana bir yazı yazıyor diye o fonksiyonun çıktısı var demek değildir.Fonksiyonların girdilerinin ve çıktılarının nasıl oldugunu inceleyelim:

toplama fonksiyonu:

int topla(int a, int b); // deklare ettik

int topla(int a, int b) // implementation

{

int c; // fonksiyonun icinde c diye bir tam sayı belirledik

c=a+b; // c yi fonksiyonun girdileri olan a ve b nin toplamına eşitledik

return c; // cıktı olarak c yi ver dedik

}

Yukarda goruldugu gibi topla fonksiyonunda void in yerine int yazdık çünkü bu sefer fonksiyonumuzun bir cıktısı olacak ve turu integer yani tam sayı olacak. Parantezlerin icinde de a ve b adında iki tene integer belirledik ve bunlar fonksiyonlumuzun girdileri oldu.Parantezlerin icindeki girdiler virgulle birbirinden ayrıldılar. return c; satırı ile fonksiyonun cıktısının ne olacagını belirlemis olduk. Bir fonksiyonun cıktısı varsa bu return komutu ile belirlenir.

Fonksiyon oluşturmayı öğrendik. Simdi olusturdugumuz fonksiyonu programımızda nasıl cagıracagımızı ( nasıl kullanacagımızı) ogrenelim:

main()

{

int x;

x=topla(3,5);

printf("%d",x);

}

yukardaki programda topla fonksiyonunu cagırdık girdi olarak 3 ve 5 i verdik cıktısını da x degiskenine atadık. Sonuc olarak x 3+5 yani 8 oldu. printf komutunun ekrana verdigi degere bakacak olursak 8 oldugunu goruruz. Yukardaki kodları birlestirip fonksiyon kullanıldıgı bi program yapacak olursak soyle olur...

#include<stdio.h>

int topla(int a, int b);

int topla(int a, int b)

{

int c;

c=a+b;

return c;

}

main()

{

int x;

x=topla(3,5);

printf("%d",x);

}


Gordugunuz gibi main i yazmadan once main in icinde kullanacagımız fonksiyonu once olusturduk sonra da main in icinde cagırdık.

Fonksiyonları ogrendigimize gore scope olayına da deginmemiz lazım. Scope turkce olarak icerik diye cevrilebilir. Bir program scope lardan olusur.Programda kullanılan her fonksiyonun bir scopu vardır main de dahil olmak uzere... Scope degiskenlerin birbirine karısmamasını saglar. Yukardaki ornekte hem mainin icinde hem de topla fonksiyonunun icinde degiskenler belirlendigini goruyorsunuz.. main in icinde belirledigimiz degiskenin adı da x yerine a olasydı topla fonksiyonunun icindeki a degiskeni ile karışırmıydı ? hayır.. cunku her degisken scope larına goredir. x degiskeninin scopu maindir a,b ve c degiskenlerinin scope u da topla fonksiyonudur...

x in adını a yaparsak programın kafası karışmaz... program icin iki tane a degiskeni olur biri scope u main olan a degiskeni, digeri scope u topla olan a degiskeni program scope ları farklı oldugu icin bu ikisini birbirine karışrtırmaz... ama aynı scope un icinde aynı isimli iki degisken belirleyemessiniz main in icinde iki tane a olamaz..

simdi bu scope olayını daha iyi anlamamıza yarayacak bir program yazalım:

#include<stdio.h>

void ekle(int x);

void ekle(int x)

{

x=x+1;

}

main()

{

int y;

y=5;

ekle(y);

prinrtf("%d",y);

}


Bu programda aldıgı değere bir ekleyen ekle adında bir fonksiyon olusturduk. mainin icinde y diye bir degisken belirledik değerini de 5 yaptık. sonra y degiskenini ekle fonksiyonuna verdik. printf le de y nin son değerini ekrana vermesini istedik. Simdi ekrana verilecek olan sayı y nin bir fazlası mı olacak ? Yani ekrana 6 mı yazılacak ? Bu soruya evet diyesi geliyor insanın cunku ekle fonksiyonu y nin degerini bir artırdı sanıyoruz ama oyle olmadı aslında. Sorunun cevabı hayır... ekrana 5 sayısı yazılacaktır. Simdi ekle(y); satırında olanları inceleyelim:

Bu satırda once y nin degeri ekle fonksiyonuna verildi.Sonra, ekle fonksiyonunun scope unda olan x degiskeninin degeri main in scope unda olan y nin değerine yani 5 e eşitlendi. Şu an ekle fonksiyonunun scope undayız yani eklenin içindeyiz... ekle fonksiyonunun icinde x in degeri bir artırıldı yani 6 oldu sonra ekle fonksiyonunun yapacagı işler bitti ve icinden cıktık, artık tekrar main in scope undayız ve main in icinde artık x diye bi değişken yok... Ve gordugunuz gibi y değişkenine bir değişiklik yapılmadı ... ekle fonksiyonu sadece kendi içinde bulunan x değişkenine bir değer atayıp sonra da onu bir artırdı ama kendi scope unda olmayan y değişkenine bir şey yapamadı...

main in icinde belirledigimiz y degiskeninin adını x diye deistirsek de bisey farketmezdi... cunku gene main in icindeki x ile eklenin icindeki x farklı şeyler olacaktı cunku scope ları farklı...

Demekki her fonksiyon kendi scope undaki degiskenlere etki edebiliyor ve her degisken bulundugu scope a gore ayrı bir sekilde degerlendiriliyor program tarafından...

Peki fonksiyonların main in icinde belirlenmis bir degiskenin degerini degistirmesinin bi yolu yokmu ? Var birincisi, fonksiyona bir cıktı belirlemek ve bu cıktıyı mainin icindeki degiskene atamak ilk programımızda ki şu satırda oldugu gibi: x=topla(3,5);

İkincisi ise pointer kullanmak ... pointerları da bir dahaki dersimizde işleyecez .

Simdi ödev veriyorum:

Asal sayı bulan bir program yapmıstık hatırlarsanız... Simdi o programı geliştirelim biraz... Bu seferki programımız çalıştığında kullanıcıdan iki sayı girmesini isteyecek ve bu iki sayı arasındaki asal sayıları alt alta ekrana verecek... Mesela 10 ve 15 diye iki sayı girdik.. program ekrana

11

13

verecek... Bu programla 5 milyonla ile 6 milyon arasındaki tüm asal sayıları bulabilirsiniz mesela...

Programda bir sayının asal olup olmadıgını kontrol eden bir fonksiyon kullanılacak... mesela fonksiyona verilen sayı asalsa cıktı olarak 1 versin degilse 0 versin... mainin icinde de bu fonksiyon kullanılarak bir loop yapılacak ve loopta girilen iki sayı arasındaki tüm sayılar sırayla fonksiyona verilecek eğer sonuc 1 olursa o sayı ekrana yazdırılacak...
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:50   Mesaj No:5

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 6 (Pointerlar[işaretçiler])

Sıra geldi pointerlara, C de ki en onemli konuya… Bu pointerları
da iyice oğrenirsek artık C de onumuz acık demektir.Peki nedir bu
pointer denen şey ?
Türkçe anlamı işaretçi demektir. Yani bunlar bir şeyleri işaret ederler.
Ama pointerların esas olayı RAMdeki byte'ların adreslerini tutan
değişkenler olmalarıdır. Yani pointerlar da integer, double yada
char gibi bir değişken turudur fakat sadece memory adresi tutarlar
ve diğer degisken turlerinden farklı olarak baska bir degiskeni
isaret edebilirler.Peki memory adresi dediğimiz şey nedir ve
işaret etmekden kastımız ne ? Diye soranların sesini duyar gibiyim
İlk önce RAMi inceleyelim biraz. RAM bilgisayarın işlemlerini
yurutebilmesi icin bazı bilgileri geçici olarak kaydettigi bir cesit
hard disktir. RAM byte'lardan oluşur mesela benim RAM im 256 mega byte.
bu da (1MB = 1024 Kilo byte ve 1Kb = 1024 byte dersek) 268435456 byte oluyor sanırım. RAM adresi bu bytelarla belirleniyor. 100000 diye

bir RAM adresi, RAM deki 100000 inci byte demek oluyor. Bu byte

dedigimiz şey de bit lerden oluşuyor.8 tane bit ten oluşan bir bloka

byte demişler. bit dediğimiz şey de bilgisayar dunyasındaki o meşhur 0 ve 1

lerin kaydedildigi yerlerdir. Yani bir bit de sadece doğru yada yanlış

bilgisi tutulabilir yani 0 yada 1 ... demek ki bir byte 8 tane 0 yada 1

den olusuyor ornek:



00001101 bir byte dir...



Bu 0 ve 1 lerin bilgisayarımıza taktığımız ve RAM dedigimiz o kartuşlarda

nasıl olustugunu merak ediyorsanız onuda soliyim. RAM in icindeki binlerce

kucuk elektronik switch lerle olusuyor. Bu switch ler acık yada kapalı

hale getirilerek 0 yada 1 i temsil ediyorlar. Elektronik dilinde bu switchlerin acık yada kapalı olmasını temsil eden şey de aletteki pinlerin ucunda voltaj olması ya da olmamasıdır. Bunu da bir ek bilgi olarak soylemiş olalım



RAM i şu şekilde hayal edelim:



.

.

.

00110010 ----> 124561 inci byte

01110011 ----> 124562 inci byte

10110010 ----> 124563 inci byte

00001011 ----> 124564 inci byte

00011101 ----> 124565 inci byte

10010011 ----> 124566 inci byte

00001111 ----> 124567 inci byte

00100101 ----> 124568 inci byte

.

.

.





124561 inci byte RAM deki adres oluyor. karşısındaki 0 ve 1 ler de o

adreste bulunan byte daki bilgilerdir.



biz yazdıgımız programda



int x;

x=5;



yazdıgımızda x değişkeninde bir bilgi tutulabilmesi icin RAM de bir adres

ayrılır ve o adrese 0 ve 1 ler kullanılarak x=5 bilgisi kaydedilir.

Bu kadar genel bilgiden sonra pointer tanıtma ve kullanmayı kodlarla

anlatalım artık...



pointerlar işaret edecekleri degiskenin turune gore tanıtılırlar

bir integer a pointer atamak istiyorsak pointerımızı şu şekilde belirleyecez:



int *p;



normal integer tanıtır gibi.. fakat tanıtacagımız degiskenin basına bir * işareti

koyunca o degişken pointer oluyor. Yukardaki komuttan sonra artık bir pointer

degişkenimiz var. Unutulmaması gereken bir nokta da pointerın da bir degişken oldugudur.

Simdi bu pointerla neler yapabilecegimize ve nasıl kullanıldıgına bakalım.



int *p;

int x;

x=5;

p=&x;



yukardaki kodlarla once bir integer pointerı belirledik. Sonra x adında bir

integer değişkeni belirledik ve ardından bu degiskenin degerini 5 yaptık.

Son satırda da pointerın x e işaret etmesini sağladık. Bunu & sembolu ile yaptık.

& işareti şu anlama geliyor: " ...nın adresi" yani &x, "x in adresi" anlamına geliyor.

Son satırdan sonra p nin degeri x in memory adresine eşitlendi. Mesela x degiskeninin

tasıdıgı degeri aklında tutmak icin bilgisayar 156789 uncu byte a 0 ve 1 lerle

5 degerini kaydetti. Artık p nin degeri 156789 oldu.



main()

{

int *p;

int x;

x=5;

p=&x;

printf("%d\n",x);

printf("%d\n",p);

return 0;

}



yukardaki kodu yazıp calıstırırsanız, programın x in degeri olarak 5 i ve

x in tutuldugu memory adresini yani p nin degerini verdigini goreceksiniz.

p nin alacagı deger her bilgisayarda farklı olacaktır. Cunku x degiskeni

RAM deki ilk bos yere yazılacaktır ve bu bilgisayarın calısma durumuna ve

RAM in kapasitesine gore degisir.



Bir degiskene pointer atadıktan sonra o pointerı kullanarak degiskene

istedigimis degisikligi yapabiliriz. p, isaret ettigi degiskenin adresini ifade

ederken, *p, degiskenin degerini ifade eder. yukardaki kodlarda



printf("%d\n",p); komutunu

printf("%d\n",*p); seklinde degistirirsek x degiskeninin

adresi yerine degerinin yani gene 5 in ekrana verildigini goreceksiniz.



Aynı sekilde x in degerini de degistirebiliriz.



*p=6;



yazdıktan sonra x in degeri artık 6 olur.Yani *p ifadesi p pointerının işaret ettigi

degişken anlamına geliyor ve x yerine istedigimiz zaman *p ifadesini kullanabiliyoruz.



Bu noktaya kadar pointerların ne oldugu ve ne ise yaradıklarını ogrendik.

Peki nedir bu pointerları bu kadar onemli yapan, nedir bu pointerların marifetleri ?

Gelelim pointerların marifetlerine ve C deki kullanım alanlarına...



C de tanıttıgımız her şey, degisken, array, fonksiyon... her şey RAM e yazılır

Dolayısıyla RAM e yazılan her şeye RAM adresini taşıyan bir pointer atanabilir.

Yani pointer C de her programda, her algoritmada kullanılabilir.Baslıcalarına deinelim.



Pointerlarla arrayler:



int A[5]



diye bir satırla tanıttıgımız A arrayine beş tane integer(tam sayı) tasıyabilecek sekilde

RAM de yer ayrılır. Program bir integerı aklında tutabilmesi icin 2 yada 4 byte yer ayırır hafızada Dielimki bizim compilerımız 4 byte yer ayırıyor bir integer icin. A arrayine yer

acılması icin 5 * 4= 20 byte lık alan hafızada ayrıldı. Diyelimki RAM de ilk bos

byte 123456 ıncı byte olsun. Bu byte dan baslayarak arrayın elemanları icin 20 bytelık yer ayrılacak. Şu şekilde:



________ 123456 ıncı byte A[0]

________

________

________

________ 123460 ıncı byte A[1]

________

________

________

________ 123464 uncu byte A[2]

________

________

________

________ 123468 ıncı byte A[3]

________

________

________

________ 123472 ıncı byte A[4]

________

________

________





Yukardaki sekilde "________" diye gosterilen yerler RAM deki bir byte ı temsil ediyor.

A[0] icin 4 tane byte ayrılmıs. 123456, 123457, 123458 ve 123459 uncu byte lar...

Ama A[0] in RAM adresi kendisine ayrılan ilk byte olan 123456 dır. Bu aynı zamanda

A arrayinin ilk elemanının adresi oldugu icin A arrayinin de adresi oluyor.

A arrayine bir pointer atamak istersek yapmamız gereken mesela p diye

bir integer pointer ı belirledikten sonra p=A satırını yazmak. A zaten A[5]

arrayının ilk elemanının pointerı oluyor otomatik olarak. Simdi bu yazdıklarımızı

kodlara dokerek acıklayalım:



#incluıde<stdio.h>

main()

{

int *p;

int A[5];

A[0]=10;



printf("%d\n",A);

printf("%d\n",A[0]);

printf("%d\n",*A);



p=A;



printf("%d\n",p);

printf("%d\n",*p);

}


Bu programı calıstırırsak şu sekilde bir cıktı verecektir: (A arrayının adresinin 123456 oldugunu kabul ediyorum)



123456 ---->A

10 ---->A[0]

10 ---->*A

123456 ---->p

10 ---->*p



goruldugu gibi A , A[5] arrayinin adresi olan 123456 degerini veriyor. Cunku A nın kendisi bir pointer.

A[0] , arrayin ilk elemenı ve 10 a esitlenmisti. *A , A pointerının işaret ettigi degiskenin degerini verecek.

Bu da arrayin ilk elemanına işaret ediyor ve 10 degerini ekrana veriyor.p pointrerı, A ya esitlendigi icin

boylece arrayın adresini tasımıs oluyor ve ekrana 123456 veriliyor.*p, 123456 adresindeki degiskenin degerini

verecegine gore *p icin ekrana 10 veriliyor... ( yukarda bahsedilen 123456 degeri sizin bilgisayarınızdaki

ilk bosalan RAM adresine gore degisecektir.)



Bir arrayin adının o arrayin pointerı oldugunu ogrendik. Bunu kullanarak (*A seklinde) arrayin ilk elemanına ulasmayı da

ogrendik. Peki arrayin diger elemanlarına nasıl ulaşacaz ? Diyelim ki p diye bir integer pointerı belirledik ve

p=A dedik. p yi kullanarak A[1] e yani arrayin ikinci elemanına nasıl ulasabiliriz ?



p++;



yazarsak p nin degeri bir artırılacak. p nin degeri ornegimizde 123456 idi. Yeni degeri 123457 mi olacak ?

Hayır

C, bunun bir array pointerı oldugunu bilecek ve bir sonraki array elemanına denk gelecek sekilde p nin degerini artıracak.

Bizim ornegimizde integer arrayı kullandık ve her integer icin 4 byte ayrılmıstı. C, bunu bildigi icin p nin degerini 4 artıracak.



p++;



komutundan sonra p nin degeri 123460 olacak. Bundan sonra *p yazarsak bu ifade 123460 adresinde bulunan degiskenin degerine esit olacak.

yani A[1] e... mesela p yi kullanarak A[1] e bir deger atamak istersek:



p=A

p++;

*p=11;



bu komutlarla A[1] in degeri 11 olacak...



Peki bu arraylerin elemanlarını neden pointer kullanarak deistirelimki ? Neden işimizi uzatalımki ? Direk A[1]=11 yazsak daha kolay olur deilmi



Simdi bunu neden ogrendigimizi gosteriyim...

Fonksiyonları işlemiştik. Mesela



int topla(int a,int b);



seklindfe tanıtılan bir fonksiyon girdi olarak iki tane tam sayı alıyor ve bunların toplamını veriyor diyelim.

Fonksiyona bu sekilde tamsayı girdisi yada cıktısı almak kolay. Peki fonksiyonumun bir array almasını yada bir array vermesini

istersek bunu nasıl yapacaz ? Ponter kullanarak



int topla(int *t,int n);



seklinde bir fonksiyon tanıtalım. Burda *t bir array pointerı olsun, n de arrayın uzunlugu...

Bu fonksiyon, arrayin elemanlarını toplasın ve sonucu versin:



int topla(int *t, int n) //1.satır

{ //2.satır

int i; //3.satır

int toplam = 0; //4.satır

for(i=0; i<n; i++) //5.satır

{ //6.satır

toplam=*t + toplam; //7.satır

t++; //8.satır

} //9.satır

return toplam; //10.satır

} //11.satır

Bu fonksiyonun yaptıgı işi satır satır anlatalım:

1.satırda fonksiyonumuzu yazdık, 2. satırda fonksiyonumuzun yaptıgı işi anlatacagımız { } isaretlerinin ilkini actık.

3. satırda for dongusunde kullanacagımız degiskeni tanıttık. 4. satırda

arrayin elemanlarını toplayacagımız toplam degiskeninin tanıttık ve ilk degerini 0 a esitledik.

5. satırda for dongumuzu yazdık.dongumuz 0 dan baslayıp

arrayin uzunluguna kadar kendini tekrarlıycak. Mesela “int A[3]” diye tanımladığımı uzunluğu 3 olan bir arrayi bu fonksiyona sokacaksak

fonksiyonu şu sekilde kullanacaz main in icinde :

topla(A,3)

burda t, A ya esitlenecek n de 3 e esitlenecek. for dongusu 3 kere donecek.

7.satır da dongu her seferinde toplam degiskenine *t nin degerini ekleyecek.

donguye ilk girildiginde *t arrayin ilk elemanının degeri olacak. Sonra 8. satırda t, bir sonraki elemana

isaret edecek. Donguye tekrar girildiginde bu sefer *t arrayin 2. elemanının degerine esit oloacak... bu sekilde devam ederek toplam degiskenine arrayin her elemanı teker teker eklenecek. 10.satırda elde edilen toplam fonksiyonun cıktısı olacak...



yukardaki kodları birlestirerek bir ornek program yazalım:



#include<stdio.h>



int topla(int *t, int n);



main()

{

int Q[5] = {2,4,6,8,10} ;

int x;

x=topla(Q,5);

printf("%d",x);

return 0;

}



int topla(int *t, int n)

{

int i;

int toplam = 0;

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

{

toplam=*t + toplam;

t++;

}

return toplam;

}




Bu programı calıstırırsanız ekrana 2 4 6 8 ve 10 un

toplamını verecektir, sanırım 30 ediyor



son olarak pointerın pointerı diye bir şey var onu anlatalım:

Pointer da bir degişken olduguna gore ve bilgisayarın pointerın adresini aklında

tutabilmek icin onu da RAM de bir yere yazdıgına gore, bir pointer a da işaret eden bir pointer belirlenebilir.Yani pointerın pointerı… kafalar biraz daha karısacak



int **a;

int *b;

int c;



c=3;

b=&c;

a=&b;



yukardaki kodlarda b pointerı c integerına isaret ediyor, a pointer pointerı da b pointerına isaret ediyor.



a --> b --> c



seklinde...



c nin degeri 3, b nin degeri c nin memory adresi, a nın degeri de b nin memory adresi oluyor.



c degiskeni degeri : 3 , RAM adresi : 123456

b degiskeni degeri : 123456 , RAM adresi : 123460

a degiskeni degeri : 123460 , RAM adresi : 123464



seklinde bir RAM adresleri ve degisken degerleri tablosu oluşacaktır. RAM adreslerini kafadan attım tabiki...



printf("%d",a) ----> 123460 ı verir

printf("%d",*a) ----> 123456 yı verir

printf("%d",**a) ----> 5 i verir



pointerın pointerı iki boyutlu arraylerde kullanılabilir... A[2][3] gibi...

Ama bukadar ayrıntıya girip anlatamıycam yoksa yazının sonu gelmez

Benden size ana hatları ile pointerlar... Ayrıntıları ogrenmek size kalmıs...

Kafanıza takılan ayrıntılar, ogrenmek istediginiz şeyler yada anlamadıgınız noktalar olursa sorun forumda



Buraya kadar kafa karıstırabilecek bir iki şeyden bahsediyim.

Birincisi matemetiksel işlemlerde *p seklinde kullanılan bir pointer carpma işlemi olan

* isareti ile karışmaz merak etmeyin. mesela

a * *b;

seklinde bir ifade a carpı b pointerının işaret ettigi deger anlamına gelir.C, * leri birbirinden ayırmasını bilir merak etmeyin

İkincisi pointerı tanıtırken kullanılan * ile pointerın işaret ettigi degiskenin degeri anlamına gelen *

sempolunu birbirine karıştırmamak gerekir. Gene C buınları karıstırmaz ama siz karıstırabilirsiniz

mesela bir fonksiyonu tanıtırken

fonksiyon(int *p);

yazıldıgında "int *p" kısmında kullanılan * isareti p nin bir integer pointerı oldugunu anlatır.

pointer tanıtma isaretidir.

Misal başka bir fonksiyon tanıtıldıktan ve implement edildikten sonra main in icinde kullanırken mesela:



fonksiyon(*p);



dersek, buradaki * işareti ise p pointerının işaret ettigi degişkenin degeri anlamına geliyor...





Pointerlar sadece intergerlar icin kullanılmaz tabiki... mesela char degiskenlerşi ve string ler icin

de bir iki ornek yazalım:



char A[] = "radres";

seklinde bir string tanımlanınca A bu stringin ilk elemanına işaret eden bir pointerdır.

*A, r yi verir...



p=A;

p++;

yazdıktan sonra *p, a ya esittir.



yada



p=A;

*(p+3)='\0';



dersek



printf("%s",A);



bize “rad” ı verir. Cunku stringin 4. elemanının olan *(p+3) u stringin bitiş elemanı anmlamına gelen '\0' a eşitledik.



pointerlarla ilgili soyliyecegim son şey fonksiyonlarla degisken degerlerini degistirmektir.


DEVAMI ALTTA
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:50   Mesaj No:6

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Daha onceki fonksiyonlar dersimizde scope olayından bahsetmistik. Scopu main olan bir degiskeni bir fonksiyona vererek degerini degistiremiyorduk. Pointer kullanarak bunu becerebiliriz.

Simdi iki ornek yazacam. Biri main de kullanılan bir degiskenin degerini degistiremeyen bir fonksiyon

digeri ise pointer kullanarak degeri degistiren bir fonksiyon.

#include<stdio.h>



void degistir1(int a);



void degistir1(int a)

{

a=a+1;

}





void degistir2(int *a);



void degistir2(int *a)

{

*a=*a + 1;

}



main()

{

int x=5;

int *p;

p=&x;



degistir1(x);

printf("%d\",x);



degistir2(p);

printf("%d",x);



return 0;



}



bu programda mainde belirlenen x degiskeninin ilk degeri 5 e esitleniyor.

ardından p diye bir integer pointerı belirlenip p=&x; satırı ile x i işaret etmesi saglanıyor.

sonra degistir1 fonksiyonuna x veriiyor. printf komutu ile x in degerine bakılıyor. Program calıstırılırsa x in degerinin degistirilemedigi gorulecektir. Bunun sebebi fonksiyonlar dersinde anlatıldı.

Sonra degistir2 fonksiyonuna x in pointerı olan p veriliyor. Ardından printf ile tekrar x in degerine bakılıyor.

Program calısınca ekrana gelen ikinci degerin bu sefer degistirildigini ve x in yeni degerinin 6 oldugu

gorulecektir.



Bunun sebebi degistir2 fonksiyonuna scope olayının etki etmemesidir. Degistir2 nin kodlarına bakarsanız

aldıgı pointerın isaret ettigi degeri bir artırdıgını gorursunuz. Pointer direk olarak RAM deki “x” in adresine gidip

orda depolanan degeri degistiriyor. Bu yuzden x in yeni degeri sorgulandıgında RAM de ki x in adresine gidip degeri okuyan

bilgisayar degerin 6 oldugunu gorecek ve bize bu degeri verecektir.



Daha cok, bi suru anlatacagım şey var pointerlarla ilgili ama bir dokumanda bu kadar oluyor…

Bu temel pointer bilgisinden sonra siz program yaza yaza, C dokumanları okuya okuya pointerların marifetlerini kendiniz anlayacaksınız. Bu sefer odev yok, anca kafanızı toparlarsınız bu yazıdan sonra
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:50   Mesaj No:7

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 7 (Dosya işlemleri)

Sıra geldi hepimzin merakla bekledigi C de dosya acma, yazma, yani data kullanma olaylarına…
Şimdi yeni bir degisken daha ogrenencez. Degiskenimizin turu: FILE isminden de anlasıldıgı gibi dosyaları temsil eden bir degisken turu.bu. Ama file diye degil FILE olarak yazacaz unutmayın ki C buyuk harf kucuk harf ayrımı yapan bir dildir. Peki nasıl kullanacaz bu FILE degiskenini ? Diger degiskenler gibi soyle:
FILE *f;
Bu komutla f adında bir FILE degiskeni pointerı yaptık. Niye pointer olarak belirledik de normal bi degisken yapmadık diye merak ediyorsanız bunun sebebi dosya acma yazma ve okuma islemleri icin kullanacagımız hazır fonksiyonların input olarak pointer kabul etmeleridir. Simdi bu FILE pointerını kullanacagımız fonksiyonlara bakalım:
fopen , fclose , fprintf, fscanf , fputs, fgets adında fonksiyonları tanıyacaz ve kullanacaz. Bu fonksiyonlar stdio.h kutuphane dosyasında tanımlanmıstır. Once fopen:
FILE *fopen(char *dosyayolu, char *dosyaizni)
Seklinde tanımlanmıstır. Fonksiyonlar dersimizi hatırlarsak bu fonksiyonun nasıl kullanıldıgını anlarız hemen. Bastaki FILE * kısmından fonksiyonun cıktı olarak bir fILE pointerı verdigini goruyoruz. Parantez icindeki inputların turlerine bakarsak iki tane string aldıgını goruruz. Bunlardan ilki acacagımız dosyanın yolu, ikincisi ise dosyayı hangi iznle acacagımızdır. Yani yazmak icinmi, okumak icinmi, append etmek icinmi actıgımızı belirtecez. Bir ornekle gosterelim.
FILE *f;
Char *path=”c:\\ornek.txt”;
f=fopen(path,”w”);
bu kodlarla f adında bip FILE pointerı belirledik, sonra path adında bir string yaptık. Daha onceki string derslerimizde
char path[]=”c:\\ornek.txt”;
seklinde string olusturuyorduk. Simdi pointerları ogrendikten sonra char *path; seklinde de string belirleyebildigimizi ogrenmis olduk. Pointerlar dersinin ikinci kısmındaki pointerların arrayler le ve arraylerin de stringlerle iliksilerini incelerseniz olayı anlarsınız. Anlayamasanız sorun J . Burada diger bir dikkat edilecek nokta c:\ornek.txt yerine c:\\ornek.txt yazdık. İki tane \ kullandık. Bunun sebebi \ isaretinin stringlerde ozel bir karakter olması. \n seklinde alt satıra gecmemiz gibi. \ isaretinden sonra gelen karakterin ozel bir karakterle karıstırılmaması icin iki tane yazıyoruz.
Yukardaki kodların son satırında ise f pointerına fopen fonksiyonundan cıkan dosyayı atıyoruz. “w” iznini kullanarak. “w” yazmak icin demek. Simdi bu izinleri ve nasıl kullanıldıklarının baslıcalarını inceleyelim biraz.
r : Okumak icin acar

w: Yazmak icin acar, dosya varsa icindekiler silinir, yoksa

a: Appends; dosya zaten varsa acar yoksa olusturur, ve dosyanın sonuna yazar.











Artık elimizde bir dosya var ona istedigimizi yapabiliriz. Simdi dosyayadan nasıl okuyacagımızı ve nasıl yazacagımızı ogrenenlim. fprintf ve fscanf fonksiyonları:



Bu fonksiyonlar scanf ve printf fonksiyonlarına benzerler. Tek farkı input olarak bir de steam almalarıdır. Steam nedir ? stream bilgi alınıp verilen arabirimlerdir. Baslıca streamler stdin, stdout ve stderr dır.Bunlar sırasıyla standart input(girdi), standart output(cıktı) ve standart error(hata) anlamına gelir. Standart girdi klavyedir. Standart cıktı monitordur. Standart error ise bir program calısırken olusan hataların kaydedildigi sream dir. Scanf fonksiyonu stdin stream ini kullanır. Yani klavyeden girilen seyi okur. Printf ise stdout streamini kullanarak bilgiyi direk monitore gonderir. Bu ana steam lerden baksa srteam ler de olusturulabilir. Mesela bir FILE pointerı bilgi okunup yazılabilen bir steam olusturur. fprintf ve fscanf fonksiyonları ile steam olarak FILE pointerı gosterilir ve buradan bilgi alınıp yazılır.Simdi printf fonksiyonu ile yaptıgım seyi fprintf fonksiyon u ile kıyaslayabilecegimiz iki kod yazalım.



int x;

x=5;

printf(“x in degeri %d dir”,x);



Bu kodla ekrana su yazılır:



x in degeri 5 dir.



Simdi fprintf ornegi:



FILE *f;

İnt x;

f=fopen(“c:\\ornek.txt”,”w”);

x=5;

fpintf(f,”x in degeri %d dir”,x);



Bu kodlarla c:\ornek.txt adındaki dosya acılır. Eger boyle bir dosya yoksa olusturulur.Varsa acılırken icindeki tum bilgiler silinir. Sonra bu text dosyasına “x in degeri 5 dir” yazılır. Goruldugu gibi printf ve fprintf arasındaki tek kodlama farkı, fprintf in parantezlerinde basa steam olarak actıgımız dosyayı temsil eden FILE pointerını yazmamız. Ve boylece ekrana bir yazı yazılacagına actıgımız dosyaya yazılıyor.



fscanf de cok benmzer sekildedir.



Scanf:

Scanf(“%d”,&y)

Fscan:

fscanf(f,“%d”,&y)

fscnaf ile f dosyasınındanki ilk veri okunur ve y degiskenine atanır. Tıpkı scanf ile klavyeden gelen bilginin okunup degiskene atanması gibi.



fclose fonksiyonu ile de dosya ile olan isimiz bitince dosyamızı kapatırız.,



fclose(f)



seklinde… Simdi buraya kadar ogrendiklerimizle basit bir program yazalım. Programımız calısınca c:\radres.txt diye bir dosyanın ilk kelimesini okusun(once radres.txt diye bir dosya olusturup sonra da icine biseyler yazıp kaydetmemiz gerekiyor tabi…)sonra da c:\ornek.txt diye bir dosya olusturup o dosyaya radres.txt den okudugu kelimeyi yazsın:



#include<stdio.h>



main()

{

FILE *radres;

FILE *ornek;

char *rad;



radres= fopen("c:\\radres.txt","r"



if(radres==NULL)

{

printf("radres.txt bulunamadı"

exit(-1);

}



fscanf(radres,"%s",&rad);

ornek=fopen("c:\\ornek.txt","w&quot ;

fprintf(ornek,"%s",rad);

fclose(radres);

fclose(ornek);



return 0;

}






yukardaki kodlarda ki if radres.txt idye bir dosya belirtilen yerde yoksa. Yani bu durumda radres FILE pointerına dondurulen deger NULL yani bossa ekrana “radres.txt bulunamadı” yazıp programdan cıkıyor…



Simdi fgets ve fputs fonksiyonlarını inceleyelim. String dersinde de soyledigimiz gibi bu fonksiyonlar scanf ve printf den farklı olarak string okuma ve yazma icin ozellesmis gonksiyonlardır. Scanf ve fscanf le belirtilen kaynaktan bir string okuttugumuzda ilk kelimeyi okurken gets ve fgets tum satırı okur. Demekki bir dosyadan tum satırı okumak yada bir satır yazdırmak istiyorsak fgets ve fputs fonks,yonlarını kullanacaz. Once gets ve puts un kullanımını hatırlayalım.



gets(buf);



seklinde bir komutla ekrandan tum satırı okutup buf stringine cumleyi atıyorduk. fgets ise su sekilde kullanılıyor.



fgets(buf,25,f);



buradaki buf okunan stringi atayacagımız degisken. 25 maksimum kac karakter okuyacagımızı belirtiyor. f ise okunacak steam i yani dosyayı temsil eden FILE pointerının adı oluyor.



puts(buf);



buf stringini ekrana bir satır olarak yazdırır ve alt satıra gecer…



fputs(buf,strlen(buf),f);



burada, buf dosyaya yazılacak olan stirng oluyor. strlen(buf), buf stringinin kac karakterden olustugunu belirten bir fonksiyon. Bu fonksiyonu kullanabilmemiz icin programımızın basına #include<string.h> satırını dahil etmemiz lazım. Cunku strlen fonksiyonu string.h kutuphane dosyasında bulunuyor. Bu fonksşyonu kullanmak yerine bir sayı da yazabilirdik. Yazdıgımız sayı kadar karakter yazılacaktı f dosyasına.



Simdi birde feof diye bir fonksiyon var onun da ne oldugunu bilmemiz lazım. Bu fonksiyon okunan dosyanın sonuna gelip gelmedigimizi kontrol ediyor.



int feof(FILE *f);



seklinde kullanılıyor. Yani girdi olarak bir FILE pointerı alıyor ve cıktı olarak bir tam sayı donduruyor. Eger fonksiyona verilen dosyanın sonuna gelinmemisse 0 degerini donduruyor.

Mesela bir dosyanın sonuna gelip gelmedigimiz ogrenmek icin bir if yazalım:



if ( feof(f) )

{

//burada eger dosyanın sonuna gelindiyse yapılacak kodlar yazılacak mesela…

}



yukardaki kodla eger f dosyasının sonuna gelinmemisse feof(f) 0 degerini dondurecek ve 0, if tarafından yanlıs olarak algılanacak. Eger dosyanın sonuna gelinmisse feof(f) 0 dan farklı bir deger dondurecek ve if bunu dogru olarak algılyıcak…



Simdiye kadar ogrendiklerimizi kullanarak bir program yazalım. Mesela bu program bir text dosyasının hepsini okusun ve icinde belli bir kelimenin kac tane bulundugunu hesaplasın.

Bu programı yazarken string.h da bulunan bir string fonksiyonu kullanacaz. strcmp adlı bir fonksiyon. Bu fonksiyon bir iki stringi bir biri ile kıyaslıyor. Ve eger ilki buyukse 1, ikincisi buyukse -1 , iki string bir birine esitse 0 degerini donduruyor. Buyukden kastım alfabede hangisinin once geldigi anlamında. Ama yazacagımız programda bizi sadece esit olup olmadıkları ilgilendirecek. İste program:



#include<stdio.h>

#include<string.h>



main()

{

FILE *f;

char buf[255];

char dosya[255];

char kelime[255];

int sayac=0;





printf("aranacak kelimeyi girin: "

gets(kelime);



while(1)

{

printf("dosyanin adini yoluyla birlikte girin: "

gets(dosya);

if((f=fopen(dosya,"r&quot)==NULL)

{

printf("dosya bulunamadı "

continue;

}

else

break;

}

while( !feof(f) )

{

fscanf(f,"%s",&buf);



if( strcmp(buf, kelime)==0)

sayac++;

}

fclose(f);

printf("%s dosyasında %d tane %s kelimesi bulundu\n",dosya,sayac,kelime);



return 0;

}






Bu programı inceleyin gayet basit bir yapısı var. Ödev verelim . Mesela combo listler vardır bilirsiniz. User:Password formatında alt alta user ve passwordlar vardır bu combo listlerde. Odevimiz bu sekilde yazılmıs bir combo listin userlarını alt alta bir dosyaya, passwordlerini alt alta baksa bir dosyaya yazarak ayıracak bir program yapmak. Bilgisayarınızda combo list yoksa eger. Siteye eklediğim bir combo list adresi vereyim hem bu list işinize de yarar belki:



Linklerin Görülmesine İzin Verilmiyor
Linki Görebilmek İçin Üye Ol veya Giriş Yap



Odev için ip ucu:



radres:avent



şeklindeki bir stringi radres ve avent seklinde ayırmak icin “:” karaktrinin stringin kacıncı elemanı oldugunu bulmak lazım. Bunu icin de string.h library dosyasında bulunan strstr fonksiyonunu kullanabilirsiniz.



x=strstr(buf, ”:” );



seklinde yazılırsa buf stringinin icinde kacıncı elemanın “:“ oldugunu x char pointerına atanır… aslında direk stringi ayıran daha kolay bir fonksiyon var ama solemicem biraz string antremanı yapmış olursunuz .
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Alt 20 January 2009, 15:50   Mesaj No:8

CoNQueRoR_61

Papatyam Usta Üyesi
Avatar Otomotik
Durumu:CoNQueRoR_61 isimli Üye şimdilik offline konumundadır
Papatyam No : 1397
Üyelik T.: 20 January 2009
Arkadaşları:0
Cinsiyet:
Memleket:istanbul
Yaş:35
Mesaj: 131
Konular:
Beğenildi:
Beğendi:
Takdirleri:10
Takdir Et:
Konu Bu  Üyemize Aittir!
Standart Ynt: C Dökümanları

Temel C Dokümanları 8 (Structer'lar[Yapılar])

Bu dokumana kadar C nin temelleri hakkında bir cok şey ogrendik. Benim ogretmeyi dusundugum tek bir ana konu kaldı: Structure lar…
Structure ın turkce deki anlamı yapı demek. C de yapılar olusturmak mumkun. Yapı kelimesinden kasıtın tam olarak ne oldugunu ancak bir ornekle anlatabilirim sanırım:
Mesela ogrenci diye bir yapı belirleyelim. Bu yapının elemanları olacaktır. Zaten structure ların olayı kendi elemanları olmasıdır. Bu elemanları biz istedigimiz sekilde belirleyebiliriz..
Bu elemanlar C deki degiskenler den olusacak. Ogrenci yapımızın elemanlarını belirleyelim:
İsim
Soyisim
Okul
Numara
Bunlar ogrenci structer inin elemanları olsun. Simdi bu isi C de nasıl yapacagımız bakalım:
struct ogrenci

{

char isim[10];

char soyisim[20];

char okul[20];

int numara;

} ;



yukardaki kodlarla struct tanımını kullanarak ogrenci adında bir structer tag ı yapmıs olduk. Bu tag ın icinde istedigimiz elemanları belirledik. buradan sonra ogrenci, bir cesit tanım oldu.

Mesela int, bir tanımdır. Tamsayıları tanımlar.

int x;

yazarsak x diye bir tam sayı belirlemis oluruz int tanımını kullanarak. Aynı sekilde yukarda belirledigimiz ogrenci tanımını kullanarak ogrenci tanımına uygun bir structure degiskeni belirleyebiliriz. Su sekilde:



ogrenci Ali;



Bu satırla Ali adında bir ogrenci structure ı yapmıs olduk. Ali nin bazı ozellikleri var. İsim, soyisim, okul, numara gibi. Simdi bu ozellikleri belirleyelim. Ali nin icindeki bir ozelliğe (elemana) ulasabilmek icin nokta isaretini kullanacaz.:



Ali.numara=567;



Bu satırla Ali yapısının numara elemanını 567 olarak atadık. Şimdi ismini ve diger ozelliklerini belirleyelim. Diger degiskenler string oldugu icin kolay bir eşitlikle belirlenemiyor. Bu işi strcpy fonksiyonu ile yapazac. Onceki derslerimizde strcpy'nin kullanımından bahsetmistik.



strcpy(Ali.isim,”Ali”);

strcpy(Ali.soyisim,”Ozturk”);

strcpy(Ali.okul,”Mehmetcik ilkokulu”);



Boylelikle Ali structure ının tum elemanlarını belirledik. Şimdi bu kodları birlestirip bir program yapalım ve programımız en sonunda Ali yapısının tum ozelliklerini ekrana yazdırsın.



#include<stdio.h>

#include<string.h>



main()

{

struct ogrenci

{

char isim[10];

char soyisim[10];

char okul[25];

int numara;

};

ogrenci Ali;

Ali.numara=567;

strcpy(Ali.isim,"Ali"

strcpy(Ali.soyisim,"Ozturk"

strcpy(Ali.okul,"Mehmetcik ilkokulu"



printf("Ali'nin numarasi : %d\n",Ali.numara);

printf("Ali'nin ismi : %s tabiki \n",Ali.isim);

printf("Ali'nin soyismi : %s\n",Ali.soyisim);

printf("Ali'nin okulu : %s",Ali.okul);

scanf("%d",&Ali.numara);

return 0;

}






Peki niye ogrendik bu structer ları ? Bu yapılar neye yarıyor ? Bu structure denen melet duzenli, daha kullanışlı ve daha kolay programlar yazmaya yarıyor. Mesela bir telefon rehberi yapacaz. Rehberdeki her kayıt icin isim soyisim numara adres alacaz. Bunların hepsi değiskenlere kaydedilmek zorunda. Her kayıt icin 4 tane degisken belirlersek. 30 kisilik bir rehber olusturmak icin 30*4= 120 tane degisken belirlemek gerekir. Ama biz array kullanarak bu degiskenlerin sayısını biraz azaltabiliriz. Ama genede cok sayıda ve karısık olur. Ama structure kullanırsak sadece bir structure arrayi ile tum kayıtları alabiliriz.



struct rehber

{

char isim[10];

char soyisim[25];

int TelNo;

char adres[255];

} ;



rehber kayıtlar[30];



yukardaki kodlarla; kayıtlar adında, 30 tane elemanı olan rehber yapısı arrayi olusturduk. Artık bir iki loop kurarak tum kayıtları kaydedebilir okutabiliriz. İşte bu kadar duzenli ve kolaylastırıcı bir etkisi var bu structure ların. Simdi 3 tane kayıt alan ve bu kayıtları aldıktan sonra ekrana yazdıran bir telefon rehberi similasyonu yazalım Kolaylık olsun diye adres ozelligini de iptal ediyorum:







#include<stdio.h>

#include<string.h>



main()

{



struct rehber

{

char isim[10];

char soyisim[10];

char adres[25];

int TelNo;

};



int i;

char buf[255];

rehber kayit[3];



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

{

printf("%d. kayit icin telefon numarasini gir:",i+1);

scanf("%d",&kayit.TelNo);

gets(buf);

printf("%d. kayit icin isim gir:",i+1);

gets(kayit.isim);

printf("%d. kayit icin soyisim gir:",i+1);

gets(kayit.soyisim);

}

puts("kayitlar alindi"

puts("kayitlar ekrana geri veriliyor:"

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

{

printf("%d. Kayit:\n",i+1);

puts("------------"

printf("isim: "

puts(kayit.isim);

printf("soyisim: "

puts(kayit.soyisim);

printf("Telefon numarasi: %d\n",kayit.TelNo);

puts("*******************************"

}

return 0;

}






Structer mantıgını anlamak onemli bir şey. Cunku bu mantıgın gelistirilmisi obje yonelimli programlama oluyor. C++ a gecerken Obje yonelimli programlamayı iyi anlamamız lazım.

Structure mantıgı dogrultusunda ilerde obje yonelimli programlamaya da gececez.



Odev: Kendinize gercek bir telefon rehberi yapın .Bir text dosyasına katıtları yazsın ve orda saklasın. Gerektiginde gene o dosyadan okusun. Programınızı gelistirebildiginiz kadar gelistirin. Bir telefon rehberinin sahip olabilecegi tum ozellikleri zamanla eklemeye calısın. İsime gore sıralama, isim yazınca o isme ait telefonu bulma gibi felan… Artık C ye dair ana hatlarıyla hemen herseyi biraz biliyorsunuz…

Bu Temel C derslerinin sonuncusuydu… Benim temel olarak ögretmek istediklerim bu kadar. Bu işin bir sürü teferruatı var tabiki. Bu temel ile tüm teferruatları kendiniz öğrenebilirsiniz diye düşünüyorum.


Her dersin sonunda bir ödev var ve diğer derste bir önceki dersin ödevinin cevabı var bakmıyarak kendinizi geliştirebilirsiniz...
__________________
Biz Bu Hallere Düşecek Adammıydık ???
Alıntı ile Cevapla
Cevapla

Bookmarks

Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)
 
Seçenekler

Yeni Sayfa 1

www.papatyam.org Ana Sayfa

Tefekküre Davet Köşesi

Papatyam Sosyal Medya Guruplarımıza Katılın

                       Instagram         

Papatyam alemdarhost.com sunucularında barındırılmaktadır.