Merhabalar, bir önceki makalemde akış kontrol mekanizmalarını tamamlamıştım. Bu makalemde dizileri anlatacağım. Ayrıca dizileri öğrenirken bolca döngü kullanacağız. Diziler aslında uzun ve derin bir konu. Diziler, çok boyutlu diziler, düzensiz diziler, dizilerle kullanılabilecek metotlar vs. Ne yazık ki hepsini detaylı bir biçimde anlatamayacağım; ancak program yazarken en çok kullanacağınız noktalara değinmeye çalışacağım. Hadi başlayalım…
DERS 6 : Diziler
Dizi nedir? En basit anlamıyla, aynı türden nesnelerin bir arada tutulduğu bir veri yapısıdır. Diyelim ki bir sınıfın not ortalaması ile alakalı bir program yazacaksınız. Sınıfta 20 öğrenci var. Her bir öğrencinin notunu bir yerde tutmanız lazım. Bu iş için 20 tane değişken mi tanımlarsınız? Notların tam sayı şeklinde olduğunu varsayarsak aşağıdaki gibi bir tanımlama yapmanız gerekir:
int ogrenci1 = 50;
int ogrenci2 = 60;
int ogrenci3 = 70;
int ogrenci4 = 80;
//bu şekilde 20 değişken tanımlamanız lazım
Sizin de gördüğünüz gibi bu işlem çok saçma olur. Bunun yerine her bir elemanı int tipinde olan bir dizi tanımlarız. Dizi tanımlamasını ve değer atamalarını şu şekillerde yapabiliriz:
//Birinci tanımlama şekli
int[] dizi;
dizi = new int[20];
//İkinci tanımlama şekli
int[] dizi2 = new int[20];
//Birinci ve ikinci tanımlama için değer ataması
dizi2[0] = 50;
dizi2[1] = 60;
//20 değeri de bu şekilde tanımlayabiliriz
//Üçüncü tanımlama şekli ve değer ataması
int[] dizi3 = new int[5] { 10, 20, 30, 40, 50 };
//Dördüncü tanımlama şekli ve değer ataması
int[] dizi4 = { 10, 20, 30, 40, 50 };
Birinci tanımlama şeklinde, önce değişkenimizi ve tipini belirtiyoruz, ardından lazım olduğu zaman boyutuyla beraber tanımlamasını yapıyoruz. Köşeli parantez içerisindeki 20 sayısı, dizinin eleman sayısını belirtir. Dizilerin en büyük dezavantajı da işte budur, yani eleman sayısının belirtilmesi gerekliliği. Örneğin öğrencilerin notlarını bir arayüz yardımıyla kullanıcıdan alacaksanız ve sınıfta kaç öğrenci olduğunu bilmiyorsanız dizileri kullanamayacaksınız. Onun yerine liste kullanmanız gerekecek. Listeleri ise ilerleyen derslerimizde anlatacağız. Şahsen ben diziyi çok nadir kullanırım, işlerimi genellikle listeler ile hallederim.
İkinci tanımlama şeklinin birinciden pek de bir farkı yok, iki satır yerine tek satırda tanımlayabiliyoruz.
Eğer dizimizi birinci veya ikinci yöntemle tanımladıysak, dizinin içerisini doldurmamız gerekecek. Diziye değer atamak içinse diziDegiskeni[index] şeklinde bir yapı kullanıyoruz. Burada dikkat edilmesi gereken nokta, index değerinin sıfırdan başlamasıdır. Yani dizinin ilk elemanına erişmek istersek veya değer atamak istersek dizi[0] yazmamız gerekecek. Dolayısıyla 20 elemanlı bir dizinin son elemanı dizi[19] olacaktır. Bu dersin en önemli noktası burasıdır. Peki 20 elemanlı bir dizide dizi[20] ifadesi kullanırsanız ne olur? Kod sorunsuz bir şekilde derlenir; ancak çalışma zamanında program o satıra gelecek ve dizinin, dizi[20] şeklinde bir elemanı olmadığı farkedilecek ve “Index was outside the bounds of the array.” şeklinde bir hata fırlatılacaktır. Bu hatayı gördüğünüzde bilin ki dizide olmayan bir elemana erişmeye çalışıyorsunuz.
Üçüncü tanımlama şekli benim en çok kullandığım. Tanımlamayı ve değer atamasını bir arada yapıyorsunuz. Dördüncü de yine benzer şekilde.
Diyelim ki değer atamalarımız tamam, işlemlerimiz bitti ve dizinin içeriğini ekrana yazdırmak istiyoruz. İşte bu noktada döngülere başvuruyoruz, çünkü aynı işlemi tekrar tekrar yapıyor olacağız ve bu iş için en ideal yöntem döngü kullanmak. Ben sadece for döngüsünü göstereceğim, eğer C# dilinde yeniyseniz, önceki derse bakmadan siz de kendi başınıza while ve foreach döngülerini yazın derim. For döngüsü kullanarak, dizi içeriğini ekrana şu şekilde basabiliriz:
for (int i = 0; i < dizi4.Length; i++)
{
Console.Write(dizi4[i] + " ");
}
Bu kadar basit. Burada yeni bir şey kullandık, belki farketmişsinizdir. Hatırlarsanız for döngüsünde bir başlangıç, bir bitiş, bir de artım değerimiz mevcuttu. Başlangıç değerimiz dizinin ilk elemanı olacağı için 0, artım değerimiz tüm elemanları yazacağımız için 1, geriye bitiş değerini yazmak kalıyor. İstersek hard coded olarak (yani kod içerisine direkt sayı yazarak) i < 5 şeklinde tanımlayabiliriz; ancak bu pek tavsiye edilmeyen bir yöntem. En güzeli dizi veri tipinin sağlamış olduğu özellik olan Length özelliğini (property’sini) kullanmak. diziAdi.Length yazdığınızda size dizinin boyutunu int tipinde verecektir. Döngülerdeki en uygun kullanım bu şekildedir. Write komutu içerisinde dizi4[i] kullandığımız için, her döngüde i değeri 1 artacak ve sırasıyla dizi4[0], dizi4[1]…, dizi4[19] değerlerini ekrana basacak. Yandaki + ” “ kafanızı karıştırmasın, değerlerin arasına boşluk eklemek için yazıldı.
Ben sadece int tipinin dizi olarak tanımlanmasını anlattım; ancak diğer veri tipleri de aynı şekilde tanımlanıyor. Örneğin string[], byte[], char[] vs. gibi. Az önceki örneklerde değerleri elle atadık. Peki ya sonucu dizi olan bir fonksiyon çağırsak durum nasıl olur? Aşağıya küçük bir program yazalım. Programın amacı şu olsun: kullanıcıdan bir tarih alalım, daha sonra bu string tipindeki tarihi gerçek bir tarih nesnesine dönüştürüp bir ay sonrasını ekrana basalım. Böylece tarih nesnesinden de kısaca bahsetmiş olalım.
using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.Write("Lütfen tarih giriniz (ör: 29.08.1990): ");
string kullaniciGirisi = Console.ReadLine();
string[] tarihBilesenleri = kullaniciGirisi.Split('.');
DateTime tarihNesnesi = new DateTime(Convert.ToInt32(tarihBilesenleri[2]),
Convert.ToInt32(tarihBilesenleri[1]),
Convert.ToInt32(tarihBilesenleri[0]));
Console.WriteLine(tarihNesnesi.AddMonths(1).ToShortDateString());
Console.ReadKey();
}
}
}
Programın nasıl çalıştığını hızlıca anlatalım. Console.Write yazan satıra kadar olan kısmı ilerleyen derslerimizde anlatacağız. Console.Write komutu ekrana yazı basmamızı sağlayan komuttur. Burada kullanıcıya tarih girmesini söylüyoruz. Bir alt satırda string tipinde bir değişken tanımlıyoruz ve kullanıcının girmiş olduğu değeri Console.ReadLine komutu yardımıyla bu değişkene atıyoruz. Örneğin programı çalıştırıp, 11.06.1989 tarihini girdik. kullaniciGirisi değişkeninin değeri 11.06.1989 olmuş oldu. Daha sonra bir string dizisi tanımlıyoruz, tarihBilesenleri adında. Bu dizinin değerlerini ise Split komutuyla oluşturuyoruz. Şöyle ki, Split fonksiyonu string tipindeki değişkenlere uygulanabilir. Parametre olarak bir karakter veya kelime alır. Aldığı parametreyi string değişken içinde arar ve bulduğu her noktadan bölüp, parçalarından bir dizi oluşturur. Bizim yazdığımız programda kullanıcı 11.06.1989 değerini girmişti, biz de bu değeri Split metodu yardımıyla . karakterlerinden böldük. Elimizde 3 elemanlı bir string dizisi oldu. Elemanlarımız “11”, “06”, “1989” şeklinde.
DateTime nesnesi tarih bilgilerini tutmamızı sağlar. Aslında gün, ay, yıl, saat, dakika, saniye gibi değerlerin tümünü içerisinde barındıran bir tiptir. Detayına Google üzerinde ulaşabilirsiniz, yoksa yazı çok uzun olacak. Bu tarih nesnesi, tarih ile alakalı bir çok işlemde bize yardımcı olacaktır. Yeni bir tarih nesnesi tanımlıyoruz ve değer olarak da kullanıcının girmiş olduğu tarihi vermeye çalışacağız. new DateTime(Yil, Ay, Gun) şeklinde tanımlama yapıyoruz. Yalnız buradaki yıl, ay ve gün değişkeni normalde int tipinde olması lazım; ancak bizim elimizde string dizisi olduğu için her bir değeri int tipine dönüştürmemiz gerek. Bu noktada Convert.ToInt32 metodunu kullanıyoruz. Convert.ToInt32(tarihBilesenleri[2]) diyerek, tarihBilesenleri dizisinin 3. elemanını yani 1989 değerini alıp, Convert metodu ile string tipinden int tipine dönüştürüyoruz. Aynı şekilde ay ve günü de dönüştürüyoruz. Bu işlem sonunda tarihNesnesi değişkeni içerisinde 11.06.1989 değeri oluyor.
Son olarak, ekranda bir ay sonrasını göstereceğimizi söylemiştik. Yine ekrana yazı basmak için Console.WriteLine metodunu kullanıyoruz. İlk satırda Write kullandık, burada WriteLine kullanıyoruz. Farkı ise WriteLine kullandığınızda cümlenin sonunda bir kez Enter’a basmış gibi imleci alt satıra kaydırır. Peki ekrana ne yazıyoruz? Önce tarih nesnesini alıyoruz ve DateTime nesnesinin metodları içerisinden belirli bir ay ekleyip/çıkarmamızı sağlayan metodu çağırıyoruz tarihNesnesi.AddMonths(1). Bu komut ile 01.07.1989 tarihini elde ediyoruz. 1 yerine istediğiniz tam sayıyı yazabilirsiniz. Eksi yazarsanız geriye gider. 01.07.1989 tarihi elde ettik; ama elimizde hala tarih nesnesi var. Ekrana basabilmek için elimizde string tipinde bir değer olmalı. Yine DateTime nesnesinin metodları içerisinden ToShortDateString() metodunu kullanıyoruz ve ekrana 01.07.1989 değerini basıyoruz.
En alttaki Console.ReadKey satırını koymazsak, program çalışır ve sonlandığı anda hemen kapanır, ekrandaki değerleri göremeyiz. Bu satırı yazdığımızda, program çalışmasını bitirecek ve bu satıra geldiğinde bir tuşa basılmasını bekleyecek, dolayısıyla biz de ekranda yazılanları okuyabileceğiz.
Dizilerle alakalı henüz değinemediğim birkaç konu daha var (matrisler, düzensiz diziler ve dizi metodları). Bunlar için mecburen Diziler 2 dersi olacak. En kısa zamanda yazmaya çalışacağım. Bir sonraki yazıda görüşmek üzere…