C# İle biLGİsayar programlama temelleri (C# Programlama Kitabı) Svetlin Nakov & Co


"if" Koşullu Deyimi ve Kıvırcık Parantezler



Yüklə 3,36 Mb.
səhifə11/31
tarix03.11.2017
ölçüsü3,36 Mb.
#28822
1   ...   7   8   9   10   11   12   13   14   ...   31

5.3.1.2 "if" Koşullu Deyimi ve Kıvırcık Parantezler



if-deyiminin gövdesinde sadece bir komut varsa, koşullu işlecin gövdesini belirten kıvırcık parantezler, aşağıda gösterildiği gibi, atlanabilir (yazılmayabilir). Ancak, sadece bir komut için olsa bile parantezleri kullanmak iyi bir uygulama olacaktır. Böylece kod daha okunabilir hale gelir.
İşte kıvırcık parantezleri atlanmasıyla karışıklığa yol açan bir örnek:

int a = 6;

if (a > 5)

Console.WriteLine("The variable is greater than 5.");

Console.WriteLine("This code will always execute!");

// Bad practice: misleading code



Bu örnekte kod yanıltıcı bir şekilde biçimlendirilmiştir ve her iki yazdırma deyiminin de if-bloğunun gövdesinin bir parçasıymış izlenimini yaratmaktadır. Gerçekte, bu sadece ilk komut için geçerlidir.



Sadece bir komuttan oluşsalar bile, her zaman "if" bloklarının gövdesi içine kıvırcık parantezleri {} koyunuz!



5.3.2 Koşullu Deyim "if-else"
Programlama dillerinin çoğunda olduğu gibi, C# dilinde de else yantümcesi ile beraber kullanılan bir koşullu deyim vardır: if-else deyimi. Biçimi aşağıdaki gibidir:


if (Boole ifadesi)

{

Koşullu deyimin gövdesi;



}

else


{

else deyiminin gövdesi;

}



if-else yapısının biçimi, özel amaçlı sözcük olan if, Boole ifadesi, koşullu deyimin gövdesi, özel amaçlı sözcük olan else, ve else-gövde deyimlerinden oluşur. else-yapısının gövdesi, bir koşullu deyimin gövdesi gibi, kıvırcık parantez içine alınmış, bir yada daha çok komuttan oluşabilir.
Bu deyim şöyle çalışır: parantez içindeki ifade (Boole ifadesi) hesaplanır. Hesaplama sonucu true veya false – Boole olmalıdır. Bu değere bağlı olarak iki olası sonuç vardır. Boole ifadesi true hesaplanmışsa, koşullu deyimin gövdesi çalıştırılır ve else-ifadesi ve komutları çalıştırılmaz. Aksi takdirde, Boole ifadesi false hesaplanmış ise, else-gövdesi çalıştırılır, koşullu ifadenin ana gövdesi ve komutları çalıştırılmaz.

5.3.2.1 Koşullu Deyim "if-else" – Örnek
Sonraki örneğe bir göz atalım ve if-else deyiminin nasıl çalıştığını açıklayalım:

static void Main()

{

int x = 2;



if (x > 3)

{

Console.WriteLine("x is greater than 3");



}

else


{

Console.WriteLine("x is not greater than 3");

}

}



Program kodu şöyle yorumlanabilir: x> 3 ise, yazılan sonuç: "x is greater than 3" olur, aksi halde (else) sonuç: "x is not greater than 3" olur. Bu durumda, x = 2 olduğu için Boole ifadenin hesaplamasından sonra else işlecinin komutları çalıştırılacaktır. Örnekteki sonuç şudur:

X is not greater than 3


Aşağıdaki şema bu örneğin işlem akışını görüntülemektedir:


5.3.3 İçiçe "if" Deyimleri
Bazen bir programdaki veya uygulamadaki programlama mantığının birbirleri içinde ihtiva eden çoklu if-yapıları ile temsil edilmesi gerekmektedir. Bunlar içiçe if veya içiçe if-else yapıları olarak adlandırılır.
Bir if veya if-else yapısının bir başka if veya if-else yapısının gövdesi içinde yer almasına içiçe yerleştirme denir. Bu gibi durumlarda her else yantümcesi önceki en yakın if yantümcesine karşılık gelir. Hangi else deyiminin hangi if deyimi ile ilgili olduğu bu şekilde anlaşılır.
İçiçe üç seviyeyi aşmak iyi bir uygulama değildir, yani en çok üçten fazla koşullu ifadeyi birbiri içine yerleştirmemeliyiz. Bir sebepten ötürü, üçten fazla yapıyı içiçe yerleştirmeniz gerekiyorsa, kod parçasının bir bölümünü ayrı bir metoda taşımanız gerekmektedir (bkz. ”Yöntemler” Bölümü).
5.3.3.1 İçiçe "if" Deyimleri – Örnek
İçiçe if yapılarının kullanılmasına bir örnek aşağıda verilmiştir:

int first = 5;

int second = 3;


if (first == second)

{

Console.WriteLine("These two numbers are equal.");



}

else


{

if (first > second)

{

Console.WriteLine("The first number is greater.");



}

else


{

Console.WriteLine("The second number is greater.");

}

}



Yukarıdaki örnekte iki sayımız var ve iki adımda onları karşılaştırıyoruz: ilk olarak eşit olup olmadıklarını karşılaştırıyoruz ve eğer değillerse, hangisinin büyük olduğunu belirlemek için tekrar karşılaştırıyoruz. Buna göre yukarıdaki kodun çalıştırılmasının sonucu şöyledir:

The first number is greater.



5.3.4 "if-else-if-else-…" Dizileri
Bazen if yapılarından oluşan bir diziyi kullanmamız gerekir. Burada else yantümcesi yeni bir if yapısıdır. İçiçe if yapılarını kullanırsak, kod çok fazla sağa doğru itilecektir. Bu gibi durumlarda, bu yüzden yeni if yantümcesinin else yantümcesinden hemen sonra kullanımına izin verilir. Hatta bir iyi uygulama olarak kabul edilir. İşte bir örnek:

char ch = 'X';

if (ch == 'A' || ch == 'a')

{

Console.WriteLine("Vowel [ei]");



}

else if (ch == 'E' || ch == 'e')

{

Console.WriteLine("Vowel [i:]");



}

else if (ch == 'I' || ch == 'i')

{

Console.WriteLine("Vowel [ai]");



}

else if (ch == 'O' || ch == 'o')

{

Console.WriteLine("Vowel [ou]");



}

else if (ch == 'U' || ch == 'u')

{

Console.WriteLine("Vowel [ju:]");



}

else


{

Console.WriteLine("Consonant");

}



Örnekteki program bir değişkenin İngiliz alfabesinden bir ünlü harf olup olmadığını kontrol etmek için seri karşılaştırmalar yapar. Birbirini takip eden her karşılaştırma, bir önceki karşılaştırma true değilse yapılır. Sonuç olarak, if-koşullarından hiçbirisinin gerçekleşmemesi durumunda, en son else bloğu çalıştırılır. Böylece örneğin sonucu aşağıdaki gibi olur:

Consonant



5.3.5 Koşullu "if" Dizileri – İyi Uygulamalar
if-yapılarını yazma kuralları için tavsiye edilen ilkeler şöyledir:


  • Belirsizliği önlemek amacıyla if ve else sonrasında kıvırcık parantezlerle {} çevrili blokları kullanın.

  • if ve else sonrası her zaman içe doğru bir sekme ile çıkıntı yaparak okunabilirliği artırmak ve belirsizliği önlemek için kodu doğru şekilde biçimlendirin.

  • Eğer mümkünse, bir dizi if-else-if-else-... yapısı veya içiçe if-else deyiminin yerine, switch-case yapısını tercih edin. switch-case yapısını bir sonraki bölümde ele alacağız.

5.4 Koşullu Deyim "switch-case"
Aşağıdaki bölüm bir olasılıklar listesi arasından seçmek için kullanılan switch koşullu deyimini kapsamaktadır.

5.4.1 "switch-case" Deyimi Nasıl Çalışıyor?
switch-case yapısı belirli bir ifadenin hesaplanan değerine (en sıklıkla tamsayı türündeki) göre programlama kodunun hangi kısmının çalıştırılacağını seçer. Bir seçeneği seçmekte kullanılan yapının biçimi aşağıdaki gibidir:

switch (tamsayı_seçicisi)

{

case tamsayı_değeri_1:



komutlar;

break;


case tamsayı_değeri_2:

komutlar;

break;

// …


default:

komutlar;

break;

}




Seçici, bir sayı veya string gibi karşılaştırılabilir bir sonuç değerini döndüren bir ifadedir. switch işleci seçicinin sonucunu gövdesindeki case etiketi içerisinde yer alan her bir değer ile karşılaştırır. Etiket değerleriyle bir eşleşme bulunursa, karşılık gelen basit veya karmaşık yapı çalıştırılır. Eşleşme bulunmazsa varsayılan default deyimi çalıştırılır (mevcut ise). Seçicinin değeri, switch yapısı içindeki değerler ile karşılaştırılmadan önce hesaplanmalıdır. Etiket değerleri benzersiz olmalıdır, tekrar edilmemelidir.
Yukarıdaki tanımdan görülebileceği gibi, her case deyimi break işleci ile sonlandırılır, switch yapısının gövdesini sona erdiren bu işleçtir. C# derleyicisi kod içeren her case-bölümünün sonunda bir break sözcüğü bekler. case-deyiminden sonra hiçbir kod bulunmuyorsa break konulmayabilir ve çalışma sırası bir sonraki case-deyimine geçer ve buradan break işlecini bulana kadar devam eder. default yapısının sonrasında ise break zorunludur.
default yantümcesinin en sonda yazılması gerekli değildir, ancak switch yapısının ortasında değil, en sona konulması tavsiye edilir.

5.4.2 "switch" İfadeleri için Kurallar
switch deyimi birçok seçenek arasından seçim uygulamak için net bir yoldur (yani, kod yürütmek için birkaç alternatif yol arasından seçim yapmak). Belirli bir değere hesaplanan bir seçiciyi gerektirir. Seçici türü bir tamsayı, char, string yada enum olabilir. Örneğin bir seçici olarak dizi yada float kullanmak istiyorsanız işe yaramaz. Tamsayı veri türünden olmayan seçiciler için, if deyimlerini sıralı olarak kullanmalısınız.

5.4.3 Çoklu Etiketlerin Kullanımı
Birden fazla etiket kullanımı birden daha fazla durumda aynı yapıyı yürütmek istediğiniz zaman uygundur. Aşağıdaki örneğe bakalım:

int number = 6;

switch (number)

{

case 1:


case 4:

case 6:


case 8:

case 10:


Console.WriteLine("The number is not prime!"); break;

case 2:


case 3:

case 5:


case 7:

Console.WriteLine("The number is prime!"); break;

default:

Console.WriteLine("Unknown number!"); break;



}


Yukarıdaki örnekte, sonlarında break almayan case deyimlerini kullanarak birden fazla etiketi uyguluyoruz. Bu durumda, seçicinin birinci tamsayı değeri, 6 olarak, hesaplanır ve bu değer case deyimlerindeki her bir tamsayı değeri ile karşılaştırılır. Bir eşleşme bulunduğunda, izleyen kod bloğu çalıştırılır. Eşleşme bulunmazsa, default bloğu çalıştırılır. Yukarıdaki örneğin sonucu şöyledir:

The number is not prime!



5.4.4 "switch-case" Kullanırken İyi Uygulamalar


  • switch deyimini kullanırken kodun okunmasını kolaylaştırmak için iyi bir uygulama, default deyimini en sona koymaktır.

  • En sık rastlanan durumlarla başa çıkan case deyimlerini en başa koymak faydalıdır. Seyrek görülen durumlarla başa çıkan case deyimleri yapının sonunda yerleştirilebilir.

  • case etiketindeki değerler tamsayı ise, onların küçükten büyüğe sıralanması önerilir.

  • case etiketindeki değerleri karakter türünde ise, onların alfabetik sıralanması önerilir.

  • Her zaman programın normal çalışmasıyla işlenemez durumları işlemek için default bloğunu kullanmak tavsiye edilir. programın normal çalışması sırasında default bloğu ulaşılamaz olmalıysa, bunu bir hata raporlama kodu içine koyabilirsiniz.



5.5 Alıştırmalar


  1. İki tamsayı değişkenini alan ve ilki ikincisinden büyükse, değerlerini değiş-tokuş yapan bir if-deyimi yazın.

  1. Üç gerçek sayının çarpımını hesaplamadan işaretini (+ veya – olarak) gösteren bir program yazın. if yapılarından oluşan bir diziyi kullanın.

  2. İçiçe if deyimlerini kullanarak, üç tamsayının en büyüğünü bulan bir program yazın.

  3. 3 gerçek sayıyı azalan sırada sıralayın. İçiçe if deyimleri kullanın.

  4. (0-9) rakamlarından birisini kullanıcıya soran ve girişe bağlı olarak rakamın (İngilizce) kelime olarak karşılığını gösteren bir program yazın. Bir switch deyimini kullanın.

  5. İkinci dereceden bir denklemin a, b ve c katsayılarını alan: ax2 + bx + c, gerçek köklerini hesaplayan ve (varsa) yazdıran bir program yazın. İkinci dereceden denklemlerin 0, 1 yada 2 adet gerçek kökü olabilir.

  6. Verilen 5 sayıdan en büyüğünü bulan bir program yazın.

  7. Kullanıcının tercihine bağlı olarak, int, double veya string değişkeni olarak girdi alan bir program yazın. Değişken int veya double ise, program bunu 1 artırır. Değişken string ise, program dizenin sonunda "*" ekler. Konsola sonucu yazdırın. switch deyimi kullanın.

  8. 5 sayı verilmiştir. Toplamı 0 olan alt kümelerini bulan bir program yazın. Örnekler:

    • Eğer {3, -2, 1, 1, 8} sayıları verilmişse, -2, 1 ve 1 sayılarının toplamı 0 olur.

    • Eğer {3, 1, -7, 35, 22} sayıları verilmişse, toplamı 0 olan hiçbir alt küme yoktur.

  9. [1 ... 9] aralığında verilen skorlara aşağıdaki kurallar dahilinde bonus puanlar veren bir program yazın:

  • Skor 1 ve 3 arasında ise, program bunu 10 ile çarpar.

  • Skor 4 ve 6 arasında ise, program bunu 100 ile çarpar.

  • Skor 7 ve 9 arasında ise, program bunu 1000 ile çarpar.

  • Skoru 0 veya 9’dan daha fazla ise, program bir hata mesajı yazdırır.

  1. [0 ... 999] aralığında bir sayıyı İngilizce telaffuzuna karşılık gelen kelimeye dönüştüren bir program yazın. Örnekler:

  • 0 --> "Zero"

  • 12 --> "Twelve"

  • 98 --> "Ninety eight"

  • 273 --> "Two hundred seventy three"

  • 400 --> "Four hundred"

  • 501 --> "Five hundred and one"

  • 711 --> "Seven hundred and eleven"

Bölüm 6.Döngüler

6.1 Bölümün İçindekileri
Bu bölümde döngü programlama yapılarını inceleyeceğiz. Bu yapılar bir kod parçacığını tekrar tekrar yürütmemizi sağlar. Tekrarlı koşullamaları, aynı zamanda koşullu tekrarlamalar olarak da adlandırılabilir, nasıl uygulayacağımızı (while ve do-while döngüleri) ve for-döngüleri ile nasıl çalışacağımızı tartışacağız. Döngüleri tanımlamak için farklı olasılıkları örneklerle vereceğiz, onları nasıl yapılandırabileceğimizi ve önemli kullanım alanlarını örnekleyeceğiz. Son olarak, foreach- döngü yapısını ve nasıl birbiri (iç içe döngüler) içine yerleştirilen birden fazla döngüyü kullanabileceğimizi tartışacağız.

6.2 "Döngü" Nedir?
Programlama sırasında kod gereği bir dizi işlem sabit sayıda veya belirli bir durum gerçek (var olana) olana kadar tekrarlanır. Döngü tekrarlanan kaynak kodu yürüten temel bir programlama yapısıdır.
Bitmeyen döngüye sonsuz döngü denir. Döngü gövdesinin yürütülmesi bazı sıra dışı durumları kodlamak için, örneğin beklenmedik bir anda döngü gövdesi break işleci tarafından sonlandırılacaksa kullanılır. Daha sonra bunlara değineceğiz, ancak şimdi C# dilinde bir döngünün nasıl oluşturulacağına bakacağız.

6.2 While Döngüsü
En basit ve yaygın olarak kullanılan döngülerden biri while döngüsüdür.


while (koşul)

{

döngü gövdesi;



}

Yukarıdaki örnekte kodda koşul, değeri true veya false – olan Boole sonuç döndüren herhangi bir ifadedir. Bu döngü gövdesinin ne kadar tekrarlanacağını belirten döngü durumudur. Bu örnekte döngü gövdesi döngünün her tekrarında programlama kodunu yürütür, yani giriş koşulu her doğru olduğu zaman. while döngüsünün davranışı aşağıdaki şema ile temsil edilebilir:
tuval 5306
while döngüsünde, Boole ifadesi hesaplanan değeri true olduğu zaman döngü gövdesindeki işlemler yürütmeye alınır. Sonra tekrar girdi koşulunun hesaplanan değeri true olmaya devam ediyorsa döngünün gövdesi bir kere daha yürütülür. Tüm bunlar koşullu ifade false değer döndürüne kadar sürekli tekrar eder. Bu noktada döngü sonlanır ve program döngü gövdesinden hemen sonra gelen bir sonraki ilk satırla yürütmeye devam eder.
while döngüsünün gövdesi döngü koşulu en başta false döndürürse bir kez bile çalıştırılmaz. Döngü koşul durumu true olduğu sürece veya break edilmediği sürece döngü sonsuza kadar yürütülür.

6.2.1 While Döngüsünün Kullanımı
while döngüsünü kullanmanın çok basit bir örneğini düşünelim. Döngünün amacı, 0-9 aralığındaki sayıları artan sırada konsolda yazdırmaktır:


// Initialize the counter

int counter = 0;

// Execute the loop body while the loop condition holds

while (counter <= 9)

{

// Print the counter value



Console.WriteLine("Number : " + counter);

// Increment the counter

counter++;

}



Örnek kod çalıştırıldığında çıktı olarak sonucu aşağıdaki gibidir:


Number : 0

Number : 1

Number : 2

Number : 3

Number : 4

Number : 5

Number : 6

Number : 7

Number : 8

Number : 9




Döngülerin faydasını göstermek için ve döngüleri kullanarak çözülebilecek bazı sorunları göstermek için biraz daha örnek verelim.
6.2.2 1 ile Başlayan ve N’e Kadar Olan Sayıları Toplamak
Bu örnekte 1 ile başlayan n’e kadar olan sayının toplamını while döngüsünü kullanarak nasıl bulabileceğinizi inceleyeceğiz. n sayısını konsoldan okutacağız:


Console.Write("n = ");

int n = int.Parse(Console.ReadLine());

int num = 1;

int sum = 1;

Console.Write("The sum 1");

while (num < n)

{

num++;


sum += num;

Console.Write(" + " + num);

}

Console.WriteLine(" = " + sum);



İlk olarak num ve sum değişkenlerini 1 değerini atayarak başlatacağız. num değişkeninde önceki sayının toplamı eklediğimiz mevcut sayıyı tutacağız. Her döngüde bir sonraki sayıyı tutacak şekilde num değeri 1 artırılır. Daha sonra döngü koşulunda bu değerin 1 ile n aralığında olup olmadığı kontrol edilir. sum değişkeni herhangi bir zamanda 1 ile başlayan ve n’e kadar olan sayıların toplamını tutar. Döngüye girdikten sonra sonraki sayıyı belirten num sayısını sum içinde tutulan sayıya ekleriz. 1 ile başlayan ve n’e kadar olan tüm sayıları + ayırıcı ile konsolda yazdırırız, ve döngünün ardından toplamanın son sonucunu yazdırırız. n=17 ile program çalıştırıldığında çıktı olarak sonucu aşağıdaki gibidir:

N = 17

The sum 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 = 153




Döngüleri düzenlemek için diğer yapılara geçmeden önce, while döngüsünün kullanılmasına bir başka örnek verelim.

6.2.2 Asal Sayı Hesaplama – Örnek
Belirli bir sayının asal olup olmadığını kontrol etmek için bir program yazacağız. Konsoldan kontrol edilecek sayıyı okutacağız. Matematik’te asal sayının tanımı, yalnızca 1’e ve kendisine bölünebilen, bunun haricinde herhangi bir sayı ile bölünemeyen herhangi bir pozitif tamsayıdır. num sayısının asal olup olmadığını, bir döngü içinde 2 ile başlayan ve num sayısına kadar olan tüm sayılar ile bölünebilir olup olmadığını kontrol ederek bulabilirsiniz.

Console.Write("Enter a positive number: ");

int num = int.Parse(Console.ReadLine());

int divider = 2;

int maxDivider = (int)Math.Sqrt(num);

bool prime = true;

while (prime && (divider <= maxDivider))

{

if (num % divider == 0)



{

prime = false;

}

divider++;



}

Console.WriteLine("Prime? " + prime);



divider değişkeni sayının muhtemel bölen değerini tutar. İlk olarak ona 2 değerini atıyoruz (mümkün olan en küçük bölen). maxDivider değişkeni mümkün olan en büyük bölendir, bu sayının kare köküne eşittir. num değerinden daha büyük bölenleri düşünmüyoruz, çünkü num sayısının daha küçük bir böleni mutlaka vardır, ve bu nedenle num değerinden daha büyük sayıları kontrol etmeye gerek yoktur. Bu şekilde döngünün yinelenme sayısını azaltıyoruz.
Sonucu hesaplamak için prime adında bir Boole değişkeni kullanıyoruz. Başlangıç değerine true atanmıştır. Döngü içinden geçerken, sayının böleni meydana çıkarsa, prime değeri false olacaktır.
while döngüsünün koşulu “mantıksal ve” işleci ile ilişkilendirilmiş diğer iki alt-koşuldan oluşmuştur. Döngüyü yürütmek amacıyla, bu iki alt-koşulun aynı anda doğru olması gerekir. Döngünün bir noktasında num sayısının bir bölenini bulursanız, prime değişkeni false olacak ve döngü koşulu artık sağlanmayacaktır. Döngünün yürütülmesi ya num sayısının ilk bölenini bulana kadar devam eder yada 2 ile başlayan ve num’e kadar olan sayı aralığındaki tüm sayılardan hiçbirine bölünemez gerçeğinin doğru olmasına bağlıdır.
Yukarıdaki örnek giriş değerleri sırasıyla 37 ve 34 sayıları ile çalıştırıldığında çıktı olarak sonucu aşağıdaki gibidir:


Enter a positive number: 37

Prime? True



Enter a positive number: 34

Prime? False





6.2.3 "break" İşleci
break işleci zamanından önce doğal bir şekilde kendi yürütmesini tamamlamadan önce döngüden çıkmak için kullanılır. Döngü break işlecine ulaştığında sonlandırılır ve programın yürütülmesi döngü gövdesinden hemen sonra gelen satırdan devam eder. break işleci ile döngünün sonlandırılması ancak döngünün yinelenmesi sırasında gövde içinden yapılır. break komutu çalıştırıldığında döngü gövdesi içindeki kod çalıştırılmadan atlanır. Bir örnekle break ile döngüden çıkmayı göstereceğiz.
6.2.4 Faktöriyel Hesaplama – Örnek
Bu örnekte konsoldan girilen bir sayının faktöriyelini hesaplayacağız. Hesaplama sonsuz while döngüsü ve break işleci kullanılarak yapılacak. Faktöriyelin ne olduğunu ve nasıl hesaplandığını matematik bilgimizi kullanarak şöyle hatırlayalım. n tamsayısının faktöriyeli n değerinden daha az yada eşit tüm tamsayıların çarpımı olarak hesaplanan bir fonksiyondur. n! olarak yazılır ve tanım gereği aşağıdaki formüller faktöriyel için geçerlidir:


  • N! = 1 * 2 * 3 … (n-1) * n, n> 1 için;

  • 2! = 1 * 2;

  • 1! = 1;

  • 0! = 1.

n! çarpımı n’den daha küçük olan tamsayıların faktöriyeli olarak şöyle ifade edilebilir:

  • N! = (N-1)! * N, ilk değer için 0! = 1 kullanılarak.

n faktöriyelini hesaplamak için doğrudan tanımı kullanacağız:

int n = int.Parse(Console.ReadLine());

// "decimal" is the biggest C# type that can hold integer values

decimal factorial = 1;

// Perform an "infinite loop"

while (true)

{

if (n <= 1)



{

break;


}

factorial *= n;

n--;

}

Console.WriteLine("n! = " + factorial);



Önce factorial değişkenine ilk değer olarak 1 atıyoruz ve konsoldan bir n sayısı okutuyoruz. Döngü koşulu olarak true kullanarak sonsuz bir while döngü oluşturuyoruz. n değeri 1'e eşit yada daha az ise döngüyü sona erdirmek amacıyla break işlecini kullanıyoruz. Aksi takdirde, elimizdeki sonucu n ile çarpıp n’i de 1 azaltıyoruz. Pratikte döngünün ilk yinelemesinde factorial değişkeninin değeri n olur, ikinci yinelemede n * (n–1) olur ve böyle devam eder. Döngünün son tekrarında factorial değeri n * (n-1) * (n-2) ... * 3 * 2 çarpımıdır, ki bu da n! değerine eşittir.

Örnek programı çalıştırırsanız ve girdi olarak 10 girerseniz, çıktı olarak sonucu aşağıdaki gibidir:

10

n! = 3628800



6.3 Do-While Döngüsü
do-while döngüsü while döngüsüne benzerdir, ancak döngü koşulu, gövdenin her yürütülmesinden sonra kontrol edilir. Bu tür döngüler koşulu en sonda olan döngüler kategorisinde değerlendirilir ve sonunda test döngüsü (post-test loop) olarak adlandırılır. do-while döngüsünün yapısı şöyledir:

Do

{

yürütülebilir kod;



} while (koşul);


Tasarım gereği do-while döngüleri aşağıdaki şemaya göre yürütülür:

tuval 5287

İlk olarak döngü gövdesi çalıştırılır. Sonra döngü koşulu kontrol edilir. Doğru ise, döngünün gövdesi tekrar edilir, değilse döngü sona erer. Döngünün koşulu sağlanmayana kadar bu mantık tekrarlanır. Döngünün gövdesi en azından bir kez muhakkak yürütülür. Döngünün koşulu sürekli doğruysa, döngü hiç bitmez.
6.3.1 Do-While Döngüsü Kullanımı
İşlemler dizisinin tekrarlanarak ve döngü başında en az bir kez olmak üzere çalıştırılmasını garanti etmek için do-while döngüsü kullanılır.

6.3.2 Faktöriyel Hesaplama – Örnek

Bu örnekte yine belirli bir sayı n sayısının faktoriyelini hesaplayacağız, ancak bu kez sonsuz while döngüsünde yerine do-while kullanacağız. Mantık, önceki örnektekine benzerdir:

Console.Write("n = ");

int n = int.Parse(Console.ReadLine());

decimal factorial = 1;

do

{



factorial *= n;

n--;


} while (n > 0);

Console.WriteLine("n! = " + factorial);



Başlangıçta 1 sonucu ile başlıyoruz ve ardışık olarak her tekrarda sonucu n sayısı ile çarpıyoruz, ve n = 0 oluncaya kadar, n sayısını bir birim azaltıyoruz. Bu bize n * (n-1) * ... * 1 çarpımını verir. Son olarak, konsolda sonucu yazdırıyoruz. Bu algoritma her zaman en az bir çarpma gerçekleştirir ve bu nedenle n ≤ 0 için düzgün çalışmaz.

Yukarıdaki örnek n = 7 için çalıştırıldığında çıktı olarak sonucu aşağıdaki gibidir:


n = 7

n! = 5040



6.3.3 Büyük Sayının Faktoriyeli – Örnek
Daha önceki örnekte n sayısı için büyük bir değer atanmışsa, örneğin n = 100, ne olacağını merak ediyor olabilirsiniz. n! hesaplanırken decimal ondalık türünde taşma gerçekleşir ve sonuç System.OverflowException türünde bir istisnai durum olacaktır:

n = 100

Unhandled Exception: System.OverflowException: Value was either too large or too small for a Decimal.

at System.Decimal.FCallMultiply(Decimal& result, Decimal d1, Decimal d2)

at System.Decimal.op_Multiply(Decimal d1, Decimal d2)

at TestProject.Program.Main() in C:\Projects\TestProject\Program

.cs:line 17




100! değerini hesaplamak istiyorsanız veri türü olarak BigInteger ( .NET Framework 4.0 için yenidir ve eski .NET sürümlerinde eksiktir) kullanabilirsiniz. Bu tür çok büyük değer alabilen tamsayıları (örneğin 100.000 basamaklı) temsil eder. BigInteger sınıfında kayıtlı sayıların boyutu üzerinde hiçbir sınırlama (yeterli RAM olduğu sürece) yoktur.
BigInteger sınıfını kullanmak için projemiz içinden System.Numerics.dll çevirisine (bu çok büyük tamsayılar ile çalışmak için standart .NET kütüphanesidir ve VS projelerinde varsayılan olarak başvurulmamaktadır) bir başvuru eklemeniz gerekir. Visual Studio Solution Explorer penceresinde mevcut proje başvuruları üzerine sağ tıklayarak bir başvuru ekleyebilirsiniz:

Listeden arayarak System.Numerics.dll kütüphanesini (assembly) seçin:

Assembly listede yoksa, Visual Studio projesi muhtemelen .NET Framework 4.0 veya üzerini hedef almıyor anlamına gelir. Bu durumda ya yeni bir proje oluşturmalısınız veya mevcut sürümünü değiştirmeniz gerekir:

Sonra "using System.Numerics;" satırını kodda program sınıfından önceki satıra eklememiz ve decimal yerine BigInteger yazmamız gerekir. Program aşağıdaki şekli alır:


using System;

using System.Numerics;


class Factorial

{

static void Main()



{

Console.Write("n = ");

int n = int.Parse(Console.ReadLine());

BigInteger factorial = 1;

do

{

factorial *= n;



n--;

} while (n > 0);

Console.WriteLine("n! = " + factorial);

}

}





Şimdi n = 100 için programı çalıştırın, 158 basamaklı bir sayı olan 100 faktöriyel değerini alacaksınız:

n = 100

n! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000




BigInteger ile 1000!, 10000! ve hatta 100000! değerlerini hesaplayabilirsiniz. Bu biraz zaman ister, ancak OverflowException oluşmaz. BigInteger sınıfı çok güçlüdür, ancak int ve long türlerinden birçok kere daha yavaş çalışır. Size tatsız bir sürpriz gibi görünse de .NET Framework’te "Big Decimal" sınıfı yoktur, sadece "Big Integer" vardır.
6.3.4 [N..M] Aralığındaki Sayıların Çarpımı – Örnek
do-while döngüleri ile çalışan başka, daha ilginç bir örnek verelim. Amaç [n...m] aralığı içindeki bütün sayıların çarpımını bulmaktır. İşte bu soruna örnek bir çözüm:

Console.Write("n = ");

int n = int.Parse(Console.ReadLine());


Console.Write("m = ");

int m = int.Parse(Console.ReadLine());


int num = n;

long product = 1;

do

{

product *= num;



num++;

} while (num <= m);


Console.WriteLine("product[n...m] = " + product);


Örnek kodda, arka arkaya her tekrarda num değişkenine n, n + 1, ..., m değerleri atanır, ve product değişkeninde bu değerlerin çarpımı biriktirilir. Kullanıcıdan n sayısını girmesi beklenir. Girilen sayı m 'den daha az olmalıdır. Aksi takdirde, sonuç olarak n sayısı alınır.
n = 2 ve m = 6 için programı çalıştırırsanız aşağıdaki sonucu elde edersiniz:


n = 2

m = 6


product[n...m] = 720


Dikkatli olun: çarpım çok hızlı büyür, bu nedenle hesaplanan sonuç için long yerine BigInteger kullanmanız gerekebilir. Ayrıca gizli tamsayı taşmasından kaçının. Denetlenmeyen kod sessizce taşacaktır ve yukarıdaki kod hata göstermek yerine hatalı çıktı üretecektir. Bunun üstesinden gelmek için, çarpmayı hesaplayan satırı checked anahtar sözcüğü ile yazabilirsiniz.

6.4 For Döngüsü
For-döngüleri while ve do-while döngülerine göre biraz daha karmaşıktır, ancak diğer taraftan, daha az kod ile daha karmaşık görevleri çözebilir. For-döngüleri aşağıdaki şemaya göre yürütülür:


For-döngüsü yapısı bir başlangıç ​​bloğu, (A), koşul, (B), gövde (D) ve döngü değişkenlerini güncelleyen komutlar (C) içermektedir. Kısa süre sonra detaylı olarak bunları açıklayacağız. Bundan önce for-döngüsünün yapısına bakalım:

for (başlatma; koşul; güncelleme)

{

döngü gövdesi;



}


Burada sayaç için bir başlatma bölümü (int i = 0), Boole koşul (i < 10), sayaç güncellenmesi için bir ifade (i++, i--, yada örneğin, i = i + 3) ve döngü gövdesini görüyoruz.
For-döngüsünde görülen sayaç diğer türdeki döngülerde bulunmamaktadır. Sayacın verilen başlangıç değeri son değere kadar çoğunlukla artan sırada olmak üzere değişir, örneğin 1’den 100’e kadar. Verilen bir for-döngüsü için yineleme sayısı, yürütmeye başlamadan önce genellikle bilinir. For-döngüsü artan veya azalan sırayla ardışık olarak veya belli bir aralıkta güncellenen döngü değişkenleri kullanabilir. Döngü değişkenleri bir veya birkaç tane olabilir, biri artarken diğeri – azalabilir. Yinelemeler 2’den 1024’e kadar 2’nin katları kadar artırılarak da tekrarlanabilir, çünkü döngü değişkenlerinin güncellemesi sadece toplama içermez, ancak başka aritmetik (ve diğer) işlemleri de içerebilir. Bu listelenen elemanların hiçbirisini kullanmak zorunlu olmadığı için hepsini atlayabilir ve sonsuz döngü elde edebiliriz.

for ( ; ; )

{

// Loop body



}


Şimdi for-döngüsünü oluşturan parçaları detaylarıyla ayrı ayrı düşünelim.

6.4.1 For Döngüsünün Başlatılması
For-döngüleri bir başlatma bloğu alabilir:

for (int num = 0; …; …)

{

// The variable num is visible here and it can be used



}

// Here num can not be used




Başlatma bloğu sadece bir kez çalıştırılır, sadece döngüye girmeden önce. Genellikle başlatma bloğu sayaç-değişkenini (ayrıca döngü değişkeni olarak da adlandırılır) bildirmek için kullanılır ve onun ilk değerini ayarlar. Bu değişken "görünür" ve sadece döngü içinde kullanılabilir. Başlatma bloğunda birden fazla değişkeni bildirmek ve başlatmak mümkündür.
6.4.1 For Döngü Koşulu
For-döngüleri bir döngü koşulunu hesaplayabilir:

for (int num = 0; num < 10; …)

{

// Loop body



}


Koşul (döngü koşulu) while-döngüsüne benzer şekilde döngünün her tekrarından önce bir kere hesaplanır. true sonucu için döngünün gövdesi çalıştırılır, false sonucu için gövde atlanır ve döngü sona erdirilir (döngü gövdesinin son satırından hemen sonra program devam eder).

6.4.2 Döngü Değişkenlerinin Güncellenmesi
Son olarak, for-döngüsü değişkenini güncelleyen kodun yapısına bir örnek vereceğiz:


for (int num = 0; num < 10; num++)

{

// Loop body



}


Döngü gövdesi çalıştırıldıktan sonra güncelleme kodu her yinelemede yürütülür. Çoğunlukla sayaç-değişkeninin değerini güncellemek için kullanılır.

6.4.3 Döngü Gövdesi
Döngü gövdesi kaynak kod bloğu içeriyor. Başlatma bloğunda bildirilen döngü değişkenleri döngü gövdesinde de kullanılabilir.

6.4.4 For-Döngüsü – Örnek
For-döngüsüne bir örnek aşağıda verilmiştir:

for (int i = 0; i <= 10; i++)

{

Console.Write(i + " ");



}


Örnek kod çalıştırıldığında çıktı olarak sonucu aşağıdaki gibidir:

0 1 2 3 4 5 6 7 8 9 10


Döngü için başka, daha karmaşık bir örnek aşağıda verilmiştir: İki değişken i ve sum sözkonusudur. Her ikisinin de başlangıç değeri 1 olarak atanmıştır, ancak döngü yinelemelerinde arka arkaya bunları güncelleştiriyoruz:

for (int i = 1, sum = 1; i <= 128; i = i * 2, sum += i)

{

Console.WriteLine("i={0}, sum={1}", i, sum);



}


Buna göre döngü çalıştırıldıktan sonra çıktısı aşağıdaki gibidir:


i=1, sum=1

i=2, sum=3

i=4, sum=7

i=8, sum=15

i=16, sum=31

i=32, sum=63

i=64, sum=127

i=128, sum=255





Yüklə 3,36 Mb.

Dostları ilə paylaş:
1   ...   7   8   9   10   11   12   13   14   ...   31




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin