eln1001 – bilgisayar programlama ı
Transkript
eln1001 – bilgisayar programlama ı
ELN1001 – BİLGİSAYAR PROGRAMLAMA I DİNAMİK BELLEK YÖNETİMİ TEMEL G/Ç FONKSİYONLARI Dinamik Bellek Tahsisi Tanımlanmış olan dizilere eleman sayısı ve elemanlarının tiplerine göre, sistem belleğinde bir yer ayrılacaktır. Diziler, bu şekilde bir yapıya sahip oldukları için, statik veri yapıları olarak adlandırılır. Programın başında kullanılıp daha sonra ihtiyaç duyulmayacak bir dizi için ayrılan bellek alanı, programın sonuna kadar korunacaktır. Dinamik Bellek Tahsisi, bir bellek alanını yalnızca ihtiyaç olduğu anda meşgul etmek, ihtiyaç olmadığı durumda ise diğer parçaların kullanımına bırakmaktır. 1 Dinamik Bellek Tahsisi C programlama dilinin <stdlib> kütüphanesi, bu tür bir dinamik bellek tahsisi için – malloc, calloc ve realloc – üç ayrı fonksiyona sahiptir. Bu fonksiyonlar, dinamik dizileri oluşturmak ve değiştirmek için kullanılmaktadır. Önceki bölümde gördüğümüz gibi, bir diziye adreslenen bir işaretçi, bir dizi gibi düşünülebilir. Bundan dolayı, malloc veya calloc ile ayırt edilen bellek alanı, bir diziymiş gibi düşünülebilir. Bu durumda, malloc veya calloc fonksiyonu, bir dizi için dinamik olarak bir bellek parçası ayırır. Dinamik Bellek Tahsisi calloc prototipi: void *calloc(size_t nmemb, size_t size) nmemb: dizi elemanlarının sayısı size: dizinin her elemanının boyutu calloc fonksiyonu kullanıldığı anda, dizinin tüm elemanları sıfıra eşitlenir. Fonksiyonun dönüş değeri, bellek tahsisi gerçekleşmişse, o bellek adresini işaret eden işaretçi, bellek tahsisi gerçekleşmemişse, NULL değeridir. calloc ile malloc arasındaki temel fark, calloc‟ un bellek tahsisi yapıldığında belleği temizlemesi(tüm elemanları sıfır yapma) ve ondan sonra tahsis etmesi, malloc‟ un ise belleği temizlemeden bir bellek tahsisi gerçekleştirmesidir. 2 Dinamik Bellek Tahsisi malloc prototipi: void *malloc(size_t size); size: tahsis edilecek bölgenin byte cinsinden uzunluğu Fonksiyonun dönüş değeri, bellek tahsisi gerçekleşmişse, o bellek adresini işaret eden işaretçi, bellek tahsisi gerçekleşmemişse, NULL değeridir. int *ptr; … … … ptr = (int*) malloc (100); (Bellek alanı ayrılıyor) … … … free ptr; (Bellek alanı serbest bırakılıyor) Dinamik Bellek Tahsisi realloc fonksiyonu ise, malloc, calloc veya realloc ‟a yapılan bir önceki çağrıda oluşturulmuş olan alanın boyutunu değiştirmek için kullanılmaktadır. Orijinal alanın içinde bulunan eleman değerlerinde bir değişiklik gerçekleştirilmez, bununla birlikte, dizinin sonuna ilave boyut kadar bellek parçası eklenir. realloc prototipi: void *realloc(void *ptr, size_t, size); ptr: boyutu değiştirilecek orijinal bellek alanının adresi, size: dizinin yeni boyutu Eğer ptr işaretçisi NULL ise, realloc malloc ile aynı işlevi görecektir. Eğer boyut 0 ise ve ptr NULL değilse, ptr‟nin işaret ettiği bellek alanı serbest bırakılır. 3 Dinamik Bellek Tahsisi Eğer ptr NULL değil ve boyutta sıfır değilse, realloc, dizi için bellekte yeni uzunluğa sahip bir yer tahsis etmeye çalışır. Eğer yer tahsisi başarılı olursa, realloc fonksiyonu, ayrılan belleğin adresini gösteren bir işaretçi döndürür. Eğer yer tahsisi bir sebepten başarılı olmazsa, realloc fonksiyonu, yer tahsisinin başarılı olmadığını göstermek için bir NULL işaretçisi döndürür. free() fonksiyonu, yer tahsisini iptal eder, böylece ilgili alan, başka programların kullanabilmesi için boşaltılmış olur. Dinamik Bellek Tahsisi #include <stdio.h> #include <stdlib.h> int main() { int *ptr; ptr = (int *) malloc(sizeof (int) * 5); /* yer ayrılıyor */ if (ptr == NULL) { printf("bellek yetersiz!..\n"); return 0; } for (i = 0; i < 5; ++i) /* 2 */ ptr[i] = i; ptr = realloc(ptr, sizeof(int) * 10); /* ayrılan yer genisletiliyor */ if (ptr == NULL) { printf("bellek yetersiz!..\n"); return 0; } return 0; } 4 TEMEL G/Ç FONKSİYONLARI Temel Giriş/Çıkış Fonksiyonları C Programlama dilinde yazılmış pek çok program kullanıcıdan giriş alma ve kullanıcıya bir çıkış üretme ihtiyacını duyar. Belirli C fonksiyonları, girişleri dış birimlerden doğrudan stdin (standard input stream) aracılığıyla alır. stdin, normalde bilgisayar klavyesidir, fakat daha farklı giriş elemanlarından da giriş alınabilir. Veri, çoğunlukla stdout (standart output stream) aracılığı ile dış birimlere gönderilir. stdout, çoğunlukla bilgisayar ekranı olarak düşünülür, fakat daha farklı dış birimlere de çıkış gönderilebilir. Flash disk veya yazıcılara gönderilen çıkış da stdout kanalları üzerinden gerçekleştirilir. Ayrıca stderr olarak isimlendirilmiş bir standart hata kanalı(standard error stream) mevcuttur. stderr kanalı, hata mesajlarını ekrana bastırmak için kullanılan bir kanaldır. 5 Temel G/Ç Fonksiyonları GİRİŞ ÇIKIŞ scanf printf getchar putchar getch putch getche puts gets Giriş Fonksiyonları - scanf scanf fonksiyonu kullanıcıdan giriş almak için kullanılır. stdin kanalı üzerinden, genellikle klavye olan dış birimden okuma gerçekleştirir. scanf prototipi: scanf(“D.B.”, &Degisken); D.B. Dönüşüm Belirteci, kullanıcı tarafından girilen verinin tipi burada belirtilir. &: Değişkenin adresini gösteren operatör Degisken: Okunan değerin içine yazılacağı değişken Girişleri okumak için kullanıcının „ENTER‟ tuşuna basmasını bekler. Geri dönüş değeri olarak, okuyup ilgili değişkene yazdığı değer sayısını döndürür. Dosya sonuna ulaşmış ise EOF karakterini döndürür. 6 Giriş Fonksiyonları - scanf scanf '%d' : Giriş tamsayısını işaretli ondalık (decimal) bir sayı olarak kabul eder. '%i' : Girişi işaretli bir tamsayı olarak alır. '%d' ye benzerdir, fakat "0x" ile başlarsa sayıyı onaltılık (hexadecimal) ve “0“ ile başladığı zaman sayıyı sekizlik (octal) olarak alır. Örneğin, "031" girişi '%d' kullanılırsa 31, '%i' kullanılırsa 25 olarak okunur. '%u' : İşaretsiz (unsigned) int, short veya char olarak okunur. '%f' : Normal (sabit noktalı) notasyonla kayar noktalı (floating-point) sayıları okur. '%g', '%G' : Kayar noktalı tamsayıyı hem normal hem de exponensiyel şekliyle okur. '%g' küçük harfleri and '%G' büyük harfleri kullanır. '%x', '%X' : Bir tamsayıyı onaltılık(hexadecimal ) sayı olarak okur. '%o' : Bir tamsayıyı sekizlik (octal) sayı olarak okur. '%s' : Karakter dizisini(character string) okur. Scan işlemi boşluk karakteri ile(whitespace) sonlandırılır. Karakter dizisinin sonunda bir (null character ) mevcuttur, bu da ayrılan bellek alanının girilenden asgari bir fazla olmasını gerektirir. '%c' : Giriş olarak tek karakter (char) alır. null karakter ilave edilmez. '(space)': Boşluk (whitespace ) karakterler için kullanılır. '%lf' : double tipinde kayar noktalı sayıları alır. 7 Giriş Fonksiyonları - getchar() Enter tuşuna ihtiyaç duyar. Tek karakter okumak için kullanılır. Prototipi : int getchar(void); Dönüş değeri : Geri dönüş değeri klavyeden alınan karakterin ASCII tablosundaki sıra numarasını gösteren int türünden bir sayıdır. Klavyeden basılan karakterin “echo” su ekranda görülür. stdio.h, programa dahil edilmelidir. Giriş Fonksiyonları - getch() Tek karakter okumak için kullanılır. Enter tuşuna ihtiyaç duymaz. Kullanımı : int getch(void); Dönüş değeri : Geri dönüş değeri klavyeden alınan karakterin ASCII tablosundaki sıra numarasını gösteren int türünden bir sayıdır. Klavyeden basılan karakterin “echo” su ekranda görülmez. conio.h, programa dahil edilmelidir. 8 Giriş Fonksiyonları - getche() Tek karakter okumak için kullanılır. Enter tuşuna ihtiyaç duymaz. Kullanımı : int getche(void); Dönüş değeri : Geri dönüş değeri klavyeden alınan karakterin ASCII tablosundaki sıra numarasını gösteren int türünden bir sayıdır. Klavyeden basılan karakterin “echo” su ekranda görülür. conio.h, programa dahil edilmelidir. Giriş Fonksiyonları – gets() stdin kanalından karakter dizisi okumak için kullanılır. Fonksiyon prototipi: char *gets(char *s); s: okunan bilginin yerleştirildiği işaretçi gets() fonksiyonu, yeni satır karakteriyle karşılaşıncaya kadar olan tüm karakterleri okuyarak değişkenin işaret ettiği adrese atar. Fonksiyon başarıyla çalıştırıldığı zaman, fonksiyonun geri dönüş değeri okunan karakter dizisinin kendisi olur. Fonksiyon başarısız olursa, NULL değerini döndürür. 9 Çıkış Fonksiyonları - Printf printf fonksiyonu kullanıcıdan giriş almak için kullanılır. stdout kanalı üzerinden, genellikle ekran olan dış birime çıkış üretir. printf prototipi: printf(F.K.D,degisken); F.K.D: Format Kontrol Dizisi, dönüşüm belirtecini, bayrakları, alan genişliklerini, yaslamayı, kesinlik derecesini ve değişmez karakterleri içerir. Değişken: Çıkış olarak gönderilecek değeri turan değişken F.K.D: Noktalı sayıların yuvarlanması veya kısaltılması Çıkışların sağa veya sola yaslanması Sütun yapılarının oluşturulması Belirli noktalara değişmez karakterlerin yerleştirilmesi Kayan noktalı sayıların ondalık olarak gösterimi İşaretsiz tamsayıların sekizlik veya onaltılık şekline dönüştürülmesi Tüm veri tiplerinin tablo şeklinde yazdırılması Geri dönüş değeri olarak, yazdığı karakter sayısını döndürür.Hata oluştuğunda negatif değer döndürür. printf, Dönüşüm Belirteçleri 'd': İşaretli tamsayı(decimal) 'i': İşaretli Tamsayı(integer) 'o': İşaretsiz sekizlik(octal) sayı 'u': İşaretsiz(unsigned) tamsayı 'x' veya 'X': İşaretsiz onaltılık (hexadecimal) tamsayı 'h' ve 'l': (short) veya (long) tamsayı 'e' veya 'E ' : Kayar noktalı sayının exponensiyel gösterimi. 'f': Kayar noktalı sayıların sabit noktalı (fixed-point) gösterimi. 'g' veya 'G': Kayar noktalı sayının değerine göre sabit-noktalı veya exponensiyel gösterimi. 'L': (Long) double tipinde gösterim. 'c' : Karakter gösterimi 's' : Karakter dizisinin gösterimi 10 printf, Gösterim Bilgisi Verinin yazdırılacağı alanın kesin boyutları alan genişliği ile belirlenir. Eğer alan genişliği yazdırılacak sayının genişliğinden büyük ise veri alan içinde otomatik sağa dayanır. %[alan_genişliği][.duyarlılık]dönüşüm_belirteci Tamsayılarda duyarlılık : Eğer yazdırılan değer belirtilen duyarlılıktan daha az basamağa sahip ise sayının önüne fark kadar sıfır konur. Tamsayılar için varsayılan duyarlılık değeri 1‟dir. Ondalık sayılarda duyarlılık : Ondalık kısımda yazdırılacak basamak sayısıdır (e, E, f için). Yazdırılacak önemli basamakların sayısıdır (g ve G için). Duyarlılık orijinal değerdeki ondalık, basamak sayısından küçük ise yuvarlama olur. Karakter dizilerinde duyarlılık yazdırılacak karakter sayısıdır. Çıkış Fonksiyonları – putchar() stdout çıkış kanalının geçerli pozisyonuna tek karakter yazmak için kullanılır. Fonksiyon prototipi: int putchar(int c); c: girilen karakterin ASCII değeri Geri dönüş değeri olarak yazılan karakteri geri döndürür. Hata oluştuğunda veya dosya sonuna ulaşıldığında EOF karakteri döndürülür. stdio.h dosyası programa ilave edilmelidir. 11 Çıkış Fonksiyonları – puts() stdout çıkış kanalına bir karakter dizisi yazdırmak için kullanılır. Fonksiyon prototipi: int puts(const char *s) s ile gösterilen karakter dizisinin stdout‟a gönderir. En sona da „yeni satır‟ karakteri ilave eder. Karakter dizisinin en sonundaki NULL karakteri yazdırılmaz. Eğer fonksiyon başarılı olursa, pozitif bir değer döndürür. Eğer bir hata oluşursa, EOF gönderir ve errno değişkeninin içine hatanın kodunu yazar. stdio.h dosyası programa ilave edilmelidir. ÖDEV ctype.h kütüphanesinde bulunan tüm fonksiyonlar araştırılacak, ne işe yaradıkları öğrenilecek, ve her biri için basit bir uygulama örneği gerçekleştirilecektir. Laboratuarda, bu fonksiyonlarla ilgili çalışmalar gerçekleştirilecektir. 12