İzmir Ekonomi Üniversitesi Bilgisayar Topluluğu www.ieubt.org C Dersleri Bölüm 3 : Program akışı Sorularınız için : programlama@ieubt.org Hazırlayan : Görkem PAÇACI (gorkem.pacaci@std.ieu.edu.tr) C Program Akışı 1. Giriş 2. Algoritma geliştirme 2.1. Kodumsu 2.2. Akış çizeneği 3. Akış denetleme 3.1 Koşul ile akış denetleme 3.1.1 if 3.1.2 if - else 3.1.3 switch - case 3.1.4 ( )? ( ) : ( ) işleci 3.2 Tekrarlama ile akış denetleme (Döngü) 3.2.1 while 3.2.2 do-while 3.2.3 for 3.2.4 break continue ile döngüyü yönlendirme 3.2.5 Karşılaştırma(==) ve atama(=) işleçlerine dikkat 3.3. İşlevleri çağırma 4. Kaynaklar
1. Giriş Program geliştirme, kod yazmanın öncesinde problemi anlama ve çözümü tasarlama aşamalarını gerektirir. En baştan kod yazmaya başlamak, küçük boyutlu programlarda kabul edilebilir olsa da, daha karmaşık programlarda başarısızlığın önemli bir sebebidir. Bunun için, programcının önce sorunu ve çözümü net olarak anlamış olması gerekir. Sorun ve çözüm anlaşıldıktan sonra, çözümü bilgisayara aktarabilmek için net bir algoritma haline getirmek gerekir. 2. Algoritma geliştirme Algoritma, belli bir amaca ulaşmak için yapılacak işlerin yapısal bir şekilde sıralanmış hali, çözümün netleştirilmiş ve aşamalarına ayrılmış, soyut ifadesidir. Bir algoritmayı geliştirirken, algoritmayı yazılı hale getirmek için çeşitli yöntemler kullanılabilir. Bunlardan bazıları, kodumsu(pseudocode) ve akış çizeneğidir (flow chart). 2.1. Kodumsu Kodumsu, bir algoritmayı ifade etmek için kullanılan serbest ve rahat bir yöntemdir. Belirli yazım tarzı yahut yazım kuralları yoktur. Örnek 2.1.(a) : Basit bir hesap makinesi; Kullanıcıdan yapacağı işlemi öğren Kullanıcıdan işlenecek sayıları öğren Eğer işlem toplama ise Ekrana sayıların toplamını yaz Eğer işlem çıkarma ise Ekrana sayıların farkını yaz Eğer işlem çarpma ise Ekrana sayıların çarpımını yaz Eğer işlem bölme ise Ekrana sayıların bölümünü yaz Programcı kendi kodumsusunu istediği gibi yazabilir. Kodumsuyu hazırlarken bazı noktalara dikkat etmek, algoritmanın anlaşılabilirliğine ve koda dönüştürülebilirliğine faydalıdır. Detaya girmekle genelleme yapmak arasındaki dengeyi koruyun. Ne kadar detaya girerseniz, kodumsu o kadar karmaşıklaşır ve koddan önce kodumsu yazmanın avantajını o denli kaybedersiniz. Ve ne kadar gereksiz genelleme yaparsanız, kodumsudan koda geçerken o kadar sıkıntı yaşarsınız. Kodumsu yazarken belli bir yazım tarzı oluşturun. Örneğin, bir ifadenin alt-ifadelerini o ifadeden biraz daha içeride yazın ki, alt-ifadelerin o ifadeye bağlı olduğu açıkça görülebilsin. Örnek 2.1.(b) : Basit bir hesap makinesi; (Kötü Örnek!!!) Kullanıcıdan bilgileri al İşlemi yap Ekrana yaz Bu örnek açıkça kötü bir örnek. Gerekenden çok fazla genelleme yapılmış, bu da kod yazmaya geçerken önceden kodumsu yazmış olmanızın faydasını ortadan kaldırır.
Örnek 2.1.(c) : Basit bir hesap makinesi; (Kötü Örnek!!!) Kullanıcıdan yapacağı işlemi girmesini iste Kullanıcıdan bir harf (char) al ve islem isimli değişkene kaydet Kullanıcıdan yapacağı işlemde kullanacağı birinci sayıyı girmesini iste Kullanıcıdan bir sayı (int) al ve sayi1 isimli değişkene kaydet Kullanıcıdan yapacağı işlemde kullanacağı ikinci sayıyı girmesini iste Kullanıcıdan bir sayı (int) al ve sayi2 isimli değişkene kaydet Yapılacak işlemi (islem) + harfine eşit ise İki sayının toplamını hesapla Toplamı ekrana yaz Yapılacak işlemi (islem) harfine eşit ise İki sayının farkını hesapla Farkı ekrana yaz Yapılacak işlemi (islem) x harfine eşit ise İki sayının çarpımını hesapla Çarpımı ekrana yaz Yapılacak işlemi (islem) : harfine eşit ise İki sayının bölümünü hesapla Bölümü ekrana yaz 2.2. Akış çizeneği Akış çizenekleri, kodumsular gibi algoritmanın geliştirilmesi ve ifadesi sırasında programcıya yardımcı olurlar. Farklı olarak, akış çizelgelerinde kullanacbileceğiniz öntanımlı şekiller vardır. Örneğin bir dikdörtgen, yapılacak bir işlemi, içinde başlangıç yazan bir elips, programın başlangıcını, bir baklava dilimi içindeki karşılaştırma ise dallanmayı ifade eder. Bu bilindik işaretler, hem akış çizelgesini okuyan herkesin aynı şeyi anlamasını sağlar, hem de yazan kişiyi belli şekilleri kullanmaya zorlayarak, gerçek koda dönüşümü kolaylaştırır. Akış çizeneklerinde kullanılan öntanımlı temel şekiller ve anlamları şöyledir; Akış çizgisi Ekrana çıktı Kullanıcıdan giriş Bağlantı noktası İşlem Dallanma ( Koşullandırma )
Örnek 2.2.(a) : Basit bir hesap makinesi;
3. Akış denetleme Programınızın içinde birbiri ardına gerçekleştirilen eylemlerin herbiri birer ifadedir. Bir işlevin çağırılması, bir aritmetik işlemin yapılması yahut bir değişkene değer atanması, ifadelere birer örnektir. İfadelerin her birinin işlenip işlenmeyeceği ya da ne kadar işleneceğiine karar vermek elinizdedir. Bunun için kontrol ifadeleri ve tekrarlama ifadelerini kullanırız. 3.1 Koşul ile akış denetleme İfadelerin gerçekleştirilmesini koşullara bağlayabilirsiniz. Bir koşul sağlanırsa bir dizi ifadenin, sağlanmazsa diğer bir dizi ifadenin çalışırılmasını sağlayabilirsiniz. Bu, program akışında dallanma sağlayacaktır. Karşılaştırma ile akış denetlemenin dört çeşidi vardır; if, if-else, switch-case, ()?():() işleci. Koşul yazmak Koşulları belirtmek için belirli bir yazım tekniği vardır. Matematikten tanışık olduğumuz mantıksal işleçlerin C deki karşılıkları şöyledir; EŞİT == KÜÇÜK < DEĞİL! BÜYÜK > EŞİT DEĞİL!= KÜÇÜK veya EŞİT <= BÜYÜK veya EŞİT >= Karmaşık karşılaştırmaları, mantıksal işleçleri birleştirerek, iç içe gömerek kurabilirsiniz. Birkaç örnek ; (not >= 45) && (devamsizlik<10) Not 45 ten büyük ya da eşit ve devamsızlık 10 dan küçükse (sınıfı geçti) (not < 45) (devamsizlik>=10) Not 45 den küçükse ya da devamsızlık 10 dan büyük ya da eşitse (sınıfta kaldı) (zaman > 09:00) && (yer!= sınıf) Saat dokuzu geçtiyse ve yer sınıf değilse (geç) (ceptekipara >= fiyat) (satici == tanıdık) ((boy < 150) && (kilo > 150)) ((boy > 180) && (kilo < 50)) Cepteki para fiyata eşit veya büyükse yada satıcı tanıdıksa (alınabilir) Boy 150 den kısaysa ve kilo 150 dan fazlaysa ya da boy 180 den büyükse ve kilo 50 den küçükse (kilo problemi) Bir karşılaştırmanın sonucu ya doğru ya da yanlış olabilir. C de 0, yanlış ı ve sıfırdan farklı her sayı da doğru yu temsil eder. Örneğin koşul gereken bir yerde 1 yazarsanız, o koşul her zaman doğru kabul edilir. Ya da 0 yazarsanız, o koşul her zaman yanlış kabul edilir. Bu sayısal değerleri mantıksal ifadelerin içinde de kullanabilirsiniz. Örneğin 1 sayi==2 koşulu, sayi 2 ye eşit olsa da olmasa da doğru bir ifadedir.
3.1.1 if İf ifadelerinde, belirlediğiniz bir koşulun gerçekleşmesi ve gerçekleşmemesi hallerini denetleyebilirsiniz. Örneğin sadece kullanıcı erkekse yaşını sor diyebilirsiniz. İf ifadesinin temel yazım şekli şöyledir; if ( koşul ) ifade; Bu durumda ifade, yalnızca koşul sağlanırsa gerçekleştirilecektir. Eğer bir koşul altında birden çok ifade gerçekleştirmek istiyorsanız, ifadeleri { arasına almalısınız. if ( koşul ) { ifade1; ifade2; ifade3; Aşağıda iki kodumsu, akış çizelgesi ve c kodu görülmektedir; Eğer öğrencinin notu yetersizse ya da öğrenci devamsızlık sınırını doldurduysa Öğrenci sınıfta kalır Eğer öğrencinin notu yetersizse ya da öğrenci devamsızlık sınırını doldurduysa Öğrenci sınıfta kalır Sınıf mevcudu azalır Yeni sınıf mevcudu ekrana yazılır if (not < 45 devamsizlik => 20) printf( sınıfta kaldınız.\n ); if (not < 45 devamsizlik => 20) { printf( sınıfta kaldınız.\n ); mevcut = mevcut 1; printf( mevcut :%d\n,mevcut);
3.1.2 if - else Önceki başlıkta anlatılan if, sadece belirtilen koşul doğru olduğunda çalıştırılacak ifadeler belirtilmesini sağlar. If den sonra else kelimesini kullanarak, belirtilen koşul yanlış olduğunda çalıştırılacak ifadeler de belirlenebilir. Dikkat edilmesi gerek nokta, if else ifadesinin iki bölümünden sadece birinin çalıştırılacağıdır. Eğer koşul doğruysa 1., eğer koşul yanlışsa 2. bölüm çalıştırılır. If ifadesinin tamamen dışında, ifade sonlandıktan sonra gerçekleşecek ifadeler de her iki durumda da gerçekleştirilecektir. If-else ifadesinin temel yazım şekli şöyledir; if (koşul) dogruysagerceklesecekifade; else yanlissagerceklesecekifade; Birden fazla ifade gerçekleştirmek için, ifadeler { arasına alınmalıdır; if (koşul) { dogruysagerceklesecekifade1; dogruysagerceklesecekifade2; dogruysagerceklesecekifade3; else { yanlissagerceklesecekifade1; yanlissagerceklesecekifade2; yanlissagerceklesecekifade3; Aşağıda bir örnek kodumsu, akış çizelgesi ve c kodu olarak gösterilmiştir; Eğer öğrencinin notu yetersizse ya da öğrenci devamsızlık sınırını doldurduysa Aksi halde Öğrenci sınıfta kalır Sınıf mevcudu azalır Öğrenci sınıfı geçer if (koşul) { printf( sınıfta kaldınız :( ); mevcut--; else { printf( sınıfı geçtiniz :D );
3.1.3 switch - case Önce görülen if else çifti, program akışını verilen koşula bağlı olarak iki dala ayırabilir. Eğer bundan fazla dallanmaya ihtiyacınız varsa, ya iç içe gömülü if else ifadeleri kullanmalı, ya da arka arkaya birçok if else ifadesini,koşulları birbiriyle kesişmeyecek şekilde yerleştirmelisiniz. Bu tür bir dallanma ihtiyacını karşılayacak bir switch case yapısı mevcuttur. Bu yapı, bir ifadeye bağlı olarak, ifadenin alabileceği değerlere göre akışı dallandırmak için kullanılır. Belirttiğiniz ifadenin alacağı değerlere göre çalışacak ifadeleri belirleyebileceğiniz gibi, belirtmediğiniz herhangi bir değer yakalandığında da gerçekleştirilecek ifadeleri belirleyebilirsiniz. Switch case ifadesinin temel yazım şekli şöyledir; switch (ifade) { case (ifadedegeri1) : ifadedegeri1sonucundacalisacakifade1; ifadedegeri1sonucundacalisacakifade2; ifadedegeri1sonucundacalisacakifade3; case (ifadedegeri2) : ifadedegeri2sonucundacalisacakifade1; ifadedegeri2sonucundacalisacakifade2; ifadedegeri2sonucundacalisacakifade3; case (ifadedegeri3) : ifadedegeri3sonucundacalisacakifade1; ifadedegeri3sonucundacalisacakifade2; ifadedegeri3sonucundacalisacakifade3; default : digerdegerlerdecalisacakifade1; digerdegerlerdecalisacakifade2; digerdegerlerdecalisacakifade3; switch case yapısının dikkatten kaçmaması gereken önemli farklılığı, koşullarla değil değerlerle ilgilenmesidir. If ifadesi, bir mantıksal koşulun doğruluğuna göre işlerken switch, belirtilen ifadenin alacağı değeri, her bir case ile belirtilen değerlerle karşılaştırır ve tutan değeri belirten case kelimesinin altındaki ifadeleri, bir break kelimesi görene kadar çalıştırır. Break kelimesi işlendiği anda switch yapısı tamamen sonlandırılır ve ondan sonraki ifadeler çalışmaya başlar. Örnek olarak, kullanıcının girdiği sayıya göre yazılı olarak kaçıncı sınıfta olduğunu söyleyecek program, kodumsu, akış çizelgesi ve C kodu olarak gösterilmiştir;
Kullanıcıdan kaçıncı sınıfta olduğu bilgisini al Eğer 1 ise Ekrana birinci sınıfta yaz Eğer 2 ise Ekrana ikinci sınıfta yaz Eğer 3 ise Ekrana üçüncü sınıfta yaz Eğer 4 ise Ekrana dördüncü sınıfta yaz int sinifno; printf( kaçıncı sınıftasınız : ); scanf( %d,&sinifno); switch(a) { case 1: printf( birinci sınıftasınız\n ); case 2: printf( ikinci sınıftasınız\n ); case 3: printf( üçüncü sınıftasınız\n ); case 4: printf( dördüncü sınıftasınız\n ); default : printf( 1 ile 4 arası değil.\n );
3.1.4 ( )? ( ) : ( ) işleci Bu işleç, basit bir if else ifadesi görevi görür, ama satır içinde, başka bir tek satırlı ifadenin içine gömülü olarak kullanılabilir. printf("durumunuz :%s",(not > 45)?("Geçti"):("Kaldı")); Soru işaretinden önceki bölüm, koşulun yazılacağı bölümdür. Soru işareti ile iki nokta arasındaki bölüm, koşul doğru olduğunda çalışacak bölümdür ve iki nokta üstüsteden ifadenin sonuna kadar olan bölüm, koşulun yanlış olması durumunda çalıştırılacak bölümdür. Bu ifade, Çok sık kullanılması durumunda kodu zor okunur hale getirebilir. Fakat bazı durumlarda da önemli bir kurtarıcıdır, örneğin yukarıdaki örneğin, normal bir if else ifadesi kullanarak yazılmış hali şöyle olabilir; if (not > 45) { printf( Durumunuz : Geçti ); else { printf( Durumunuz : Kaldı ); 3.2 Tekrarlama ile akış denetleme (Döngü) 3.2.1. while 3.2.2 do-while 3.2.3 for 3.2.4 break continue ile döngüyü yönlendirme 3.2.5 Karşılaştırma(==) ve atama(=) işleçlerine dikkat 3.3. İşlevleri çağırma 4. Kaynaklar İsim Yazar(lar) Yayınevi C How to program (4.e) H.M. Deitel, P.J. Deitel Prentice Hall(2004) Basic sözlüğü Rudolf BUSHC (Münip ÖNİZ) Franzis'(Yüce Yayınları)(1986)