1. Skip to Menu
  2. Skip to Content
  3. Skip to Footer>

Sayıcı Kontrollü Döngü

PDF Yazdır e-Posta

Written by Admin

Posted on 07 Eylül 2010

Son Güncelleme 07 Eylül 2010

ALGORİTMALARI UYGULAMAK: DURUM1 (SAYICI KONTROLLÜ DÖNGÜ)

Algoritmaların nasıl geliştirildiğini gösterebilmek için sınıf ortalaması bulma probleminin değişik biçimlerini çözeceğiz. Aşağıdaki problemi inceleyiniz.
Bir sınıftaki 10 kişi bir sınava girmiştir. Notlar (0'dan 100'e kadar tamsayılar) size verilmiş ve bu sınavın sonucunda sınıf ortalamasını bulmanız istenmiştir.
Sınıf ortalaması, notların toplamının sınıftaki öğrenci sayısına bölünmesiyle bulunur.

Bu problemi bilgisayarda çözecek algoritma, bütün notların teker teker bilgisayara girilmesi, ortalama hesabının yapılması ve sonucun ekrana yazdırılması biçimindedir. Sahte kodları kullanalım ve yaptırılacak işleri listeleyip, onların hangi sırada kullanılacağını belirleyelim.
Notları girmek için sayıcı kontrollü döngüyü kullanacağız. Bu teknik sayici adındaki bir değişken kullanarak, ifadelerin kaç kez tekrar edileceğini belirlememiz esasına dayanır. Bu örnekte döngü, sayıcı 10'u geçtiğinde sonlanmaktadır. Bu kısımda sahte kodlardan oluşan algoritmayı (Şekil 3.5) ve bu algoritmanın C ile yazılmış halini (Şekil 3.6) göstereceğiz. Diğer kısımda, sahte kodlardan oluşan algoritmaların nasıl geliştirildiğini anlatacağız. Sayıcı kontrollü döngüler, genellikle belirli döngüler olarak adlandırılırlar. Çünkü döngü başlamadan önce döngünün kaçıncı tekrardan sonra sonlanacağını biliriz.

Algoritmada toplam ve sayici değişkenlerinden bahsedildiğine dikkat ediniz. toplam değişkeni, bir dizi değerin toplamını depolamak için kullanılacaktır. sayici değişkeni ise saymak amacıyla kullanılacaktır ( Burada kaç tane not girildiğini saymak için kullanacağız). Toplamları depolamak için kullanılan değişkenlere, programda kullanılmadan önce 0 atanmalıdır. Aksi takdirde, bu değişkeni depoladığımız hafıza konumunda daha önceden bulunan sayı da hesaplarımıza katılır. sayici değişkenine genellikle kullanımına göre 0 ya da 1 atanır ( Her ikisi içinde örnekler göstereceğiz ). İlk değeri verilmemiş değişkenler genellikle, çöp (garbage) değer ( hafıza konumunda bu değişken için en son depolanmış değer) içerirler.

    Genel Programlama Hataları 3.5
    Eğer sayıcı ya da toplam değişkenlerine ilk atamalar yapılmazsa program muhtemelen yanlış çalışacaktır. Bu, mantıksal hatalara bir örnektir.

    İyi Programlama Alıştırmaları 3.6
    Sayıcı ve toplam değişkenlerine ilk değerler vermek.

toplamı 0'a ata
sayici 'yı 1'e ata


sayici 10' eşit ya da 10'dan küçükken (while)
Diğer notu gir.
Girilen notu, toplama ekle
sayici' ya 1 ekle


Sınıf ortalamasını, toplamı 10'a bölerek bul
Sınıf ortalamasını yazdır.


Şekil 3.5 Sayıcı Kontrollü Döngülerle sınıf ortalaması problemini çözen algoritmanın sahte kodlarla yazılmış biçimi

1 /* Sekil. 3.6: fig03_06.c
2 Sayıcı kontrollü döngü ile
3 sınıf ortalamasının bulunması */
4 #include <stdio.h>
5
6 int main( )
7 {
8 int sayici, not, toplam, ortalama;
9
10 /* ilk değerlerin verilmesi */
11 toplam = 0;
12 sayici = 1;
13
14 /* işlem kısmı */
15 while ( sayici <= 10 ) {
16 printf( "Notu girin: " );
17 scanf( "%d", &not );
18 toplam = toplam + not;
19 sayici = sayici + 1;
20 }
21
22 /* bitiş kısmı */
23 ortalama = toplam / 10;
24 printf( "Sınıf ortalaması %d dir.\n", ortalama );
25
26 return 0; /* programın başarılı bir şekilde bitti */
27 }


Notu girin: 98
Notu girin: 76
Notu girin: 71
Notu girin: 87
Notu girin: 83
Notu girin: 90
Notu girin: 57
Notu girin: 79
Notu girin: 82
Notu girin: 94
Sınıf ortalaması 81 dir.

Şekil 3.6 Sayıcı kontrollü döngü ile sınıf ortalaması problemini çözen C programı ve programın örnek bir çıktısı.

Bu programda, sonuç olarak hesaplanan ortalamanın bir tamsayı olduğuna dikkat ediniz. Aslında bu örnekteki notların toplamı 817 yapmaktadır ve 10'a bölündüğünde 81.17 sonucu vermektedir. İleride bu tür sayılarla (ondalıklı sayılarla) ilgili konuları anlatacağız.

ALGORİTMALARI UYGULAMAK: DURUM1       (SAYICI KONTROLLÜ DÖNGÜ)

 

Algoritmaların nasıl geliştirildiğini gösterebilmek için sınıf ortalaması bulma probleminin değişik biçimlerini çözeceğiz. Aşağıdaki problemi inceleyiniz.

Bir sınıftaki 10 kişi bir sınava girmiştir. Notlar (0'dan 100'e kadar tamsayılar) size verilmiş ve bu sınavın sonucunda sınıf ortalamasını bulmanız istenmiştir.

Sınıf ortalaması, notların toplamının sınıftaki öğrenci sayısına bölünmesiyle bulunur. Bu problemi bilgisayarda çözecek algoritma, bütün notların teker teker bilgisayara girilmesi, ortalama hesabının yapılması ve sonucun ekrana yazdırılması biçimindedir. Sahte kodları kullanalım ve yaptırılacak işleri listeleyip, onların hangi sırada kullanılacağını belirleyelim.

Notları girmek için sayıcı kontrollü döngüyü kullanacağız. Bu teknik sayici adındaki bir değişken kullanarak, ifadelerin kaç kez tekrar edileceğini belirlememiz esasına dayanır. Bu örnekte döngü, sayıcı 10'u geçtiğinde sonlanmaktadır. Bu kısımda sahte kodlardan oluşan algoritmayı (Şekil 3.5) ve bu algoritmanın C ile yazılmış halini  (Şekil 3.6) göstereceğiz. Diğer kısımda, sahte kodlardan oluşan algoritmaların nasıl geliştirildiğini anlatacağız. Sayıcı kontrollü döngüler, genellikle belirli döngüler olarak adlandırılırlar. Çünkü döngü başlamadan önce döngünün kaçıncı tekrardan sonra sonlanacağını biliriz.

 

Algoritmada toplam ve sayici değişkenlerinden bahsedildiğine dikkat ediniz. toplam değişkeni, bir dizi değerin toplamını depolamak için kullanılacaktır. sayici değişkeni ise saymak amacıyla kullanılacaktır ( Burada kaç tane not girildiğini saymak için kullanacağız). Toplamları depolamak için kullanılan değişkenlere, programda kullanılmadan önce 0 atanmalıdır. Aksi takdirde, bu değişkeni depoladığımız hafıza konumunda daha önceden bulunan sayı da hesaplarımıza katılır. sayici değişkenine genellikle kullanımına göre 0 ya da  1 atanır ( Her ikisi içinde örnekler göstereceğiz ). İlk değeri verilmemiş değişkenler genellikle, çöp (garbage) değer ( hafıza konumunda bu değişken için en son depolanmış değer) içerirler.

 

Genel Programlama Hataları 3.5

Eğer sayıcı  ya da toplam değişkenlerine ilk atamalar yapılmazsa program muhtemelen yanlış çalışacaktır. Bu, mantıksal hatalara bir örnektir.

 

İyi Programlama Alıştırmaları 3.6

Sayıcı ve toplam değişkenlerine ilk değerler vermek.

 

toplamı 0'a ata

sayici 'yı 1'e ata

 

sayici 10' eşit ya da 10'dan küçükken (while)

      Diğer notu gir.

      Girilen notu, toplama ekle

      sayici’ ya 1 ekle

 

Sınıf ortalamasını, toplamı 10'a bölerek bul

Sınıf ortalamasını yazdır.

Şekil 3.5 Sayıcı Kontrollü Döngülerle sınıf ortalaması problemini çözen algoritmanın sahte kodlarla yazılmış biçimi

 

1          /* Sekil. 3.6: fig03_06.c

2             Sayıcı kontrollü döngü ile

3             sınıf ortalamasının bulunması */

4          #include <stdio.h>

5

6          int main( )

7         {

8                 int sayici, not, toplam, ortalama;

9

10              /* ilk değerlerin verilmesi */

11              toplam = 0;

12              sayici = 1;

13 

14              /* işlem kısmı */

15              while ( sayici <= 10 ) {

16                  printf( "Notu girin: " );

17                  scanf( "%d", &not );

18                  toplam = toplam + not;

19                  sayici = sayici + 1;

20              }

21  

22              /* bitiş kısmı */

23              ortalama = toplam / 10;

24              printf( "Sınıf ortalaması %d dir.\n", ortalama );

25

26              return 0;   /* programın başarılı bir şekilde bitti */

27        }

 

 

Notu girin: 98

Notu girin: 76

Notu girin: 71

Notu girin: 87

Notu girin: 83

Notu girin: 90

Notu girin: 57

Notu girin: 79

Notu girin: 82

Notu girin: 94

Sınıf ortalaması 81 dir.

 

 

Şekil 3.6 Sayıcı kontrollü döngü ile sınıf ortalaması problemini çözen C programı ve programın örnek bir çıktısı.

 

Bu programda, sonuç olarak hesaplanan ortalamanın bir tamsayı olduğuna dikkat ediniz. Aslında bu örnekteki notların toplamı 817 yapmaktadır ve 10'a bölündüğünde 81.17 sonucu vermektedir. İleride bu tür sayılarla (ondalıklı sayılarla) ilgili konuları anlatacağız.

 

3.9 YUKARIDAN AŞAĞIYA,ADIMSAL İYİLEŞTİRMEYLE ALGORİTMALARI UYGULAMAK:DURUM 2 (NÖBETÇİ KONTROLLÜ DÖNGÜLER)

 

Ortalama problemimizi genelleştirelim.Aşağıdaki problemi inceleyiniz:

Program çalıştırıldığında, kaç kişinin ortalamasının hesaplanacağını önceden bilmeden, sınıf ortalamasını bulacak bir program geliştirin.

İlk sınıf ortalaması  örneğinde, notların sayısını (10) başlangıçta biliyorduk. Bu örneğimizde ise kaç not girileceğini başlangıçta bilmiyoruz. Program, herhangi bir sayıda veriyi işlemek zorundadır. Bu durumda, programımız notların girişinin sonlandığına nasıl karar verecektir? Sınıf ortalamasını ne zaman hesaplayacağını ve yazdıracağını nasıl bilecektir?

 

Bu problemi çözmenin yolu, veri girişinin sonlandığını belirten bir özel değer, nöbetçi değer, ( sinyal değer ve ya işaretçi değer de denir) kullanmaktır. Kullanıcı, girmesi gereken tüm verileri girdikten sonra son değeri girdiğini belirten bir nöbetçi değer girer. Nöbetçi kontrollü döngüler, genelde belirsiz döngüler olarak adlandırılır çünkü döngü çalışmaya başlamadan önce döngünün kaç kez tekrarlanacağı bilinmemektedir.

 

Nöbetçi değer, kabul edilebilir herhangi bir giriş değeriyle karıştırılmayacak biçimde seçilmelidir. Not değerleri genellikle pozitif tamsayılar olduğundan, -1 bu örnek için uygun bir nöbetçi değer olabilir. Böylece sınıf ortalama programı, 95,96,75,74,89 ve –1 gibi verileri işleyecektir. Program, sınıf ortalamasını 95,96,75,74 ve 89 notları için hesaplayacak ve ortalamayı yazdıracaktır.( -1 nöbetçi değerdir, bu sebepten ortalama hesabına katılmamalıdır.)

 

Genel Programlama Hataları 3.6

Veri olabilecek bir değeri nöbetçi değer seçmek.

 

Bu sınıf ortalama problemine, iyi yapısal programlar geliştirmek için ihtiyaç duyduğumuz ve yukarıdan-aşağıya adımsal iyileştirme adını verdiğimiz bir teknikle yaklaşacağız. Bunun için en yukarıya yapmak istediğimiz işin sahte kodunu yazalım.

 

Bu sınav için sınav ortalamasını belirle.

 

En yukarıya yazdığımız bu kod, tüm program için geçerli olacak ve tüm programın tanıtıcısı konumunda bulunacaktır. Ancak çok az durumda, en yukarıya yazdığımız bu sahte kod bir C programı yazmak için yeterli detaya sahiptir. Bu yüzden, süreci iyileştirmeye başlayacağız. Bunun için, yukarıdaki kodu daha küçük görevlere bölüp, bu görevlerin hangi sırada yapılacağını listeleyeceğiz. İlk iyileştirmemiz şu biçimde yapılabilir :

 

Değişkenleri belirle.

Notları gir,topla ve say.

Sınıf ortalamasını hesapla ve yazdır.

 

Burada yalnızca dizi yapısı kullanılmıştır ; adımlar çalıştırılacakları sırada birbiri ardına sıralanmıştır.

 

Yazılım Mühendisliği Gözlemleri 3.3

Her iyileştirme algoritmanın bütünleştirilmesidir; yalnızca detay seviyeleri değişmektedir.

 

Bir sonraki iyileştirme seviyesinde (ikinci iyileştirmemizde), bazı değişkenleri belirtmeliyiz. Sayıların toplamına, kaç sayının işlendiğini bilmemize, her notun değerini girdi olarak alacak bir değişkene ve hesaplanan ortalamayı tutacak bir değişkene ihtiyaç duyacağız.

 

Değişkenleri belirle  

 

sahte kodunu

 

toplam değişkenini sıfır olarak belirle

sayıcı değişkenini sıfır olarak belirle              biçiminde iyileştirebiliriz.

 

Yalnızca toplam ve sayıcıya ilk değer atanması gerektiğine dikkat ediniz ; ortalama ve not değişkenleri için (sırasıyla hesaplanmış ortalama ve kullanıcı girişi için kullanılırlar) ilk değer atanmasına gerek yoktur. Çünkü bu değerler, 2. ünitede anlattığımız destructive-read in işlemi sayesinde, hafızada önceden bulunabilecek verileri siler.

 

Notları gir,topla ve say

 

sahte kodumuzun tüm notları alabilmesi için bir döngü yapısına ihtiyacı vardır. Kaç notun girileceğini ve işleneceğini bilmediğimiz için nöbetçi kontrollü döngü kullanacağız. Kullanıcı notları girdikten sonra nöbetçi değeri girecektir. Program her seferinde girilen sayının nöbetçi değere eşit olup olmadığını kontrol etmeli, nöbetçi değer girildiği anda da döngüyü sonlandırmalıdır. Öyleyse sahte kodumuzda yapacağımız iyileştirme

 

İlk notu gir

Kullanıcı nöbetçi değeri girmediği sürece(while)

       Bu notu o andaki toplam değere ekle

       Sayıcıyı bir arttır

       Sıradaki notu al ( bu değer nöbetçi değer olabilir )

 

biçiminde yapılmalıdır. Sahte kodda, while yapısının gövdesindeki ifadeleri küme parantezleri içine almadığımıza dikkat ediniz. Bunun yerine, while yapısı içindeki tüm ifadeleri içeriden başlattık. Bir kez daha sahte kodların yalnızca bir program geliştirme aracı olduğuna dikkat ediniz.

 

Ortalamayı hesapla ve yazdır                   sahte kodunu  ise

 

Eğer ( if ) sayıcı sıfıra eşit değilse

           Ortalamayı, notların toplamını sayıcıya bölerek hesapla

            Ortalamayı yazdır

Aksi takdirde ( else )

            “Not girilmemiştir” yazdır                biçiminde düzeltebiliriz.

 

Burada, toplamın sıfıra bölünme ihtimalini ortadan kaldırdığımıza dikkat edin. Bir sayıyı sıfıra bölmek engellenmezse ölümcül hata oluşturur.Şimdi de ikinci iyileştirmemizi topluca şekil 3.7’de görelim.

 

Genel Programlama Hataları 3.7

Sıfıra bölmeye çalışmak ölümcül bir hata oluşturur.

 

İyi Programlama Alıştırmaları 3.7

Değeri sıfır olabilecek bir deyimi bölme işlemlerinde bölen olarak kullanacaksak bunu programda ölümcül  bir hata oluşturmayacak biçimde kullanmak gerekir.(Örneğin bir hata mesajı yazdırarak)

 

Şekil 3.5 ve 3.7’de sahte kod içinde boş satırlar bırakarak okunurluğu arttırmaya çalıştık.Aslında bu boş satırlar programları çeşitli kısımlara ayırmaktadır.

 

Toplam değişkenini sıfır olarak belirle

Sayıcı değişkenini sıfır olarak belirle

 

İlk notu gir

Kullanıcı nöbetçi değeri girmediği sürece (while)

       bu notu o andaki değere ekle

       Sayıcıyı bir arttır

       Sıradaki notu al(bu değer nöbetçi değer olabilir)

 

Eğer  ( if ) sayıcı sıfıra eşit değilse

           Ortalamayı, notların toplamını sayıcıya bölerek hesapla

            Ortalamayı yazdır

Aksi takdirde ( else )

            “Not girilmemiştir” yazdır       

 

Şekil 3.7 Sınıf ortalaması problemini nöbetçi kontrollü döngülerle çözen sahte kod algoritması.

 

 

 

Yazılım Mühendisliği Gözlemleri 3.4

Programların çoğu mantıksal olarak 3 kısma bölünebilir:Program değişkenlerinin bildirildiği ve değişkenlere ilk değer atandığı bildirim safhası, girilen verilerin değerlerinin işlendiği ve program değişkenlerinin ayarlandığı işleme safhası ve son olarak da sonuçların hesaplandığı ve yazdırıldığı sonlandırma safhası.

 

Şekil 3.7’deki sahte kod algoritması, daha genel sınıf ortalaması problemlerini çözmektedir. Algoritma iki iyileştirme seviyesinden sonra geliştirilmiştir. Çoğu zaman daha fazla seviyeye ihtiyaç duyulur.

 

Yazılım Mühendisliği Gözlemleri 3.5

Programcı, yukarıdan-aşağıya adımsal iyileştirme sürecini, sahte kod algoritması programcı tarafından C kodlarına çevrilebilecek kadar detaya sahip olduğunda sonlandırır. Daha sonra C programının yazılması oldukça kolay olacaktır.

 

C programı ve örnek bir çıktısı Şekil 3.8’de gösterilmiştir. Notlar için yalnızca tamsayılar girilmiş olsa da ortalama hesabı sonucunun, ondalıklı bir sayı olma ihtimali bulunmaktadır. int tipi böyle bir sayıyı temsil edemez. Bu sebepten, programda yeni bir veri tipi olan float, ondalıklı sayıları temsil edebilmek için kullanılmıştır. Ayrıca, ortalama hesabında iki tür arasındaki dönüşümü sağlamak için dönüşüm operatörü (cast operatörü) kullanılmıştır.Bu yeni özellikler programın yazılmasından sonra detaylı bir şekilde açıklanmıştır.

 

1          /* Şekil 3.8: fig03_08.c

2             Sayıcı kontrollü döngülerle

3             sınıf ortalaması bulan program */

4          #include <stdio.h>

5

6          int main( )

7          {

8             float ortalama ;             /* yeni veri tipi */

9             int sayici, not, toplam ;

10  

11           /* ilk değer atama */

12           toplam = 0;

13           sayici = 0;

14

15           /* işlem */

16           printf( "Notu giriniz (Çıkış için –1) : " );

17           scanf( "%d", &not );

18 

19           while ( not != -1 ) {

20              toplam = toplam + not;

21              sayici = sayici + 1;

22              printf( "Notu giriniz (Çıkış için –1) : " );

23              scanf("%d", &not);

24           }

25

26           /* sonlandırma */

27           if ( sayici != 0 ) {

28              ortalama = ( float ) toplam / sayici;

29              printf ( "Sınıf ortalaması %.2f", ortalama);

30           }

31           else

32              printf ( "Hiç not girilmemiştir\n" );

33

34           return 0;   /* Program başarılı bir şekilde sonlanmıştır */

35        }

 

Notu giriniz (Çıkış için –1) : 75

Notu giriniz (Çıkış için –1) : 94

Notu giriniz (Çıkış için –1) : 97

Notu giriniz (Çıkış için –1) : 88

Notu giriniz (Çıkış için –1) : 70

Notu giriniz (Çıkış için –1) : 64

Notu giriniz (Çıkış için –1) : 83

Notu giriniz (Çıkış için –1) : 89

Notu giriniz (Çıkış için –1) : -1

Sınıf ortalaması 82.50

Şekil 3.8 Sınıf ortalaması problemini nöbetçi kontrollü döngülerle çözen C programı ve örnek bir çıktısı.

 

Şekil 3.8‘de, while döngüsü (19.satır) içindeki birleşik ifadeye dikkat ediniz. Döngü ile dört ifadenin de tekrarlanabilmesi için bu ifadelerin küme parantezi içine alınması gerektiğine dikkat ediniz. Küme parantezleri olmadığında, son üç ifade döngü dışında kalır ve bilgisayarın kodu aşağıdaki biçimde algılamasına sebep olur.

 

while( not != -1 )

     toplam = toplam + not;

sayici = sayici + 1;

printf( “Notu giriniz (Çıkış için –1) :” );

scanf( “%d”, &not);

 

Bu, kullanıcı ilk not olarak –1 girmediğinde sonsuz döngü oluşmasına sebep olur.

 

İyi Programlama Alıştırmaları 3.8

Nöbetçi kontrollü döngülerde kullanıcıdan veri istenirken nöbetçi değerin her seferinde hatırlatılması gerekir.

 

Ortalamaların hesabında her zaman tamsayı değerleri hesaplayamayız. Sıklıkla ortalama, 7.2 ya da –93.5 gibi ondalıklı bir kısım içeren bir değerdir. Bu değerler  ondalıklı sayılar  (floating point numbers) ya da gerçek sayılar olarak adlandırılır ve float veri tipi ile temsil edilirler. Hesaplamadaki ondalık kısmı tutabilmek için, ortalama değişkeni float tipinde bildirilmiştir.Buna rağmen toplam/sayici işleminin sonucu bir tamsayıdır. Çünkü toplam ve sayici değişkenleri tamsayı değişkenleridir. İki tamsayıyı bölmek bize ondalık kısmı kaybolmuş bir tamsayı değeri verecektir. Hesaplama işlemi ilk önce yapıldığından, ondalık kısım, sonuç ortalama değişkenine atanmadan önce kaybolur. Tamsayı değerleriyle ondalık kısma sahip bir hesaplama yapabilmek için, işlemde kullanılacak değerleri geçici olarak  ondalıklı sayılara çevirmeliyiz. C, bu işlemi gerçekleştirmek için dönüşüm (cast) operatörünü kullanır.Programın 28.satırındaki

 

ortalama = (float) toplam / sayici;

 

ifadesi bir dönüşüm operatörü , ( float ), içermektedir.Bu operatör sayesinde, bu operatörün operandı olan toplam değişkeninin geçici olarak, ondalıklı sayı biçiminde bir kopyası oluşturulur. toplam değişkeninde depolanan değer hala bir tamsayıdır. İşlem artık, ondalıklı bir sayının (toplam değişkeninin geçici olarak float tipine çevrilmiş kopyası), sayici değişkeni içinde tutulan tamsayı değerine bölünmesi haline gelmiştir. C derleyicisi, operandlarının tipi aynı olan deyimleri hesaplayabilir. Operandların aynı tipte olmaları için, derleyici seçilen operandlara  terfi ( promotion ) adı verilen bir işlem uygular. Örneğin, int ve float veri tipini içeren bir deyimde, ANSI standardı int operandlarının kopyalarının oluşturulmasını ve float tipine  terfi ettirilmesini söylemektedir. Örneğimizde, sayici değişkenin kopyası oluşturulup, float tipine terfi edildikten sonra işlem yapılmakta ve ondalıklı biçimdeki sonuç ortalama değişkenine atanmaktadır. ANSI standardı, değişik tipteki operandlar arasındaki terfi işlemleri için bir takım kurallara sahiptir. 5.ünitede tüm standart veri tipleri ve terfi sıraları anlatılacaktır.

 

Dönüşüm operatörleri, her veri tipi için geçerlidir. Dönüşüm operatörleri, veri tipi isminin parantez içine alınmasıyla oluşturulur. Dönüşüm operatörü tekli bir operatördür. Yani tek bir operand kullanılır. İkinci ünitede, ikili aritmetik operatörleri çalışmıştık. C, ayrıca artı ( + ) ve eksi ( - ) operatörlerinin tekli biçimlerini de içermektedir. Böylece programcı –7 ya da +5 gibi deyimler yazabilmektedir. Dönüşüm operatörleri, sağdan sola doğru işler ve diğer tekli operatörlerle, örneğin, tekli artı ( + ) ve tekli eksi ( - ) operatörleriyle aynı seviyede önceliğe sahiptir. Bu öncelik,  *, / ve % operatörlerinden bir seviye üstte ve parantez operatöründen bir seviye alttadır.

Şekil 3.8’de, 29.satırdaki printf  ifadesindeki dönüşüm belirteci ortalama  değişkeninin değerini yazdırmak için %.2f biçiminde kullanılmıştır. f, ondalıklı bir değerin yazdırılacağını belirtmektedir. .2 ise, değerin hangi duyarlık ile gösterileceğini belirtir ve gösterilecek değerin, noktadan sonra iki basamak içerebileceği anlamına gelir. Eğer %f dönüşüm belirteci tek başına kullanılırsa, değerleri 6 duyarlığında yazdırır. Yani noktadan sonra 6 basamak yazdırır. Bu, %.6f yazmak ile aynıdır. Ondalıklı sayılar duyarlık ile yazdırıldıklarında, yazdırılan değerin belirtilen sayıda ondalıklı kısım içerebilmesi için değer yuvarlanır. Hafızadaki değer değiştirilmez. Aşağıdaki ifadeler çalıştırıldığında, 3.45 ve 3.4 değerleri yazdırılır.

 

printf(“%.2f\n”,3.446);          /*3.45 yazdırılır*/

printf(“%.1f\n”,3.446);          /*3.4 yazdırılır*/

 

Genel Programlama Hataları 3.8

scanf ifadesi içindeki biçim kontrol dizesi içinde dönüşüm belirtecini, duyarlık ile birlikte kullanmak hatadır. Duyarlık yalnızca printf dönüşüm belirteçleriyle kullanılır.

 

Genel Programlama Hataları 3.9

Ondalıklı sayıların mükemmel bir biçimde gösterilebileceklerini düşünerek bu sayıları kullanmak hatalı sonuçlar üretilmesine sebep olur. Ondalıklı sayılar çoğu bilgisayarda yaklaşık olarak temsil edilirler.

 

İyi Programlama Alıştırmaları 3.9

Eşitlik söz konusu olduğunda ondalıklı sayıları karşılaştırmayınız.

 

Ondalıklı sayılar, her zaman %100 kesin olmasalar da bir çok uygulamada kullanılırlar. Örneğin, 37.6 sıcaklığının normal vücut sıcaklığı olduğunu söylediğimizde çok fazla ondalıklı basamak belirtmemize gerek yoktur. Sıcaklığı termometreden 37.6 olarak okuduğumuzda, vücut sıcaklığının gerçek değeri 37.5999473210643 olabilir. Burada anlatılan, bu değer yerine 37.6 kullanılmasının çoğu uygulamada yeterli olacağıdır. Bu konu hakkında daha fazla bilgiyi ileride yeniden vereceğiz. Ondalıklı sayıların oluşmasındaki bir diğer sebep de bölme işlemidir. Onu üçe böldüğümüzde sonuç 3.3333333... dır ve üçlerin dizisi sonsuza kadar devam etmektedir. Bilgisayar, böyle bir değeri tutmak için yalnızca belli sayıda boşluk ayıracağından ondalıklı sayıların yalnızca bir tahmin olduğu açıktır.

 

3.10 YUKARIDAN AŞAĞIYA ADIMSAL İYİLEŞTİRMEYLE ALGORİTMALAR  YAZMAK: DURUM3 (YUVALI KONTROL YAPILARI)

 

Şimdi başka bir problem üzerinde çalışalım. Algoritmamızı yine sahte kod ve yukarıdan aşağıya adımsal iyileştirmeyle oluşturacağız ve bu algoritmanın C kodunu yazacağız. Daha önceden kontrol yapılarının birbirleri üzerine (bir dizide) eklenebildiğini görmüştük. Şimdi ise C’de kontrol yapılarını, yapısal bir biçimde birleştirebilecek diğer yolu çalışacağız. Bu yola, bir kontrol yapısını diğeri içine yuvalamak denir.Aşağıdaki problemi inceleyiniz.

Bir kurs öğrencilerini bir lisans sınavına hazırlamaktadır. Geçen sene, bu kursu tamamlayan öğrencilerden bir kısmı lisans sınavına girmiştir. Kurs yöneticileri, öğrencilerin sınavdaki başarılarını öğrenmek istemektedir ve size sonuçları özetleyen bir program yazmanızı söylemişlerdir. Bu sınava giren 10 öğrencinin isimlerinin yer aldığı bir liste size verilmiştir. Bu listede eğer öğrenci sınavı geçmişse isminin yanında 1, eğer sınavdan kalmışsa isminin yanında 2 yazmaktadır.

 

Programınızın sınav sonuçlarını aşağıdaki şekilde analiz etmesi gerekmektedir.

Sizden;

 

1.Her sınav sonucunu girmenizi ve program başka bir sınav sonucunu alacağında ekrana 

  “Sonucu girin” mesajını yazdırmanızı

2.Her tipte sınav sonucunun  sayısını bulmanızı

3.Kaç öğrencinin sınavı geçtiğini ve kaçının kaldığını özetleyen bir gösterge hazırlamanızı

4.Eğer 8’den fazla öğrenci sınavı geçtiyse “yüksek başarı”  mesajını yazdırmanızı istemektedirler.

 

Problemi dikkatlice okuduktan sonra aşağıdaki gözlemleri yaparız:

 

1.Program 10 test sonucunu işleyecektir. Sayıcı kontrollü döngü kullanılacaktır.

2.Her test sonucu 1 ya da 2 gibi bir sayıdır. Program yeni bir sonuç okuduğunda bu sonucun 1 mi yoksa 2 mi olduğuna karar vermelidir. Algoritmamızda 1 olması durumunu inceleyeceğiz. Eğer sayı 1 değilse 2 olduğunu düşüneceğiz. ( Bu ünitenin sonunda bu kabullenmeye benzer bir dizi alıştırma bulacaksınız )

3.İki sayıcı kullanılacaktır. Bunlardan birincisi sınavı geçen öğrenci sayısını, ikincisi ise sınavdan kalan öğrenci sayısını saymak için kullanılacaktır.

4.Program tüm sonuçları işledikten sonra, sınavı geçen öğrenci sayısının 8’den fazla olup olmadığına karar vermelidir.

Şimdi yukarıdan aşağıya adımsal iyileştirmeyi kullanalım. En başa aşağıdaki sahte kodu yazalım:

 

Sınav sonuçlarını incele ve yüksek başarı durumunun gerçekleşip gerçekleşmediğini belirle.

 

Bu kodun tüm programın bir özeti olduğunu tekrar vurgulamak istiyoruz. Ancak bu kodu C programına çevrilebilecek kadar detaylandırabilmek için birkaç iyileştirme yapmalıyız. İlk iyileştirmemiz şu şekildedir:

 

Değişkenleri tanımla, 10 notu gir ve kalanlarla geçenleri say,

Sınav sonuçlarının özetini yazdır ve yüksek başarı sağlandı mı karar ver.

 

Bu iyileştirme sonucunda da tüm programın bütünü anlatılmış olsa bile hala iyileştirmeler yapmalıyız. Geçen ve kalanları kaydetmek için sayıcılara, döngü sürecini kontrol etmek için bir başka sayıcıya ve kullanıcının gireceği veriyi tutacağımız bir değişkene ihtiyacımız vardır.Bu sebepten,

 

Değişkenleri tanımla

 

sahte kodunu

 

Geçenler değişkenini sıfıra ata.

Kalanlar değişkenini sıfıra ata

Öğrenci değişkenini bire ata

 

biçiminde iyileştirebiliriz.                  

 

On notu gir ve geçenlerle kalanları say

 

sahte kodu, her sınavın sonucunu başarılı bir şekilde girebileceğimiz bir döngüye ihtiyaç duymaktadır. Burada, 10 adet sınav sonucu olduğunu kesin olarak bildiğimizden sayıcı kontrollü döngü kullanabiliriz.  Döngünün içinde (döngünün içine yuvalanmış), bir çiftli seçim yapısı kullanarak, sınav sonucunun geçer bir not ya da kalır bir not olduğuna karar verip uygun sayıcıları arttırırız. Sahte kodun iyileştirilmiş hali

 

Öğrenci sayıcısı 10’a eşit ya da 10’dan küçükken yeni sınav sonucunu al

           

Eğer ( if ) öğrenci geçmişse

                 Geçenlere bir ekle

     Aksi takdirde ( else )

                 Kalanlara bir ekle

 

Öğrenci sayıcısına bir ekle

 

Boş satırların if/else kontrol yapısını açığa çıkartmak için konulduğuna dikkat ediniz. Böylelikle programın okunurluğu arttırılmıştır.

 

Sınav sonuçlarının özetini yazdır ve yüksek başarı sağlandı mı karar ver

 

Kodunu aşağıdaki biçimde iyileştirebiliriz:

 

Geçenlerin sayısını yazdır

Kalanların sayısını yazdır

Eğer(if)  8‘den fazla öğrenci geçmişse

          “Yüksek başarı” yazdır.

 

İkinci iyileştirmenin tamamı, Şekil 3.9’da gösterilmiştir. Boş satırların, while yapısını vurgulamak için bırakıldığına ve programın okunurluğunun arttırıldığına dikkat ediniz.

Bu sahte kod C’ye dönüştürülebilecek kadar iyileştirilmiştir. C programı ve bu programın iki örnek çıktısı Şekil 3.10’da gösterilmiştir. Programda, değişkenler bildirilirken aynı anda değişkenlere ilk değer atandığına dikkat ediniz. Bu, C’nin önemli özelliklerinden biridir. Bu şekildeki atamalar derleme zamanında gerçekleşir.

 

Performans İpuçları3.1

Değişkenler bildirilirken, değişkenlere ilk değer atamak programın çalışma zamanını kısaltır.

 

Yazılım Mühendisliği Gözlemleri 3.6

Bilgisayarda bir problemi çözmedeki en zor kısmın çözüm algoritması geliştirmek olduğu tecrübeyle sabittir. Doğru algoritma geliştirildikten sonra çalışan bir C programı geliştirme süreci oldukça kolaydır.

 

Yazılım Mühendisliği Gözlemleri 3.7

Çoğu programcı, programlarını sahte kod gibi program geliştirme araçları kullanmadan yazarlar ve esas hedeflerinin problemi bilgisayarda çözmek olduğunu düşünürler. Bu sebepten de sahte kod yazmanın sonuçları üretme zamanını geciktirdiğini düşünürler.

 

Gecenler değişkenini sıfıra ata.

Kalanlar değişkenini sıfıra ata

Öğrenci değişkenini bire ata

 

Öğrenci sayıcısı 10’a eşit ya da 10’dan küçükken yeni sınav sonucunu al

           

Eğer öğrenci geçmişse

                 Geçenlere bir ekle

        Aksi takdirde

                 Kalanlara bir ekle

 

Öğrenci sayicisına bir ekle

 

Gecenlerin sayısını yazdır

Kalanların sayısını yazdır

Eğer 8‘den fazla öğrenci geçmişse

          “Yüksek başarı” yazdır

Şekil 3.9 Sınav sonuçları programı için sahte kod.

 

1          /* Şekil 3.10: fig03_10.c

2             Sınav sonuçlarının analizi */

3          #include <stdio.h>

4

5          int main( )

6          {

7             /* Bildirimde değişkenlere ilk değer vermek */

8             int gecenler = 0, kalanlar = 0, ogrenci = 1, sonuc;

9

10           /* sayıcı kontrollü döngüyle 10 sonucun işlenmesi*/

11           while ( ogrenci <= 10 ) {

12              printf ( "Sonucu girin (1 = geçti, 2=kaldı ): " );

13              scanf( "%d", &sonuc );

14

15              if ( sonuc == 1 )        /* if/else, while içinde yuvalanmıştır. */

16                 gecenler = gecenler + 1;

17              else

18                kalanlar = kalanlar + 1;

19

20              ogrenci = ogrenci + 1;

21           }

22

23           printf ( "Geçenler %d\n", gecenler);

24           printf( "Kalanlar %d\n", kalanlar);

25       

26           if (gecenler > 8 )

27              printf( " Yüksek başarı\n" );

28

29           return 0;   /* Program başarılı bir şekilde sonlanmıştır. */

30        }

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 2

Sonucu girin (1 = geçti, 2=kaldı ): 2

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 2

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 2

Geçenler 6

Kalanlar 4

 

 

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 2

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Sonucu girin (1 = geçti, 2=kaldı ): 1

Geçenler 9

Kalanlar 1

Yüksek başarı

Şekil 3.10 Sınav sonuçları problemi için C programı ve bu programın iki örnek çıktısı.

 

 

3.11 ATAMA OPERATÖRLERİ

 

C, atama ifadelerini kısaltmak için bir çok atama operatörüne sahiptir.Örneğin,

c = c+3;   

ifadesi toplama atama operatörüyle,+=, aşağıdaki biçimde kısaltılabilir.

c += 3;

 

+= operatörü, operatörün sağındaki deyimin değerini operatörün solundaki değişkenin değerine ekler ve sonucu operatörün solundaki değişkene kaydeder.

değişken = değişken   operatör   deyim;

 

şeklindeki her ifade

 

değişken operatör =deyim;

 

şeklinde yazılabilir. Burada operatör,  +,-,*,/ ya da % gibi tekli operatörler ya da 10.Ünitede anlatacaklarımızdan birisi olabilir.

Böylece, c += 3; ifadesinin, c’ye 3 eklediğini anlamış olduk. Şekil 3.11, aritmetik atama operatörlerini, bu operatörleri kullanan örnek ifadeleri ve açıklamaları göstermektedir.

 

Atama Operatörü      Örnek Deyim             Açıklama               Atar

int c = 3, d = 5, e = 4, f = 6, g = 12; olduğunu kabul ediniz.

+=                               c += 7                         c = c + 7                  c’ ye 10’ u

-=                                d -= 4                          d = d – 4                 d’ ye 1’i

*=                               e *= 5                         e = e * 5                  e’ ye 20’ yi

/=                                f /= 3                           f = f / 3                    f’ e 2’ yi

%=                             g %= 9                       g = g % 9               g’ ye 3’ü

 

Şekil 3.11 Aritmetik atama operatörleri

 

Performans İpuçları 3.2

Şu ana kadar bahsettiğimiz performans ipuçlarından çoğu küçük geliştirmeler yapmaktadır, bu sebepten okuyucu bunları önemsememeyi düşünebilir. Buradaki önemli nokta performans ipuçlarının bütününün birlikte yapacağı etkidir. Bu etki, programlarınızı önemli bir biçimde hızlandırabilir. Ayrıca küçük bir iyileştirme çok fazla sayıda tekrar edilen bir döngü içine yerleştirilirse önemli bir geliştirme sağlanır.

 

3.12 ARTIRMA VE AZALTMA OPERATÖRLERİ

 

C, tekli artırma operatörü ( ++ ) ve tekli azaltma operatörünü ( -- ) kullanmamıza izin verir.Bu operatörlerin özetini Şekil 3.12’de bulabilirsiniz.Eğer c değişkeni 1 arttırılacaksa, c = c +1 ya da c += 1  yerine artırma operatörü de kullanılabilir. Eğer artırma ya da azaltma operatörleri değişkenden önce yerleştirilirse, sırasıyla ön arttırma ( preincrement ) ya da ön azaltma (predecrement) olarak adlandırılır. Eğer artırma ya da azaltma operatörleri değişkenden sonra yerleştirilirse, sırasıyla son artırma ( postincrement ) ya da son azaltma( postdecrement ) olarak adlandırılırlar. Ön artırma (ön azaltma) ile öncelikle değişkenin değeri bir arttırılır (azaltılır ) ve değişkenin yeni değeri, değişkenin içinde bulunduğu deyimde kullanılır. Son artırma (son azaltma) ile değişkenin o andaki değeri deyimde kullanıldıktan sonra değişkenin değeri bir arttırılır. ( azaltılır )

 

Şekil 3.13’te, ++ operatörü için ön artırma ve son artırma biçimleri incelenmiş ve aralarındaki fark gösterilmiştir. c değişkenine son artırma uygulanması, c değişkeninin değerinin printf ifadesi içinde kullanıldıktan sonra arttırılmasına sebep olmuştur. c değişkenine ön artırma uygulanması, c değişkeninin değerinin printf ifadesinden önce arttırılmasına ve yeni değerin printf ifadesi içinde kullanılmasına sebep olmuştur.

 

Operatör

Örnek deyim

Açıklama

++ 

++a

a’yı bir arttır ve a’nın yeni değerini a’nın içinde   bulunduğu deyimde kullan                 

 

++

a++

a’nın değerini a’nın içinde bulunduğu deyimde kullan ve daha sonra a’yı bir arttır.

--

--b

b’yi bir azalt ve b’nin yeni değerini b’nin içinde bulunduğu deyimde kullan

--

b--

b’nin değerini b’nin içinde bulunduğu deyimde kullan ve daha sonra b’yi bir azalt

Şekil 3.12 Arttırma ve azaltma operatörleri

 

1          /* Şekil 3.13: fig03_13.c

2             Ön arttırma ve son artırma */

3          #include <stdio.h>

4

5          int main ( )

6          {

7             int c = 5;

8            

9             printf( "%d\n", c );

10           printf( "%d\n", c++ );    /* Ön arttırma */

11           printf( "%d\n\n", c );

12  

13           c = 5;

14           printf( "%d\n", c );

15           printf( "%d\n", ++c );    /* Son artırma */

16           printf( "%d\n", c );

17       

18           return 0;   /* Program başarılı bir şekilde sonlanmıştır */

19        }

 

 

5

5

6

 

5

6

6

 

Şekil 3.13 Ön arttırma ve son azaltma arasındaki fark

 

Program c’nin değerini ++ operatörü kullanılmadan önce ve sonra göstermektedir. Azaltma operatörü(--) benzer biçimde çalışmaktadır.

 

İyi programlama Alıştırmaları 3.10

Tekli operatörlerle, operandları arasında boşluk bırakılmamalıdır.

 

Şekil 3.10’daki 3 atama ifadesi

 

gecenler =gecenler+1;

kalanlar =kalanlar+1;

ogrenci  =ogrenci+1;

 

Atama operatörleriyle

 

gecenler += 1;

kalanlar += 1;

ogrenci += 1;

 

Ön arttırma operatörleriyle

 

++gecenler;

++kalanlar ;

++ogrenci ;

 

Son arttırma operatörleriyle

 

gecenler++;

kalanlar++;

ogrenci++;

 

biçiminde yazılabilirdi. Eğer bir ifadede değişkenin kendisi artırılıyor ya da azaltılıyorsa ön artırma ya da son arttırmanın aynı etkiyi yaratacağını bilmek önemlidir. Ön arttırma ve son arttırma (benzer olarak ön azaltma ve son azaltma), yalnızca değişken daha geniş bir deyimin içinde yer alıyorsa farklı etkilere sahiptir.

 

Arttırma ve azaltma operatörlerinin operandları olarak yalnızca değişken isimleri kullanılabilir.

 

Genel Programlama Hataları 3.10

Artırma ve azaltma operatörlerini değişken isimleri yerine bir deyimle birlikte kullanmaya çalışmak.Örneğin,  ++(x+1) yazmak bir yazım hatasıdır.

 

İyi Programlama Alıştırmaları 3.11

ANSI standardı, genellikle operatörün operandının hesaplama sırasını belirlememiştir.(Bu konudaki istisnaları 4.ünitede göreceğiz) Bu sebepten, programcı artırma ve azaltma operatörlerinin kullanıldığı ifadelerde belli bir değişkenin birden fazla kez arttırılması ya da azaltılmasından kaçınmalıdır.

 

Şekil 3.14’te, şu ana kadar gösterdiğimiz operatörlerin öncelik sıralarını ve işleme biçimlerini bulacaksınız. Operatörlerin önceliği yukarıdan aşağıya gidildikçe azalmaktadır. İkinci sütunda operatörlerin işleme biçimlerini bulacaksınız. Koşullu operatör ( ?: ), tekli arttırma ( ++ ) tekli azaltma ( -- ), artı ( + ), eksi ( - ) ve dönüşüm operatörleriyle =, +=, -=, *=, /=, %= atama operatörlerinin sağdan sola doğru işlediğine dikkat ediniz. Üçüncü sütun çeşitli operatör gruplarının isimlerini belirtmektedir.Şekil 3.14’teki diğer tüm operatörler soldan sağa doğru işlerler.

 

Operatörler                                                              İşleyiş                        Tip

  ( )                                                                             soldan sağa                  parantez

 ++      --         +          -            (tip)                          sağdan sola                   tekli

*          /           %                                                       soldan sağa                  multiplicative

+          -                                                                     soldan sağa                  additive

<          <=       >          >=                                          soldan sağa                  karşılaştırma

= =      !=                                                                   soldan sağa                  eşitlik

?:                                                                                sağdan sola                  koşullu

=          +=       -=        *=        /=                                sağdan sola                  atama

Şekil 3.14 Şu ana kadar anlatılan operatörlerin öncelikleri