11 Şubat 2023 Cumartesi

C# Temelleri 2

 Merhaba direk bu sayfaya gelenler için belirteyim, bu yazı serinin ikinci yazısı. İlk bölüm için 

https://ujk-ujk.blogspot.com/2023/01/c-temelleri-1.html

sayfasına bakınız. 

İlk bölümde gördüğümüz temellerden sonra şimdi biraz daha gelişmiş metodlar ve kodlama teknikleri ile devam ediyoruz.


C# Rastgele Sayı Üretmek

Yazılım ile rastgele sayılar (random numbers) üretilirken aslında üretilen tam bir rastgele sayı değildir. Biliyorsunuz bilgisayarlar rastgele işlem yapmaz, ama kodlama ile bize rastgele imiş gibi gelecek, ne olacağı tahmin edilemeyecek sayılar üretilebilir. Bu yüzden bu sayılara sahte rastgele sayılar (pseudo random numbers) denir. Rastgele sayı üretmek için önce bir Random tipi değişken tanımlayarak başlarız. 

        static void Main(string[] args)
        {
            Random rastgele = new Random();
            int sayı = rastgele.Next(1, 7);

            Console.WriteLine(sayı);

            Console.ReadKey();
        }

Önce rastgele adında Random tipi bir nesne üretiyoruz. rastgele nesnesinin Next() metodu bize rastgele bir tamsayı üretir. Parametresinde ise üretilecek rastgele tamsayının hangi değerler arasında olacağını belirtiriz. İlk parametre üretilecek sayının olası en küçük değeridir. Yukarıdaki örnekte sayının en az 1 değerinde olması istenmiş. Üretilecek sayı ikinci parametrede verilen değerden küçük olmalıdır. Örnekte ikinci değer 7 girildiği için üretilecek sayı en fazla 6 olabilir. Bu noktaya dikkat edelim üretilecek sayı ilk parametreden büyük ya da eşit ama ikinci parametreden küçük olmalıdır. İkinci parametredeki değer olası aralığa dahil değildir. Bu yukarıdaki örnek bir tavla zarının yazılım ile simülasyonu oluyor ve 1'den 6'ya kadar rastgele bir sayı üretiyor. Örneğin 1'den 20'ye kadar bir rastgele sayı üretmek istersek,

            int sayı = rastgele.Next(1, 21);

yazarız. Random nesnenin double tipi sayı üreten NextDouble() metodu da vardır. 

            Random rastgele = new Random();
            //int sayı = rastgele.Next(1, 21);
            double sayı = rastgele.NextDouble();

            Console.WriteLine(sayı);

Bu metod parametresiz ve bize 0'dan 1'e kadar rastgele bir double sayı üretir. Birden fazla rastgele sayı üretmek için yeni bir Random nesnesi oluşumuna ihtiyacımız yok, rastgele oluşumunu kullanarak yeni sayılar üretmeye devam edebiliriz. 

            int sayı1 = rastgele.Next(1, 7);
            int sayı2 = rastgele.Next(1, 7);
            int sayı3 = rastgele.Next(1, 7);

            Console.WriteLine(sayı1);
            Console.WriteLine(sayı2);
            Console.WriteLine(sayı3);

örnek sonuç




C# Bir Dik Üçgenin Hipotenüsünü Hesaplamak

Bir örnek uygulama yazalım ve bir dik üçgenin hipotenüs uzunluğunu hesaplayalım. Geometri dersinden hatırlarsak bir dik üçgende birbirine dik olan kenarların uzunluklarının karelerinin toplamı üçüncü kenarın yani hipotenüsün uzunluğunun karesine eşittir. a² + b² = c² şeklinde bir formül vardı. 

Önce a ve b uzunluklarını kullanıcının girmesini isteyeceğiz,

        static void Main(string[] args)
        {
            Console.WriteLine("A kenarı uzunluğunu giriniz:");
            double a = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("B kenarı uzunluğunu giriniz:");
            double b = Convert.ToDouble(Console.ReadLine());

            Console.ReadKey();
        }

Sorumuzu soruyoruz, kullanıcının konsoldan girmiş olduğu değer String olduğu için double veri tipine dönüştürüyoruz. Şimdi hipotenüs uzunluğunu hesaplayalım ve konsola yazdıralım. 

            double c = Math.Sqrt((a * a) + (b * b));

            Console.WriteLine("Hipotenüs uzunluğu : " + c);

a² ve  değerlerini ayrı ayrı hesaplamadık hepsini parametre değeri girerken yaptık. Program bir matematik işlem yaparken bir parantez açılırsa önce o açılan parantezin içindeki işlem yapılır, sonra yapılan işlemin sonucu tek bir değer olarak parantez dışına verilir. Yukarıdaki örnekte de önce a ve a çarpılacak yani karesi alınacak , sonra b ve b çarpılacak sonuçlar toplanıp Math.Sqrt() metoduna parametre değeri olarak verilecek. 

Çalıştırıp deneyelim,

3'ün karesi 9, 4'ün karesi 16, toplarsak 25, onun da karekökü 5 eder. 



C# String Metodları

Bu bölümde String veri türünün metodlarından çok kullanılan bazılarını göreceğiz. Bir String değişken tanımlayarak programa başlayalım.

        static void Main(string[] args)
        {
            String tamİsim = "Ümit Kayacık";

            Console.ReadKey();
        }

Bir satır aşağıya geçip tamİsim yazıp noktaya bastığımız anda bu String değişkene uygulanabilecek metodların bir listesini Visual Studio programı bize yardım amaçlı gösterecektir. 

Gördüğümüz gibi kullanılabilecek birçok metod var. Örneklere büyük harfe çevirme metodu ile başlayalım.

            tamİsim = tamİsim.ToUpper();
            Console.WriteLine(tamİsim);

ve çalıştıralım

ToUpper() metodu string içindeki tüm harfleri büyük harfe çevirecektir. Bilgisayar yapılanması Türkçe olmayanlarda özellikle Türkçe karakterlerin çevrilmesinde sorun yaşanabilir. 

Şimdi de küçük harfe çevirelim.

            tamİsim = tamİsim.ToLower();
            Console.WriteLine(tamİsim);

sonuç

ToLower() metodu da string içindeki tüm harfleri küçük harfe çevirir. Bir string içindeki belli karakterleri başka biriyle değiştirmek istersek. Mesela bir telefon numarası olsun ve içinde tire işaretleri olsun.

            String tamİsim = "Ümit Kayacık";
            String telNo = "123-456-789";

Tire işaretlerini bölü işareti ile değiştirmek için

            telNo = telNo.Replace("-", "/");

            Console.WriteLine(telNo);

Replace() metodu 2 parametre alır ilki string içinde değiştirmek istediğimiz string ikincisi ne ile değiştirmek istiyoruz. Çalıştıralım ve görelim,

Parametrelerde verdiğimiz değerler tek karakter olması gerekmez. Dikkat edersek parametreler çift tırnak içinde veriliyor, yani parametreler string türü ve birden fazla karakterden oluşabilir. Mesela

            telNo = telNo.Replace("-4", "/a");

            Console.WriteLine(telNo);

bize şu sonucu verir

Değiştirilecek stringlerin uzunlukları da aynı olmak zorunda değildir. Mesela 

            telNo = telNo.Replace("-", "/ab");

olabilir. Değiştirilecek string olarak boş string verirsek de string içinden tireleri yok edebiliriz.

            telNo = telNo.Replace("-", "");

String içine istediğimiz yere ilave bir string ekleyebiliriz. Mesela isim başına @ işareti koyarak userName isimli bir değişken değeri oluşturalım. 

            String userName = tamİsim.Insert(0, "@");

            Console.WriteLine(userName);

ve sonuç

Insert() metodu 2 parametre alıyor. İlki soldan itibaren kaçıncı karakterin oraya ekleme yapacağımızı belirten index değeri. Programlama dillerinde genelde index değerleri sıfırdan başlar. Biz de en sol başa ilave yapmak istediğimiz için index değerini 0 giriyoruz. İkinci parametre de o noktaya eklemek istediğimiz string değeri. Tekrar belirtelim string bir değer olduğu için çift tırnak içinde yazılır ve birden fazla karakterden oluşabilir. 

Sırada aslında bir metod değil bir özellik (property) olan Length özelliği var. Bu özellik bize string'in kaç karakter uzunluğunda olduğunu verir. 

            Console.WriteLine(tamİsim.Length);

sonuç

Dikkat edersek tamİsim.Length yazdık sonuna () eklemedik. Çünkü bu bir metod değil bir özellik (property). Özellikler bağlı oldukları nesneye özel bir değer verir ya da alırlar yani bir nevi değişkendirler, metodlar ise bir iş yapan kod parçacıklarıdır. Hepsini ilerledikçe ayrıntılı göreceğiz. 

Length (uzunluk) özelliği string işlenirken çok kullanılır, mesela maksimum kullanıcı adını 8 karakter ile sınırlamak istersek bu özellikten yararlanarak kontrol yapabiliriz. 

Sıradaki metod biraz daha karışık. Diyelim tamİsim değişkeni içinden isim ve soyisim değerlerini alacağız. Bunun için tamİsim değerinin alt string'lerini çekip almalıyız. 

            String isim = tamİsim.Substring(0, 4);
            String soyİsim = tamİsim.Substring(5, 7);

            Console.WriteLine("Adınız : " + isim);
            Console.WriteLine("Soyadınız : " + soyİsim);

sonuç

Substring() metodu string değerin alt string'ini almak için kullanılır. 2 parametre alır, ilki kaçıncı karakterden başlanacağı index değeri ve ikincisi kaç karakter alınacağı. index değeri tabii ki soldan itibaren sıfırdan başlayacak. Eğer başlanan yerden string'in sonuna kadar tüm karakterler alınacaksa ikinci parametre girilmeyebilir. Yani

            String soyİsim = tamİsim.Substring(5);

satırı da doğru çalışacaktır. Şimdilik string metodları üzerinde bu kadar çalışma yeterli, sonraki konuya geçelim.



C# if Karşılaştırma Komutu

Geldik her programlama dilinin en önemli karşılaştırma komutuna. if (eğer) karşılaştırma komutu yardımı ile kodumuz içinde birçok karşılaştırmalar yapar ve sonuca göre işlemler yaparız. Eğer karşılaştırmamızın sonucu doğru ise bir blok kodu çalıştırabiliriz ya da doğru değilse başka bir blok kodu çalıştırabiliriz. Sadece bu komut ile bazen tüm program kontrollerini yapmak mümkün olabilir, bu yüzden dikkatli incelemenizi tavsiye ederim. 

Örnek olarak kullanıcıya yaşını soralım ve 18 yaşından küçük ya da büyük olmasına göre işlem yapalım.

        static void Main(string[] args)
        {
            Console.WriteLine("Lütfen yaşınızı giriniz :");
            int yaş = Convert.ToInt32(Console.ReadLine());

            if(yaş >= 18)
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }

            Console.ReadKey();
        }

if komutu yanına parantez içinde karşılaştırma kodu yazılır. Burada (yaş >= 18) yazılmış yani yaş değeri 18 değerinden büyük veya eşitse parantez içindeki karşılaştırma sonucu true olacaktır. Parantez içinde her türlü işlem yapılabilir ancak bir şartla, işlemlerin sonunda ortaya çıkacak olan değer true ya da false olacak. Karşılaştırma işlemi sonucu true olursa arkasından gelen süslü parantezler içindeki kod bloğu çalıştırılır, false olursa kod bloğu çalıştırılmaz. Süslü parantezler içinde istediğimiz kadar kod yazabiliriz. Bu şekilde süslü parantezler içinde kod bloğu belirtmek C# programlarında bir çok yerde kullanılır. Mesela içine kodlarımızı yazdığımız Main() metodu da tanımlanırken yazdığımız kodlar süslü parantez içinde. class Program süslü parantez içinde , namespace CSharpTemelleri süslü parantez içinde gibi. Visual Studio editörümüz de bu blokların belli olması için otomatik olarak içiçe bloklarda tab ekleyerek görsel bir girinti yapıyor, bize kolaylık olsun diye. Genel olarak programcılıkta içiçe kod blokları editör otomatik yapmasa bile programcı tarafından böyle girdilenir ki bölümler belli olsun.

Programı çalıştırıp soruya 18 ya da daha büyük bir değer girerek cevap verirsek sisteme kayıt edildiğimizi belirten mesaj konsola yazılacaktır. 18'den küçük bir değer girersek bu kod bloğu çalışmadığı için hiç bir şey yazmayacaktır.

Eğer değer olarak 18'den küçük girildiğinde de bir mesaj vermek istersek, hemen if bloğunun bittiği yere bir else bloğu ekleriz. 

            if(yaş >= 18)
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }
            else
            {
                Console.WriteLine("Üzgünüm 18 veya daha büyük");
                Console.WriteLine("yaşta olmanız gerekir.");
            }

Şimdi 18'den küçük değer girersek aşağıdaki else bloğu içindeki mesajlar konsola yazılacaktır. if bloğu ve else bloğu arasında başka komutlar olamaz, hemen if bloğunun bittiği yerde olmalıdır. Yapısı gereği else bloğu tek başına bir anlam ifade etmez, öncesinde bir if karşılaştırması yapılmış olmalıdır. Karşılaştırma sonucu doğru ise if bloğu değilse else bloğu içindeki kod çalıştırılır. 

if ve else blokları arasında if karşılaştırması geçersiz çıkması durumunda yeni karşılaşltırmalar da ekleyebiliriz. Bu amaçla else if bloğu kullanılır. Diyelim kullanıcı sıfırdan küçük bir değer girince bambaşka bir mesaj vermek istiyoruz. 

            if(yaş >= 18)
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }
            else if(yaş <= 0)
            {
                Console.WriteLine("Siz daha doğmamışsınız.");
            }
            else
            {
                Console.WriteLine("Üzgünüm 18 veya daha büyük");
                Console.WriteLine("yaşta olmanız gerekir.");
            }

Çalıştırıp 0 ya da daha küçük bir değer girersek 

Dikkat edersek if karşılaştırması doğru değildi ama en sondaki else bloğu işlenmedi. Sebebi aradaki else if karşılaştırması sonucunun doğru çıkması. Örnekteki 3 blok bir bütün oluşturuyor. Yukarıdan başlanır hangi blok işlenirse diğerlerine bakılmadan en sona atlanır. 

else if bloklarını arada ihtiyacımız olduğu kadar ekleyebiliriz. Tek dikkat etmemiz gereken karşılaştırmaların yapılacağı sıra olmalıdır. Mesela çok yaşlı birini de sisteme kayıt etmek istemeyebiliriz. 

            if(yaş >= 18)
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }
            else if (yaş > 100)
            {
                Console.WriteLine("Kayıt olmak için çok yaşlısınız.");
            }
            else if (yaş <= 0)
            {
                Console.WriteLine("Siz daha doğmamışsınız.");
            }
            else
            {
                Console.WriteLine("Üzgünüm 18 veya daha büyük");
                Console.WriteLine("yaşta olmanız gerekir.");
            }

Çalıştırıp 100'den büyük bir değer girersek beklediğimiz gibi çalışmadığını görürüz. 

Dediğimiz gibi yukarıdan başlıyor karşılaştırmaları yapmaya ve if(yaş >= 18) karşılaştırması true çıkış verdiği için onun kod bloğu çalışıyor. Daha sonra tamamı bir bütün olarak değerlendirildiği için diğer karşılaştırmalara bakmıyor bile ve en sona atlıyor. Yani else if (yaş > 100) karşılaştırması hiç yapılmıyor. 

Bu yanlışı düzeltmek için kaydı kabul etmeyecek olan karşılaştırmayı önceye yazmamız gerekir.

            if (yaş > 100)
            {
                Console.WriteLine("Kayıt olmak için çok yaşlısınız.");
            }
            else if (yaş >= 18)
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }
            else if (yaş <= 0)
...

şimdi doğru çalışır.

Böyle dizi karşılaştırmalarda bazen bir çok olumsuz olasılık var ve bir tek olumlu olasılık varsa tersten yapmak daha kolay olur. Yani önce olumsuzları ayıklarsınız sonra geriye olumlu kalır. Biz gençkene buna olmayana yergi metodu derdik. Örneğimizi şu şekil de düşünebiliriz. 

            if (yaş > 100)
            {
                Console.WriteLine("Kayıt olmak için çok yaşlısınız.");
            }
            else if (yaş <= 0)
            {
                Console.WriteLine("Siz daha doğmamışsınız.");
            }
            else if (yaş < 18)
            {
                Console.WriteLine("Üzgünüm 18 veya daha büyük");
                Console.WriteLine("yaşta olmanız gerekir.");
            }
            else
            {
                Console.WriteLine("Sisteme kayıt edildiniz.");
            }

Ama burada unutup dışarıda bıraktığınız bir olasılık otomatik olarak sisteme kayıt edilme sonucuna varır. İhtiyacınız nasıl uygunsa o seçimi kullanırsınız. Burada amacım kafa karıştırmak değil, bu yapının çalışmasını tam kavramanızı sağlamak. Yılların tecrübesiyle bile şu en temel yapıda hala hatalar yaptığım oluyor. 

Başka bir örnek olarak kullanıcıya adını sorduğumuzu ve hiç bir şey girmeden enter tuşuna bastığını kontrol edelim.

            Console.WriteLine("Lütfen adınızı giriniz :");
            String isim = Console.ReadLine();

            if (isim == "")
            {
                Console.WriteLine("Bir isim girmediniz.");
            }
            else
            {
                Console.WriteLine("Merhaba " + isim);
            }

Çift tırnak içinde hiçbir karakter girmeyerek yazılan değer boş bir string değerdir. Hiç bir şey yazmadan direk enter basarsanız konsoldan bu boş string değeri okunur. Dikkat etmemiz gereken en önemli nokta karşılaştırma yaparken kullandığımız == (çift eşit) işlemi. Bildiğimiz matematik işlemler olarak düşünürsek kafamıza neden çift eşittir işareti var gibi sorular takılır. 

Bilmemiz gereken şudur. Eşittir işareti C# yazılımda neden kullanılır. Daha önce de gördük Eşittir işareti aslında bit atama komutudur. Eşittir işaretinin sağ tarafındaki işlemin sonucunda bulunan değer sol tarafındaki değişkene konur (atanır). Çift eşit ise bir karşılaştırma komutudur ve iki tarafındaki değer birbirine eşitse true, eşit değilse false sonucu çıkar. (isim = "") yazılsaydı sonucunda isim değişkenine boş bir string konacaktı ve bu değer de boolean bir değer olmadığı için (string olduğu için) program hata verecekti. Kodumuza 

            Console.WriteLine(isim = "");
            Console.WriteLine(isim == "");

yazalım ve görelim. İlk satır isim değerini boş string yapacak ve konsola da boş bir satır yazacaktır. İkinci satır ise değer boş string olduğu için konsola true değeri yazacaktır.

Yukarıdaki karşılaştırmanın tersi olarak eşitliği değil eşitsizliği de sorgulayabiliriz. 

            if (isim != "")
            {
                Console.WriteLine("Merhaba " + isim);
            }
            else
            {
                Console.WriteLine("Bir isim girmediniz.");
            }

(isim != "") karşılaştırması ile isim değerinin boş olmaması kontrol ediliyor. Eğer isim değeri boş string değilse karşılaştırma true sonuç verir. Yani == karşılaştırması eşit mi diye kontrol ederken != karşılaştırması eşit değil mi diye karşılaştırır. 



C# switch Karşılaştırma Komutu

6 Şubat 2023 Pazartesi, kalktım bugün yazmaya devam edecektim ancak Kahraman Maraş ve çevresinde gerçekleşen büyük depremin haberi ile güne başladık. 17 Ağustos 1999 depremini Bursa'da komşu il olarak yaşadım. Adapazarı'nda akrabalarım vardı ve o gün Adapazarı'na gittim, 2 gün sokaklarda yattık. İnanın çok zor, hem de bu kış şartlarında daha zor. Allah herkesin yardımcısı olsun. Umarım bu sefer yardımlarımızı daha organize ve çabuk ulaştırabiliriz. 

Yazımıza kaldığımız yerden devam edelim. switch karşılaştırma komutu bir çok else if bloğu yerine kullanılabilecek alternatif bir yapı. Örnek olarak kullanıcıdan haftanın gününü sorsak ve girilen gün değerine göre değişik mesajlar vermek istesek, bunu bir sürü if ve else if blokları ile yazabiliriz.

        static void Main(string[] args)
        {
            Console.WriteLine("Bugün haftanın hangi günü?");
            String gün = Console.ReadLine();

            if (gün == "Pazartesi")
            {
                Console.WriteLine("Pazartesi haftanın ilk günü");
            }
            else if (gün == "Salı")
            {
                Console.WriteLine("Salı markete gidilir");
            }
            ...
            else if (gün == "Pazar")
            {
                Console.WriteLine("Pazar kahvaltısı");
            }
            else
            {
                Console.WriteLine("Sanırım bir gün adı girmediniz");
            }

            Console.ReadKey();
        }

Uzun bir kod oldu şimdi aynı işi switch komutu ile nasıl yapacağımızı görelim.

            String gün = Console.ReadLine();

            switch (gün)
            {
                case "Pazartesi":
                    Console.WriteLine("Pazartesi haftanın ilk günü");
                    break;
                case "Salı":
                    Console.WriteLine("Salı markete gidilir");
                    break;
                case "Çarşamba":
                    Console.WriteLine("Çarşamba hafta ortası");
                    break;
                case "Perşembe":
                    Console.WriteLine("Perşembe maç var");
                    break;
                case "Cuma":
                    Console.WriteLine("Cuma mübarek gün");
                    break;
                case "Cumartesi":
                    Console.WriteLine("Cumartesi buluşması");
                    break;
                case "Pazar":
                    Console.WriteLine("Pazar kahvaltısı");
                    break;
                default:
                    Console.WriteLine("Sanırım bir gün adı girmediniz");
                    break;
            }

Bazen bu yapıya switch yapısı yerine switch-case yapısı da denir. Burada switch komutu ile birlikte tek bir blok kod yazıyoruz. Komuta parametre olarak gün değişken değerini veriyoruz. Aşağıda case satırlarında ise gün değişkeninin olası değerleri sıralanıyor. case ile başlayıp yanına karşılaştırılacak değeri koyup arkasına iki nokta üstüste koymak bir kod bloğu başlatır. Başlatılan bu blok break komutu ile biter. Her case bloğunun sonunda break komutu olmalıdır. Nasıl if bloğunun sonunu süslü parantezin kapanmasından anlıyorsa, C# derleyici case bloğunun sonunu da break komutundan anlar. 

Olası değerler ve bu değerlere karşı yapılacak işlemlerin olduğu alt kod blokları bittikten sonra en sona sadece default yazarak bir kod bloğu başlatılır. default bloğu yukarıdaki hiç bir değerin olmaması durumunda çalışır. default olmasa da program çalışır, sadece case'lerden hiç biri gerçekleşmezse hiç bir şey yapmadan geçer. default bloğu altına case yazarsanır o da çalışır ama kod olarak çirkin durur yapmayın. Mesela

                case "Pazar":
                    Console.WriteLine("Pazar kahvaltısı");
                    break;
                default:
                    Console.WriteLine("Sanırım bir gün adı girmediniz");
                    break;
                case "sd":
                    Console.WriteLine("bingo");
                    break;

En altta default kalsın ki nerede arayacağımızı bilelim. Bu break komutu da başka yerlerde de karşımıza çıkabilir. break bazen içinde bulunulan bloktan o satırda çıkmak için de kullanılır.



C# Mantıksal Operatörler (İşleyiciler)

Mantıksal operatörler birden fazla karşılaştırmanın birlikte yapılması gerektiğinde kullanılır. Örnek olarak dışarısının sıcaklığına göre yorum yapacağımız bir program olsun. Sıcaklık için belirlediğimiz aralıklara göre mesajlar vermek istiyoruz. 

        static void Main(string[] args)
        {
            Console.WriteLine("Dışarıda sıcaklık kaç derece?");
            double sıcaklık = Convert.ToDouble(Console.ReadLine());

            if(sıcaklık >= 10 && sıcaklık <= 25)
            {
                Console.WriteLine("Dışarıda hava güzelmiş");
            }

            Console.ReadKey();
        }

Önce kullanıcının sıcaklık değerini girmesini istiyoruz, sonra girilen değeri double değere dönüştürüyoruz. if koşuluna gelince bir değil 2 koşulun aynı anda doğru olmasını bekliyoruz. Yani hem sıcaklık >= 10 karşılaştırması true çıkış verecek hem de sıcaklık <= 25 karşılaştırması true çıkış verecek. Yani sıcaklık değeri 10 dereceye eşit ya da büyük olacak ve 25 dereceye eşit ya da küçük olacak. Böyle her iki koşulun da gerçekleşmesi için koşulları birbirine && (ve) işlemi ile bağlıyoruz. && işleminin doğruluk tablosu şöyle:

  • true && true => true
  • false && true => false
  • true && false => false
  • false && false => false

Gördüğümüz gibi sadece her iki tarafı da true değerine sahipken sonuç true oluyor. İşlemler yapılırken önce karşılaştırmalar yapıldığı için burada ayrıca belirtilmemiş ama ben bu tip çoklu karşılaştırmalarda çoğunlukla işlemleri parantez içinde göstermekten yanayım .Yani

            if ((sıcaklık >= 10) && (sıcaklık <= 25))

şeklinde yazılması yapılan işlemi anlamada daha etkili olacaktır. Şimdi de extrem sıcaklıklar için bir mesaj yazalım.

            if ((sıcaklık >= 10) && (sıcaklık <= 25))
            {
                Console.WriteLine("Dışarıda hava güzelmiş");
            }
            else if ((sıcaklık < -50) || (sıcaklık > 50))
            {
                Console.WriteLine("SAKIN DIŞARI ÇIKMAYIN!");
            }

İki karşılaştırmanın sadece birinin doğru olması durumunda bloğumuz işlensin istiyorsak karşılaştırmaları birbirine || (veya) mantıksal işlemi ile bağlarız. Bu karakter Türkçe klavyede AltGr tuşu ile birlikte sol alttaki büyük-küçük tuşuna bastığımızda yazılan karakterdir. || işleminin doğruluk tablosu şöyle:

  • false || false => false
  • true || false => true
  • false || true => true
  • true || true => true

Gördüğümüz gibi iki taraftan sadece biri true değerde ise sonuç true olacaktır. Burada da aslında iç parantezlere gerek yoktu ancak işlemler daha açık görünsün diye öyle yazdım. sıcaklık değeri -50 dereceden düşükse veya +50 dereceden büyükse SAKIN DIŞARI ÇIKMAYIN şeklinde mesaj veriyor.




C# while Döngüsü (loop)

Programcılıkta yeni bir adıma geçiyoruz, döngüler (loops). Döngüler belli koşullara bağlı olarak aynı kod bloğunu defalarca tekrarlamak için kullanılır. İlk göreceğimiz while döngüsü, belirtilen karşılaştırma true sonuç verdiği sürece altında verilen kod bloğu içindeki kodu tekrar tekrar çalıştırır. Karşılaştırma false değeri verince döngü biter ve kod bloğu işlenmeden hemen sonrasına program atlar. 

Diyelim kullanıcıya ismini soracağız ve isim yazmadan enter basarsa tekrar soracağız. Bu durumda while döngüsü ile bir değer girilene kadar sorumuzu tekrar tekrar sorabiliriz. 

        static void Main(string[] args)
        {
            Console.Write("İsminizi girer misiniz : ");
            String isim = Console.ReadLine();

            while (isim == "")
            {
                Console.Write("İsminizi girer misiniz : ");
                isim = Console.ReadLine();
            }

            Console.WriteLine("Merhaba " + isim);

            Console.ReadKey();
        }

Eğer kullanıcı değer girmeden enter basarsa isim değişkeni değeri boş string olacaktır bu durumda while döngüsü karşılaştırması true sonuç verecek ve döngü bloğu içindeki kod çalışacaktır. Kod bloğunda soruyu tekrar soruyor ve cevabı tekrar alıyor. Blok bitince bu bir while döngüsü bloğu olduğu için başa geri döner ve karşılaştırmayı yine yapar. Eğer karşılaştırma sonucu false çıkarsa kod bloğu işlenmeden bir sonraki satıra geçer ve Merhaba .. mesajı verilir. Örnek olarak 2 defa boş girilmiş ve sonra isim girilmiş bir çıktı:

Bu kod çalışıyor ama tekrarlanan satırlar var. Programcılığın en önemli ilkelerinden biri aynı kodları tekrar tekrar yazmamaktır. Küçük bir değişiklik ile daha sade bir kod oluşturabiliriz. 

        static void Main(string[] args)
        {
            String isim = "";

            while (isim == "")
            {
                Console.Write("İsminizi girer misiniz : ");
                isim = Console.ReadLine();
            }

            Console.WriteLine("Merhaba " + isim);

            Console.ReadKey();
        }

Önce isim değişkenine while döngüsü içine girecek bir değer veriyoruz, sonra sorumuzu sadece döngü içinde soruyoruz. Kodumuzun daha berrak olması için çok kullandığımız bir tekniktir bu. 

while karşılaştırması sonucu her zaman true oluyorsa döngü asla bitmez, kod döner durur. Buna sonsuz döngü denir. Bazen gerekir mesela. 

            while (1 == 1)
            {
                Console.WriteLine("Yardım edin sonsuz döngüde kaldım!");
            }

Karşılaştırma hep true sonuç verdiği için mesajı sürekli ekrana yazacaktır. Programı durdurmak için Ctrl+C tuşlarına basabilirsiniz. 

            while (true)

Şeklinde yazarsak da sonuçta sonsuz döngü elde ederiz. Daha önce break ile kod bloklarından çıkabileceğimizi belirtmiştik. Sonsuz döngüden kod yoluyla çıkmak için kullanabiliriz. 

            int sayaç = 0;

            while (true)
            {
                Console.WriteLine("Yardım edin sonsuz döngüde kaldım!");
                sayaç++;
                if (sayaç >= 10)
                    break;
            }

Bu kod sayaç değişkeni değeri 10 veya daha büyükse break komutunu çalıştırıyor. break komutu da içinde bulunulan döngüyü kırıp dışına çıkıyor. Kodda başka bir dikkat çeken nokta if bloğunu belirtmek için süslü parantez açıp kapatmadık. if bloğu içinde sadece tek bir komut işlenecekse süslü parantez açıp kapatmaya gerek yoktur, ama sadece bir tek komut işlenecekse. Ama siz daha açık görünsün diye süslü parantezleri yine de koyabilirsiniz. 



C# for Döngüleri

for döngüleri bir kod bloğunu belirli sayıda tekrarlama amacıyla kullanılır. Mesela 10'a kadar sayan bir program yazalım. for döngüleri while'den farklı olarak parametresinde 3 adet işlem yapılmasını bekler. 

        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
            }

            Console.ReadKey();
        }

Dikkat edersek işlemler parametreler gibi virgül ile ayrılmıyor. Her biri bir komut satırı oluşturduğu için noktalı virgül ile ayrılıyor. Bu işlemlerin ilki olan int i = 0 işlemi döngüye ilk girerken sadece bir kez çalıştırılır. Burada döngü içinde kullanılacak olan sayaç tanımlanır ve ilk değeri verilir. Sayaç değeri olarak burada i değişkeni belirlenmiş. Genelde index kelimesinin kısaltılmışı olarak i harfinin değişken adı olarak kullanılması gelenek olmuştur. Bu birinci işlem sadece en başta bir kez çalışır , bir daha döngü yaptıkça çalıştırılmaz. Değişken tanımlamasını for döngü parametreleri içinde vermek zorunlu değildir, daha önce tanımlanmış bir değişken de kullanılabilir. 

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

gibi. 

İkinci işlem bir karşılaştırma işlemi ve aynı while döngüsünde olduğu gibi bu işlemin sonucu true olduğu müddetçe kod bloğu işletilecektir. Örneği düşünürsek en başta i değişkeni değeri sıfır olduğu için ve i < 10 karşılaştırması true sonuç vereceği için başlangıçta blok işlenecektir. i değişkeni değeri 10'dan küçük olduğu müddetçe de kod bloğu başa geri döndüğünde tekrar çalışacaktır. Mesela karşılaştırma i > 10 olsaydı bir kere bile kod bloğu işletilmeden program blok sonrası satıra atlayacaktı. 

Üçüncü işlem ise kod bloğu çalıştırılıp en son bloğun süslü parantez kapatmasına geldiğinde yapılan işlemdir. Yani örneğe bakarsak konsola i değeri yazıldıktan sonra blok sona eriyor. O esnada i değeri 1 arttırılıyor. Sonra program yine for döngüsü başına dönüyor ve karşılaştırma işlemi tekrar yapılıyor. Sonuç true olursa kod bloğu tekrar çalıştırılıyor. i değeri 10 olunca karşılaştırma işlemi false sonuç verir ve kod bloğu çalıştırılmadan sonrasına atlanır. Programın çıktısı şöyle olacaktır.

Gördüğümüz gibi değer sıfır iken kod bloğu çalışıyor , her seferinde değer 1 artıyor. Değer 10 olunca kod bloğu çalıştırılmıyor ve program bitiyor. 1'den 10'a kadar yazan bir kod şöyle olacaktır.

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

Değeri ikişer olarak da arttırabiliriz. Bu bize tek sayıları verir.

            for (int i = 1; i <= 10; i += 2)
            {
                Console.WriteLine(i);
            }

ve sonuç

Bir örnek olarak 10'dan geri sayalım ve bitişinde mutlu yıllar mesajı verelim.

            for (int i = 10; i > 0; i--)
            {
                Console.WriteLine(i);
            }

            Console.WriteLine("*** MUTLU YILLAR! ***");

ve sonuç

Sayacımızın ilk değeri 10 olarak veriliyor. i değeri sıfırdan büyük olduğu müddetçe kod bloğu işletilecek ve her döngü sonunda i değeri 1 azaltılacak. 



C# İç İçe Döngüler

Bazen döngüleri içiçe kullanmak gerekebilir. Örnek olarak konsola bir karakteri tekrar tekrar, yan yana ve alt alta yazarak bir dikdörtgen şekli yapmak istiyoruz diyelim. Önce genişliği kaç karakter olacaksa bir döngü içerisinde yan yana o kadar karakteri basarız. Sonra alt satıra geçip bir önceki satır yazma döngüsünü tekrar ederiz. Bunu da yine bir döngü içinde yüksekliğimiz kadar satır olarak tekrar ederiz. 

        static void Main(string[] args)
        {
            Console.Write("Kaç satırınız olacak : ");
            int satırlar = Convert.ToInt32(Console.ReadLine());

            Console.Write("Kaç sütununuz olacak : ");
            int sütunlar = Convert.ToInt32(Console.ReadLine());

            for (int satırNo = 0; satırNo < satırlar; satırNo++)
            {
                for (int sütunNo = 0; sütunNo < sütunlar; sütunNo++)
                {
                    Console.Write("@");
                }
                Console.WriteLine();
            }

            Console.ReadKey();
        }

ve sonuç




C# Sayı Tahmin Oyunu (Konsol Uygulaması)

Öğrendiklerimizi kullanan basit uygulamalar yapmak bilgilerimizi pekiştirmek için çok faydalıdır. Bir programlama dili öğrenmeye başladığımda en çok denediğim uygulamalardan birini yapalım. 1-100 arasında bir rastgele sayı tutsun bilgisayarımız ve biz o sayıyı bulmaya çalışalım. Önce gereken değişkenlerin tanımlaması ile başlayalım.

        static void Main(string[] args)
        {
            Random random = new Random();
            bool tekrarOyna = true;
            int min = 1;
            int max = 100;
            int tahmin;
            int sayı;
            int tahminler;

            Console.ReadKey();
        }

Önce rastgele sayı üretmek için Random tipi bir nesne üretiyoruz. Adını random koydum, rastgele de koyabilirdim ama Türkçesi daha açıklayıcı olmadıktan sonra böyle özel sınıflardan üretilen nesnelere sınıf adının küçük harfle başlayanını vermek hatırlama bakımından daha faydalıdır. Aynı zamanda C# programlarında bir gelenek olarak isimlendirme böyle yapılır. Oyun sonunda kullanıcıya tekrar oynamak isteyip istemediğini soracağız. Bu amaçla kullanmak üzere tekrarOyna adında boolean bir değişken tanımlıyoruz ve ilk değerini true olarak giriyoruz. Neden böyle veriyoruz, çünkü tüm oyun kodunu bir while döngüsü içine koyacağız ve karşılaştırmada bu değişkeni kullanacağız. İlk değerini true vererek en başta döngünün içine girilmesini sağlayacağız. min ve max değişkenlerini tahmin etmişsinizdir, 1 ve 100 arasında bir sayı tahmin edilecek. En son 3 değişkeni sadece tanımlıyor ama ilk değerlerini vermiyoruz. tahmin değişkeni kullanıcının tahmini olarak girdiği sayıyı saklayacak. sayı değişkeni bilgisayarın ürettiği rastgele sayıyı saklıyor. tahminler değişkeni de kullanıcının kaç tane tahmin yapmış olduğunu saklayacak. 

Oyun tekrarına bakan ana döngü ile başlayalım.

...
            int tahminler;

            while (tekrarOyna)
            {
                tahmin = 0;
                tahminler = 0;
                sayı = random.Next(min, max + 1);
            }

tekrarOyna değeri true olduğu müddetçe oyunumuz yeniden başlayacağı için, her başlangıçta tahmin ve tahminler değerlerini sıfır yapıyoruz. sayı içinse yeni bir rastgele sayı üretiyoruz. 

Sırada tahmin edilen sayı tutulan sayıya eşit olana kadar devam edecek olan döngü var. Bu döngü içinde kullanıcıya tahminini soracağız, tahminler değerini 1 arttıracağız. 

            while (tekrarOyna)
            {
                tahmin = 0;
                tahminler = 0;
                sayı = random.Next(min, max + 1);

                while (tahmin != sayı)
                {
                    Console.WriteLine(min + "-" + max + " arası bir sayı giriniz :");
                    tahmin = Convert.ToInt32(Console.ReadLine());
                    Console.WriteLine("Tahmininiz : " + tahmin);
                }
            }

Kullanıcının tahminini aldıktan sonra girilen değerin tutulan sayıdan büyük ya da küçük olduğunu belirterek kullanıcıya yardımcı olalım. 

                while (tahmin != sayı)
                {
                    Console.WriteLine(min + "-" + max + " arası bir sayı giriniz :");
                    tahmin = Convert.ToInt32(Console.ReadLine());
                    Console.WriteLine("Tahmininiz : " + tahmin);

                    if (tahmin > sayı)
                    {
                        Console.WriteLine(tahmin + " değeriniz çok geldi.");
                    }else if (tahmin < sayı)
                    {
                        Console.WriteLine(tahmin + " değeriniz az geldi.");
                    }
                }

Tahmin edilen sayı tutulan sayıdan büyükse çok olduğunu , küçükse az olduğunu belirttik. Eşit olması durumunda döngüden çıkılacak. Döngü bloğunu bitirmeden önce son bir şey yapmalıyız. tahminler sayısını 1 arttırarak kullanıcının kaç tahminde sayıyı bulduğunu takibe alalım. 

                    }else if (tahmin < sayı)
                    {
                        Console.WriteLine(tahmin + " değeriniz az geldi.");
                    }
                    tahminler++;
                }

Döngüden çıkıldığında doğru tahmin yapılmış demektir. Kullanıcıya bunu bildirelim. while (tahmin != sayı) bloğunun bittiği yere şu satırları ekleyelim. 

                    tahminler++;
                }
                Console.WriteLine("*******************************");
                Console.WriteLine("Tutulan sayı " + sayı + " idi");
                Console.WriteLine("TEBRİKLER DOĞRU!");
                Console.WriteLine(tahminler + " tahminde bildiniz.");

Şimdi de kullanıcıya tekrar oynamak isteyip istemediğini soralım. Kullanıcıya cevabı true ya da false yazacağı bir soru sormak yerine evet ya da hayır diye cevaplayacağı (kısacası e/h) şekilde soru sorabilmek için bir değişkene daha ihtiyacımız olur. En üstte onu da tanımlayalım.

...
            int tahminler;
            String cevap;

            while (tekrarOyna)
...

şimdi sorumuzu soralım

...
                Console.WriteLine(tahminler + " tahminde bildiniz.");

                Console.WriteLine();
                Console.WriteLine("Tekrar oynamak ister misiniz? (e/h):");
                cevap = Console.ReadLine().ToUpper();

                if (cevap != "E")
                {
                    tekrarOyna = false;
                }
            }

            Console.WriteLine("Oynadığınız için teşekkürler. Bye!");

            Console.ReadKey();

cevap = Console.ReadLine().ToUpper(); satırında iki metodu birbirine bağlayarak kullandık. Önce Console.ReadLine() metodu çalışır, sonucunda konsoldan girilen string değeri ToUpper() metodu ile büyük harfe çevrilir ve cevap değişkenine konur. Cevabın e ya da E olmaması durumunda oyunu bitiriyoruz. Bu işin kolay yolu, eğer hayır cevabı için de illaki h ya da H beklersek kullanıcı başka bir şey girince soruyu tekrar sormamız gerekir ki bu kodumuzu biraz karıştıracak anlatım kolaylığı olsun diye böyle yaptım. Çalıştıralım ve görelim.




C# Taş, Kağıt, Makas Oyunu (Konsol Uygulaması)

Denemelerle bilgilerimizi pekiştirmeye devam edelim. Taş-Kağıt-Makas oyunumuzda ilk ihtiyacımız bilgisayarın üçünden birini tutması. Bir değişken tanımlayıp 1 için taş, 2 için kağıt, 3 için makas olacağını düşünelim.

        static void Main(string[] args)
        {
            Random random = new Random();
            bool tekrarOyna = true;
            String oyuncu;
            String bilgisayar;

            Console.ReadKey();
        }

Başlangıçta yine gerekeceğini düşündüğümüz değişken tanımları ile girdik. Bir random nesnesi rastgele seçim için, tekrarOyna daha önce gördük, oyunu tekrar oynamak istemezsek false yapacağımız değişken, oyuncu değişkeni kullanıcının tahminini saklayacak, bilgisayar değişkeni bilgisayarın ürettiği rastgele değeri saklayacak. Kullanıcının tahminini alarak döngümüze başlayalım.

...
            String bilgisayar;

            while (tekrarOyna)
            {
                Console.WriteLine("TAŞ, KAĞIT ya da MAKAS seçiminizi yazın");
                oyuncu = Console.ReadLine().ToUpper();
            }

Yine metodları ard arda kullanarak girilen değeri büyük harf olarak sakladık. Kullanıcı  TAŞ KAĞIT ya da MAKAS değerlerinden birini yazmaz ise sorumuzu tekrar sormak için bu soruyu döngü içine alalım.

            while (tekrarOyna)
            {
                oyuncu = "";
                while (oyuncu != "TAŞ" && oyuncu != "KAĞIT" && oyuncu != "MAKAS")
                {
                    Console.WriteLine("TAŞ, KAĞIT ya da MAKAS seçiminizi yazın");
                    oyuncu = Console.ReadLine().ToUpper();
                }
            }

Oyun her yeni ya da yeniden başladığında oyuncu değişkenine boş string veriyoruz ki sorumuz en az bir kere sorulsun. Sırada bilgisayarın rastgele değer üretmesi var. Bilgisayar 1 ve 3 arası rastgele sayı üretecek biz onu bir switch bloğu ile string karşılığına çevireceğiz. 

                while (oyuncu != "TAŞ" && oyuncu != "KAĞIT" && oyuncu != "MAKAS")
                {
                    Console.WriteLine("TAŞ, KAĞIT ya da MAKAS seçiminizi yazın");
                    oyuncu = Console.ReadLine().ToUpper();
                }
                switch (random.Next(1, 4))
                {
                    case 1:
                        bilgisayar = "TAŞ";
                        break;
                    case 2:
                        bilgisayar = "KAĞIT";
                        break;
                    case 3:
                        bilgisayar = "MAKAS";
                        break;
                }

switch komutuna parametre olarak 1 ve 3 arasında rastgele sayı üreten random.Next(1, 4) komutunu yazıyoruz. İşlem sonucu üretilen sayı switch bloğunun parametresi olacak. case 3: yerine default da yazabilirdik. Nasıl olsa değer 1, 2 ya da 3 olabilir ancak. Şimdilik oyuncu ve bilgisayarın tuttukları değerleri konsola yazarak bir çalıştıralım ve şimdiye kadar yaptıklarımızı test edelim.

                }

                Console.WriteLine("Oyuncu : " + oyuncu);
                Console.WriteLine("Bilgisayar : " + bilgisayar);
            }

            Console.ReadKey();

Çalıştırmaya kalkınca hata verir. Değer verilmemiş bilgisayar değişkeni kullanılıyor şeklinde bir mesaj. Tabi derleyici bu switch bloğu içinde bu değişkene illa bir değer giriliyor diye muhakeme yürütecek kadar akıllı değil. Kural olarak, koşullu blokların içinde yapılan değer girişleri olmayabilir diye yok kabul edilir. Bu yüzden oyun başında ona da boş string değeri verelim.

            while (tekrarOyna)
            {
                oyuncu = "";
                bilgisayar = "";

Deneme artık başarılı

Sırada tercihleri karşılaştırıp kimin kazandığına karar vermek var.

                Console.WriteLine("Oyuncu : " + oyuncu);
                Console.WriteLine("Bilgisayar : " + bilgisayar);

                if (oyuncu == bilgisayar)
                {
                    Console.WriteLine("Berabere kaldınız");
                }else if ((oyuncu == "TAŞ" && bilgisayar == "KAĞIT") ||
                    (oyuncu == "KAĞIT" && bilgisayar == "MAKAS") ||
                    oyuncu ==   "MAKAS" && bilgisayar == "TAŞ")
                {
                    Console.WriteLine("Üzgünüm kaybettiniz!");
                }
                else
                {
                    Console.WriteLine("Tebrikler KAZANDINIZ!");
                }

İki değer eşitse berabere demektir. İkinci blokta bilgisayarın kazandığı tüm olasılıkları topladık ve oyuncuya kaybettiğini bildirdik. Son kalan olasılıklar ise oyuncunun kazandığı ihtimallerdir. Son olarak kullanıcıya tekrar oynamak isteyip istemediğini soralım.

...
                    Console.WriteLine("Tebrikler KAZANDINIZ!");
                }

                Console.Write("Tekrar oynamak ister misiniz? (e/h): ");
                if (Console.ReadLine().ToUpper() != "E")
                    tekrarOyna = false;

Kodu kısalttıkça kısalttık. Değişken tanımlamadan konsoldan okunan değeri direk if karşılaştırmasında kullandık, if bloğunda tek satır olduğu için süslü parantez kullanmadık, evet harici tüm cevapları hayır kabul ettik ve 3 satırda işi bitirdik. 

Örnek uygulamalara devam edeceğiz ama yazı çok uzadı ve sayfa yavaşlamaya başladı. Bu kadarını bir yayınlayalım sonra devam edeceğiz.

Görüşmek üzere kalın sağlıcakla..

Sonraki bölüm https://ujk-ujk.blogspot.com/2023/02/c-temelleri-3.html



Hiç yorum yok:

Yorum Gönder