Temel Bilgisayar Programlama Ara Sınav Çalışma Notları (Dr. Övünç ÖZTÜRK, Dr. Tahir Emre KALAYCI) (İnşaat Mühendisliği ve Gıda Mühendisliği Grupları İçin) Temel Kavramlar Programlamayı bir problemi çözmek için yaparız. Her bir alanın da kendine özgü problem çözme yöntemi vardır. Programlama açısından problem çözmede iki aşamadan söz edebiliriz: 1. Problem çözme aşaması a) Problemin tanımlanması b) Çözümün ana hatlarının ortaya konulması c) Ana hatlara bağlı olarak bir algoritma geliştirilmesi d) Algoritmanın doğruluğunun sınanması (çeşitli örnek girdilerle) 2. Gerçekleştirim aşaması a) Hazırlanan algoritma belirli bir programlama diline dönüştürülür (bu ders açısında bu dil C programlama dilidir) b) Program bilgisayarda derlenir ve çalıştırılır c) Programın belgelemesi ve bakımı (hataların düzeltilmesi, yeni özellikler eklenmesi, vb.) yapılır Özetleyecek olursak, yazılım geliştirme açısından yapılması gerekenler dört aşamada gösterilebilir (yazılım geliştirme aşamaları): 1. Problemi belirleme ve anlama (Analiz-Çözümleme) 2. Algoritma hazırlama (Tasarım) 3. Program geliştirme (Gerçekleştirim) 4. Programı çalıştırma ve doğruluğunu değerlendirme (Sınama, Bakım, Kullanım, Kurulum) Algoritma Nedir? Algoritma bir problemi çözmek için ortaya koyduğumuz çözüm adımlarıdır. Algoritmaya ilişkin verilebilecek farklı tanımlar olsa da, aşağıdaki iki tanım bizim için yeterlidir: • Sonlu bir işi tanımlamada kullanılan, açık ve seçik tanımlanabilen ve yürütülebilen ardışık adımlardan oluşan kümedir (Özkan, 2003). • Algoritma; matematik ve bilgisayar bilimlerinde bir işi yapmak için tanımlanan, bir başlangıç durumundan başladığında açıkça belirlenmiş bir son durumda sonlanan, sonlu adımlar (işlemler) kümesidir (Vikipedi, Algoritma başlığı). Algoritma Geliştirilmesi Algoritma geliştirirken ilk olarak problem ele alınarak iyice anlaşılır. Sonraki aşamada bu problemin çözümü üzerine düşünülür ve bir çözüm bulunur. Bulunan bu çözümün adımları bizim algoritmamızı oluşturacaktır. Algoritma, problemin çözümünü oluşturan adımlardır, o adımların akışıdır. Örnek: Elektronik kasiyerin ürün satma algoritması (Çebi, 2006) 1. Satın alınan ürüne bak 2. Ürünün fiyatını bul 3. Müşteriden parayı al 4. Alınan paradan ürün fiyatını çıkar ve para üstünü bul 5. Para üstünü ver Algoritma gösterimi için sıklıkla kullanılan iki yöntem vardır. Biri sözde kodlar, diğeri de akış şemasıdır. Sözde kodlar herkesin anlayabileceği ve rahatlıkla bir programlama diline çevrilebilecek basit komutlardan oluşan bir dildir. Sözdekodun temel işlevi program geliştirmeye geçmeden algoritmayı oluşturmak, üzerinde düşünebilmek ve tartışabilmektir. Sözdekodlar gibi akış şemaları da bir problemi çözen algoritmayı anlaşılır hale getirmek için kullanılan bir araçtır. Geometrik şekillerden yararlanarak algoritmayı göstermeye yarar. Basit ve yapısal akış şemaları vardır. Basit akış şemaları belirli anlamlara sahip geometrik şekillerden yararlanır (Özkan, 2003): • İşlemleri gösteren simgeler • Veri giriş ve çıkış işlemlerini gösteren simgeler • Verilerin saklanmasıyla ilgili simgeler Program (Elkner, 2010) Program hesaplamayı gerçekleştirmek için gereken, birbirini izleyen yönergelerden (komutlardan) oluşan yapıdır. Hesaplama matematiksel (bir eşitsizlik sisteminin çözülmesi, polinomun kökünün bulunması) olabilir, sembolik (bir belge içinde metin arama, değiştirme, program derleme) bir hesaplama olabilir. Temel yönergeler aşağıda listelenmiştir: • Girdi: klavyeden, dosyadan veya başka bir aygıttan veriyi alma. • Çıktı: ekranda veriyi görüntüleme veya veriyi bir dosya veya başka bir aygıta gönderme. • Matematik: Toplama, çarpma, vb. gibi bazı temel matematiksel işlemleri gerçekleştirme. • Koşullu yürütme: belirli durumlar için sınama yaparak bu sınama sonuçlarına göre deyimleri uygun sırada çalıştırma. • Tekrarlama: bazı eylemleri ya değiştirmeden ya da değişikliklerle tekrar tekrar yürütme. Şu ana kadar kullandığımız her program, ne kadar karmaşık olursa olsun, yukarıdakilere benzeyen komutlarla geliştirilmiştir. Programlama Dilleri Çözülecek olan problemin niteliğine göre seçilmelidir. Programlama dillerinin hepsi simgeseldir, bilgisayarın anlayabileceği işlemleri insanların da anlayabileceği simgelerle ifade etmek için kullanılırlar. Simgeler (kodlar) derleyici (veya yorumlayıcı) yardımıyla bilgisayarın anlayabileceği bir biçime (makine kodu, dili) çevrilirler. Simgesel kodlar kaynak kod, makine diline çevrilmiş kod ise nesne kodu olarak adlandırılır. Programlama dilleri aşağıdaki şekilde sınıflandırılmaktadır: • Makine dilleri: Doğrudan makine kodlarından oluşur. • Assembly dilleri: Anımsatıcı simgelerin kullanıldığı dillerdir. • Yüksek düzey diller: Komutlar yapılacak işlemin İngilizce karşılığı veya onu anımsatıcı kodlardır (kelimelerdir). • Dördüncü kuşak diller: Daha esnek, çoğu kodu otomatik oluşturan dillerdir. Az kod ile çok iş anlayışı benimsenmiştir. Derleyici: Bir programlama dilinde yazılmış olan kaynak kodunu makine diline - dolayısıyla çalışabilir bir sürüme - çeviren yazılımdır. Programlamanın Temel Kavramları Yapısal programlama dilleri açısından ortak olan bazı temel kavramlar aşağıda listelenmiştir: • Değişkenler: değeri program çalışırken değişen büyüklükler. • Sabitler: değeri programın çalışması boyunca sabit kalan büyüklükler. • Atama işlemleri: bir değişkene farklı değerleri temsil edebilmesi için farklı değerler yerleştirilmesi/atanması • Veri türleri: verinin içerdiği bilgiyi belirlemek için kullanılan türlerdir (tamsayılar, gerçel sayılar, kesirli sayılar, mantıksal değerler, diziler/katarlar). • Veri yapıları: veriyi problemin türüne göre düzenlemede kullanılan ve üzerinde işlemler yapılabilen yapılardır (diziler, listeler, yığıtlar, kuyruklar, ağaçlar). • Kontrol yapıları: program içerisinde gerçekleştirilen işlemlere ilişkin kendi aralarında nasıl birleştirileceğini belirleyen yapılardır: ◦ Sıra: birbiri ardına sıralanan bir dizi işlemdir ◦ Seçim: belirli bir koşulun sağlanıp sağlanmaması durumuna göre iki sıradan/işlemden birinin seçilmesidir. ◦ Tekrar: belirli işlemleri belirli bir koşul sağlandığı sürece art arda tekrar çalıştırma işlemidir. • Yordam ve fonksiyonlar: Bir uygulamanın aşamalarını farklı programlara ve alt yapılara ayırmada kullanılan düzenleme yapılarıdır. Bir program sadece ana programdan oluşabileceği gibi ana program, yordamlar (alt programlar) ve fonksiyonlardan oluşabilir. Ana programdan yordam/fonksiyonlara aktarılan verilere parametre adını veriyoruz. C Programlama Dili Genel amaçlı, orta düzeyde, yapısal bir programlama dilidir (Bingül, 2011). 1972 yılında Dennis Ritchie tarafından Bell Telefon Labaraturvarında tasarlanmıştır. Bir çok alanda kullanılmaktadır. Özellikle C dili ile geliştirilen UNIX işletim sistemiyle kullanım yaygınlığı artmıştır. Günümüzdeki bazı diller C programlama dilinden esinlenmiştir (C++, Java, JavaScript, PHP, C#). Taşınabilir bir dildir, ANSI standartında uygun kodlandığı zaman ANSI destekleyen derleyicilerde derlenir, ANSI destekleyen işletim sistemlerinde çalışır. C kullanmanın gerekçeleri aşağıda listelenmiştir: • Güçlü ve esnek bir dildir. C ile işletim sistemi veya derleyici yazabilir, kelime işlemciler oluşturabilir veya grafik çizebilirsiniz. • İyi bir yazılım geliştirme ortamına sahiptir. • Özel komut ve veri tipi tanımlamasına izin verir. • Taşınabilir bir dildir. • Gelişimini tamamlamış ve standardı oluşmuş bir dildir. • Yapısal bir dildir. C kodları fonksiyon olarak adlandırılan alt programlardan oluşturulur. • C++, Java, JavaScript, JavaApplet, PHP, C\#, ... gibi diller C dilinden esinlenmiştir. Programlama Yapısı C programları bir veya daha fazla fonksiyondan oluşur (çalışabilmesi için mutlaka main() fonksiyonu barındırmalıdır). Her fonksiyon bir veya daha fazla deyim içerir. Bu deyim(ler) C bloklarıdır. Fonksiyonlar programın başka bir yerinden çağrılabilir. Her bir deyim program çalıştırıldığında belirli bir eylemi yerine getirir. Deyimler işlemleri yerine getiren komutlardır. Tüm C deyimleri ; (noktalı virgül) işareti ile sonlandırılır. Programımızı çalıştırabilmek için C programımızda mutlaka yer alması gereken fonksiyon main fonksiyonudur. Program yürütüldüğünde ilk çağrılan fonksiyon main() fonksiyonudur. C programlarının ana fonksiyonudur. C programlama dilinde kendi fonksiyonlarımızı tanımlayabildiğimiz gibi bize hazır olarak sunlmuş, kullanabileceğimiz hazır kütüphane fonksiyonları da bulunmaktadır. Sıklıkla kullanacağımız printf ve scanf hazır kütüphane fonksiyonlarıdır. Derleyicinin kaynak kodunu denetlemesi için önişlemci emirleri vardır. Bu emirler # işareti ile başlar. En çok kullanacağımız (ve kullanılan) emirler #include ve #define önişlemci emirleridir. • #include: Bir kaynak dosyasını programa eklemek için kullanılır, özellikle kütüphaneleri ve içerdikleri fonksiyonları kullanabilmek için kullanılır. C programına başlık dosyaları dahil edilir (.h uzantılı). Örnek: #include <stdio.h> • #define: Sembolik sabilerin tanımlanması için kullanılır. Örnek: #define SON 50 Programımıza kodla ilgili, programla ilgili yorumlarımızı, açıklamalarımızı açıklama satırlarıyla ekleriz. Açıklama satırları derleyici tarafından yok sayılır ve çalıştırılmazlar. C programlama dilinde iki şekilde açıklamalar eklenebilir: • • // işaretleriyle, işaretten sonra (//bu bir yorumdur) /* */ işaretlerinin arasında satırlara da yayılabilen blok şeklinde (/* bu bir yorumdur */) C dilinde 32 adet anahtar sözcük vardır: Değişken: program içinde kullanılan değerlere bellek üzerinde açılan alanlardır. Değişkenler bir değişken ismi ve değişkende tutulacak olan veri türüyle tanımlanır. C programlama dilinde kullanılacak değişkenler kullanılmadan önce tanımlanmalıdır. C programlama dilinde var olan temel veri türleri şunlardır: • char: karakter veriler • int: tamsayı veriler • float: tek duyarlıklı kayan noktalı sayılar • double: çift duyarlıklı kayan noktalı sayılar • void: değer içermeyen veriler Tanımlarken veri_türü değişken_ismi; şeklinde tanımlanır (int sayi;). Bir başlangıç değeri vereceksek atama işleci kullanılır: int sayi=100; Farklı amaçlara göre farklı değişken türleri vardır: • Yerel değişkenler: bildirildiği blokta/fonksiyonda geçerli değişkenlerdir • Genel değişkenler: program içindeki tüm fonksiyonlar/bloklarda geçerli olan değişkenlerdir , Daha önce #define ile sembolik sabit tanımlamıştık, sabit değişken tanımlaması ise farklı şekilde yapılmaktadır: veri_türü const değişken_adı = değeri; (Örnek: int const sayi=100;) Temel Giriş/Çıkış Standart giriş ve çıkış işlemleri için kullanılması gereken kütüphane stdio.h kütüphanesidir. Standart giriş birimi klavye, çıkış birimi ekrandır. : printf(kontrol_karakterleri, argüman_listesi); Kontrol karakterleri çıkışı yapılan verinin biçimlendirilmesinde kullanılır. Bu karakterler % işaretiyle başlar: %c (işaretsiz karakter), %s (karakter dizisi), %d veya %i (işaretli onluk sayı), %u (işaretsiz onluk sayı), %o (işaretsiz sekizlik sayı), %x (işaretsiz onaltılık sayı), %e (çift duyarlıklı sayı), %f (tek duyarlıklı sayı). Ek olarak satır işlemleriyle ilgili kontrol karakterleri de vardır: %n (satır atlama, yeni satır), %b (imleci sola kaydırma), %f (sayfa atlama), %r (satır başı), %t (tab boşluğu). Temel giriş işlemi için - klavyeden veri alma - scanf() fonksiyonu kullanılmaktadır. Kullanımı scanf(kontrol_karakterleri, argüman_listesi); şeklindedir. Burada da printf fonksiyonunda kullanılan kontrol karakterleri geçerlidir. Argüman listesi klavyeden girdi alınacak değişkenlerdir. İşleçler (Operatörler) Bazı işlemleri gerçekleştirmek için bize hazır olarak sunulmuş simgeler vardır. Bu simgeler kendilerine verilen operandlar üzerinde işlemleri gerçekleştirirler. C programlama dilinde aşağıdaki işleçler vardır: • Aritmetik işleçler (toplama +, çıkarma -, çarpma *, bölme /, kalan %, arttırma ++, azaltma --) • Mantıksal işleçler (ve &&, veya ||, değil !) • Karşılaştırma işleçleri (eşit ==, eşit değil !=, büyük >, küçük <, büyük veya eşit >=, küçük veya eşit <=) • Basit atama işleci (=) İşleçlerin bir işlem önceliği vardır. Program geliştirirken bu işlem önceliğini bilmek önemlidir. Parantezlerle bu önceliği ayarlamak da mümkündür. Yanlış yapmamak için, umulmadık buglarla karşılaşmamak için her zaman parantez kullanımı önemlidir. Öncelik sırası aşağıda incelenebilir: Yapısal Program Geliştirme Programımızda deyimlerin sırası programın çalışma sırasını belirliyor. Bazı durumlarda koşullara göre farklı akışlara-sıralar belirlememiz gerekiyor. Bu amaçla koşul deyimleri kullanılır. Böylece programımızın satırlarının işlem sırasını denetlemiş ve değiştirmiş oluruz. Koşullu programlar için deyim olarak if, if/else, switch vardır. Koşullar için karşılaştırma işleçleri ve mantıksal işleçleri kullanırız. Belli bir koşulu denetlemek için kullanılan deyim if (İngilizce Eğer anlamındadır) deyimidir. Bir karşılaştırma işlemi sonucunda bir eylemin yapılması gerekiyorsa if deyimi kullanılır. Kullanımı if koşul deyim; şeklindedir. koşul doğru olduğunda deyim çalışacaktır. Yanlış olması durumunda deyim çalışmayacak, atlanacaktır. C'de if deyimi aşağıdaki şekilde kullanılmaktadır: if(sayi>10){ printf(“Sayı 10'dan büyüktür.”); } Yukarıdaki if bloğu (küme parantezleri arasındaki kısım if bloğu olarak adlandırılmaktadır) sayının 10'dan büyük olması durumunda çalışacaktır. if deyimiyle bir koşul sağlandığında bir deyimin çalışmasını sağlıyorduk, o koşul sağlanmadığında başka bir deyimin çalışmasını istiyorsak if/else yapısını kullanırız: if(sayi>10){ printf(“Sayı 10'dan büyüktür.”); }else{ printf(“Sayı 10'dan büyük değildir.”); } Yukarıdaki if/else yapısında sayının 10'dan büyük olması durumunda if bloğu, olmaması durumunda else bloğu çalışacaktır. Bir değişkenin aldığı değerlere göre farklı deyimlerin çalıştırılacağı durumlarda switch yapısı kullanılır. Bu deyimi kullandığımız tüm işlemleri if/else yapısıyla da yapabiliriz. Eğer bir değişken farklı sabitlerle karşılaştırılacak ve buna göre farklı işlemler yapılacaksa switch tercih edilebilir. C dilinde kullanımı şu şekildedir: switch (harf) { case 'a': printf("a harfine bastınız\n"); break; case 'b': printf("b harfine bastınız\n"); break; default: printf("a veya b ye basmadınız\n"); } Bu switch bloğunda koşul denetlemesinde kullanılan değişken harf (karakter tipindedir) a olduğunda ilk durum, b olduğunda ikinci durum, bunlarında dışında bir harf olduğunda da default (varsayılan) durum çalışacaktır. Döngüler Döngüler programın bir kısmını oluşturan bir deyim kümesinin belirli bir koşul gerçekleşene kadar (gerçekleştiği sürece) tekrarını sağlamak için kullanılırlar. Döngüleri sonlandırmak için gerekli koşul ifadelerine göre döngüler iki farklı şekilde olabilir: 1. Sayaç kontrollü: döngünün çalıştırılması gereken tekrar sayısı tam olarak bilindiğinde kullanılan döngü tipidir. 2. Gözcü kontrollü: döngünün çalıştırılması gereken tekrar sayısı tam olarak bilinmediğinde kullanılan döngü tipidir. Ayrıca döngü sonlandırıcı koşulun kontrolü iki farklı şekilde gerçekleştirilebilir: 1. Döngü başlarken, döngüyü oluşturan kod parçası (döngü bloğu) çalıştırılmadan önce. 2. Döngü biterken, döngüyü oluşturan kod parçası (döngü bloğu) çalıştırıldıktan sonra. C programlama dilinde üç döngü tipi vardır: while, do/while ve for. While ve do/while arasındaki temel fark do/while döngüsünde koşul sağlanmasa bile bloğun bir kere çalışacak olmasıdır. Birden ona kadar sayıları ekrana basan döngü örnekleri sırasıyla şu şekildedir: While döngüsü: int sayac = 1; while(sayac<=10){ printf(“%d “,sayac ); sayac = sayac+1; } Do/While döngüsü: int sayac = 1; do{ printf(“%d “,sayac ); sayac = sayac+1; }while(sayac<=10); For döngüsü: int sayac; for(sayac=1;sayac<=10;sayac++){ printf(“%d “,sayac ); } Bu döngü yapılarında döngünün akışını değiştirmek için kullanılabilecek iki deyim vardır: 1. break: döngüyü erken bitirmek, sonlandırmak için kullanılan deyimdir. 2. continue: döngüde kendisinden sonra gelen tüm deyimleri atlayarak döngünün bir sonraki turunu çalıştırmak için kullanılır. Fonksiyonlar Gerçek yaşam programları bugüne kadar gördüklerimizden daha büyük, daha kapsamlıdır. Büyük programları geliştirmenin en iyi yolu, programı modül adı verilen küçük parçalardan (alt sistemlerden) oluşturmaktır. Böylece her bir parça daha kolay yönetilebilecektir. C programlama dilindeki modüllere fonksiyon adı verilmektedir. Yapısal programlama için fonksiyonlar kritik bir öneme sahiptir. Programın çalışması için gerekli olan main() bir fonksiyondur. Giriş ve çıkış için kullandığımız printf ve scanf de fonksiyondur. Fonksiyona veriler girdi olarak verilir, fonksiyondan bir çıktı alınır: C'de fonksiyonlar fonksiyonun ismi kullanılarak çağrılırlar. Çalışan kodumuz fonksiyon çağrım satırına gelince akış fonksiyona geçer. Fonksiyon çalışmasını tamamlayınca akış tekrar çağrıldığı noktaya gider ve fonksiyon çağrılma satırından sonraki satırdan çalışma devam eder. Fonksiyonların üzerinde çalışacağı veriler (değerler) parametreler yoluyla fonksiyona aktarılırlar. Parametreler tanımlayarak fonksiyonun üzerinde çalışacağı değişkenler belirlenir. Fonksiyon çağrılırken bu parametrelere değerler argüman olarak geçirilir. Global değişkenler de değer aktarımı için kullanılabilir. C'de örnek bir fonksiyon ve kullanımı aşağıda incelenebilir: Bu program kodu mesaj çağrısıyla karşılaştığında (5. satır) 10. satıra fonksiyon bloğuna atlayarak oradaki deyimleri çalıştıracak ve işlem bittiğinde çağrıldığı yerden sonraki satırdan işlemine devam edecektir. Bu kodun çıktısı aşağıdaki gibi olacaktır: birinci mesajınız ikinci mesajınız Dikkat edilirse bu örnekte fonksiyon ne parametre almaktadır, ne de bir geri dönüş değerine sahiptir. Parametre alan ve geri dönüş değeri olan fonksiyon örneği aşağıda incelenebilir. Buradaki return anahtarı fonksiyonun hesaplama sonucunu çağrıldığı yere aktarması için kullanılmaktadır ve geri dönüşü olan fonksiyonlarda mutlaka olmalıdır. Bu fonksiyon örneği kullanıcıdan scanf ile alınan iki tamsayı değerin (int) çarpımını carp isimli fonksiyonda gerçekleştirmekte ve printf ile ekranda görüntülemektedir. Fonksiyon tanımlamasında int x ve int y fonksiyona değer aktarmakta kullanılan tamsayı parametrelerdir. Fonksiyon adından önce yazılan int ifadesi de fonksiyonun geri dönüş değerinin türünü belirtmektedir. Kaynakça: • Deitel & Deitel, C ve C++, Sistem Yayıncılık, 2010. • Y. Özkan, C ile Programlama, Alfa Yayınları, 2003. • M. Veine, C Programming for the Absolute Beginner, Thomson, 2008. • J. Elkner, A. B. Downey, C. Meyers, Bilgisayar Bilimcisi gibi Düşünmek: Python ile Öğrenme (2. baskı, Çeviren: T. E. Kalaycı), 2010, http://yzgrafik.ege.edu.tr/~tekrei/dersler/bbgd_p/ • Viki, Algoritma, http://tr.wikipedia.org/wiki/Algoritma • A. Bingül, C Programlama Dili'ne Giriş, http://www1.gantep.edu.tr/~bingul/c/ • Ç. Çebi, C Programlama Dersleri, http://www.cagataycebi.com/programming/c_programming/ • F. Kadifeli, A. C. C. Say, M. U. http://www.kadifeli.com/fedon/stdcprtr.php Çağlayan, C Programlama Dili, 2007,