Görsel C# Programlama Güz 2009 (6. Hafta)
Diziler (Arrays) Diziler (arrays), aynı veri tipine sahip birden fazla veriyi bünyelerinde saklayan veri yapılarıdır. (Data Structures) Değişkenler içerisinde yalnız bir tek bilgi depolarken dizileri kullanarak aynı türden birden fazla bilgiyi saklayabiliriz. Programımız içerisinde kullanacağımız 100 adet tamsayıyı 100 farklı değişken içinde saklamak yerine bu amaçla içinde 100 tamsayı saklı bir dizi kullanmak daha mantıklıdır.
c bu dizinin adıdır. c.Length bize dizinin kaç elemana sahip olduğunu söyler. c dizisi 12 elemana sahiptir. ( c[0], c[1], … c[11] ) [ ] sayesinde dizinin elemanlarına ulaşırız. (indeks)
İndeks (Index) İndeks dizi elemanlarına ulaşmamızı sağlayan pozisyon numarasıdır. İndeks ya pozitif bir tamsayı ya da tamsayılarla ilgili bir deyim olabilir. Dizilerin ilk elemanının indeksi daima SIFIR dır. a = 5; b = 6; c[ a + b ] += 2; deyimi c dizisinin c[ 11 ] elemanının içeriğine 2 ekler.
!!! Dikkat !!! Dizilerin indeks numaraları sıfırdan başladığı için, c[7] ile bu dizinin yedinci elemanı farklı şeyleri ifade eder. c[7] normalde dizinin sekizinci elemanıdır.
Dizilerin Deklare Edilmesi ve Oluşturulması Diziler bellekte yer kaplayan nesnelerdir. (objects) Diziler new anahtar kelimesiyle bellekte dinamik olarak oluşturulurlar. int[] c = new int[ 12 ]; // Aynı anda deklare et ve olustur Veya int[] c; // once deklare et c = new int[ 12 ]; // sonra olustur
Hatırlatma C++’ tan farklı olarak C#’ ta dizi deklare ederken boyutu köşeli parantezler içerisinde girmek bir derleyici hatasına sebep olur. (Örneğin, int[ 12 ] c;)
Dizilerle İşlemler Dizinin deklarasyonu Dizinin oluşturulması Dizi elemanlarına ilk değer atanması Dizinin manipulasyonu
Create 10 ints for array; each int is initialized to 0 by default Declare array as an array of ints InitArray.cs array.Length returns length of array Each int is initialized to 0 by default array[counter] returns int associated with index in array
İlk Değer Atama Listeleri (Initializer Lists) Dizi elemanlarına atanacak ilk değerler { } arasına birbirlerinden virgülle ayrılarak yazılırlar. int[] n = { 10, 20, 30, 40, 50 }; değimi n adında, içerisinde 5 tamsayı saklayan bir dizi oluşturur. Dizi elemanlarının indeks değerleri : 0, 1, 2, 3, 4 İlk değer atama listeleri kullanıldığında new anahtar kelimesine gerek yoktur. Derleyici dizinin boyutu olarak girilen değerlerin sayısını kullanır.
Declare array as an array of ints InitArray.cs Compiler uses initializer list to allocate array
Sabit Değişkenler (Constant Variables) Bu başlık sizlere de ilginç geldi mi? (Oxymoron) Bu tür değişkenler “const” anahtar kelimesi ile deklare edilirler. Sadece okunabilir değişkenler (read-only variables) olarak da adlandırılırlar. Bu tür değişkenlere, deklare edildikleri anda muhakkak bir ilk değer ataması yapılır ve bu değer daha sonra değiştirilemez. Sabit değişken tanımlamak ve bunu dizilerin boyutu olarak kullanmak genel olarak tercih edilen bir yoldur.
Sabit Değişkenler (Constant Variables) Sabit değişkenleri diğer değişkenlerden ayırtedebilmek için kullanılabilecek bir notasyon: Sabit değişken isimlerinin bütün karakterlerini büyük harfle yaz, değişken ismi birden fazla kelimeden oluşuyorsa kelimeleri birbirinden alt çizgilerle ayır. ÖRNEK: const int DIZI_BOYUTU;
Hatırlatma Deklare edilmiş ve ilk değer atanmış bir sabit değişkene yeni bir değer atamaya çalışmak derleyici hatası verir. Örnek: const int DIZI_BOYUTU=10; DIZI_BOYUTU=11; Sabit bir değişkeni ilk değer atamadan deklare etmeye çalışmak derleyici hatası verir. const int DIZI_BOYUTU; DIZI_BOYUTU=10;
Declare constant variable ARRAY_LENGTH using the const modifier InitArray.cs (1 of 2) Declare and create array that contains 10 ints array.Length : Dizinin eleman sayisini geri cevirir. array.Rank : Dizinin kac boyutlu oldugunu geri cevirir. Use array index to assign array value
InitArray.cs (2 of 2)
Declare array with initializer list SumArray.cs Sum all array values
Hatırlatma Bir dizinin elemanları içerisinde bir döngü vasıtasıyla gezilirken dizi indeksinin sıfıra eşit veya büyük ayrıca dizinin boyutundan küçük olmasına dikkat edilmelidir. Döngüye devamı test eden koşulun indeks değerlerinin bu aralıkta olacağını garanti etmesi gerektiğini unutmayınız.
foreach Deyimi foreach deyimi bir dizinin elemanlarının indeks kullanılmadan ziyaret edilebilmesine imkan tanır. foreach deyimi dizi elemanları üzerinde değişiklik yapamaz. Kullanım foreach ( veri tipi tanımlayıcısı in dizinin adı ) deyimler
for(int i=0;i<array.Length;i++) total+=array[i]; ForEachTest.cs For each iteration, assign the next element of array to int variable number, then add it to total for(int i=0;i<array.Length;i++) total+=array[i];
Dizileri ve Dizi Elemanlarını Metodlara Argüman Olarak Kullanma Diziler metodlara otomatik olarak referans argüman biçiminde gönderilirler. Dizi adları aslında dizinin ilk elemanının bellekteki adresidir çünkü. Dizi adı metod argümanı olarak köşeli parantezsiz kullanılır. Dizinin deklarasyonu double[] a = new double[ 24 ]; 2. Metodun çağrılması DiziyiDegistir( a ); 3. Metodun tanımı void DiziyiDegistir( double[] b )
Declare 5-int array with initializer list PassArray.cs (1 of 3) Pass entire array to method ModifyArray
Pass array element array[3] to method ModifyElement PassArray.cs (2 of 3) Pass array element array[3] to method ModifyElement Method ModifyArray manipulates the array directly
Method ModifyElement tries to manipulate an array’s element PassArray.cs (3 of 3)
Bir Diziyi Bir Metodun Argümanı Olarak Kullanma Diziler metod argümanı olarak referansla (call-by-reference) çağrılırlar. Bir metod, dizinin baslangıç adresini argüman olarak kullanır ve böylece bellekteki yeri bilinmiş olur. Çağıran metod böylelikle çağırdığı metoda argüman olarak verilen bilgiyi manipule edebilme hakkını da vermiş olur. Diziler değer ile (call-by-value) metodlara argüman olarak atansalardı eğer bu bir performans eksikliğine yol açardı. (Metod içerisinde işlensin diye dizinin herbir elemanının kopyası alınırdı.) SIKLIKLA çağrılan metodlardaki kapasitesi büyük diziler böyle bir soruna sebep olurdu.
Çok Boyutlu Diziler Örneğin 2 boyutlu dizileri ele alalım. (Matrisler) İçinde bilgi saklanan tablolar gibi düşünülebilirler. Satırlar (rows) ve sütunlar (columns) vardır. Dizinin elemanlarına birbirlerinden virgüller ayrılmış 2 indeksle ulaşılır. int[ , ] b= { { 1, 2 }, { 3, 4 } }; b[0,0] =1 b[0,1]=2 b[1,0] =3 b[1,1]=4
İçinde Dizi Saklayan Diziler (Jagged Arrays) int[][] jagged = { new int[] {1, 2}, new int[] {3}, new int[] {4, 5, 6 } };
Çok Boyutlu Diziler 3 satır ve 4 sütunlu (3-by-4 array) bir dizi deklarasyonu int[ , ] b; b = new int[ 3 , 4 ]; İçinde dizi saklayan dizi deklarasyonu int[][] b; b = new int[ 2 ][ ]; // 2 satırlı b[ 0 ] = new int[ 5 ]; // 1. satır 5 sütunlu b[ 1 ] = new int[ 3 ]; // 2. satır 3 sütunlu
Çok Boyutlu Dizilerin Manipülasyonu Genelde for döngüleri kullanılır. int total = 0 for ( int row = 0; row < a.GetLength(0); row++ ) { for ( int column = 0; column < a.GetLength(1); column++ ) total += a[ row, column]; }
InitArray.cs (1 of 3) Use nested array initializers to initialize the “rectangular” array array1 Use nested array initializers of different lengths to initialize the “jagged” array array2
Passes in a “rectangular” array Iterates through each of the array’s “rows” GetLength returns the length of each dimension Iterates through each of the array’s “columns” InitArray.cs (2 of 3)
Passes in a “jagged” array Iterates through each of the array’s “rows” array[row].Length returns number of columns associated with row subscript Iterates through each of the array’s “columns” InitArray.cs (3 of 3)
Bir Dizinin En Küçük ve En Büyük Elemanını Bulma using System; class DizilerleIslemler { static void Main(string[ ] args) int enKucuk, //Dizinin en kucuk elemanini saklayan degisken enBuyuk; //Dizinin en buyuk elemanini saklayan degisken const int DIZI_BOYUTU = 10; //Dizinin boyutunu saklayan sabit degisken int[ ] a = new int[DIZI_BOYUTU]; Random rastgele = new Random(); Console.WriteLine("Dizinin Icerigi:"); for (int i = 0; i < a.Length; i++) a[i] = rastgele.Next(5, 50); //Dizinin i. elemanina 5 ile 50 arasinda rastgele bir sayi ata Console.Write("{0} ", a[i]); } Console.WriteLine();
Bir Dizinin En Küçük ve En Büyük Elemanını Bulma KucuguBuyuguBul(a, out enKucuk, out enBuyuk); //Neden out, ref degil???? Console.WriteLine("a dizisinin en kucuk elemani: {0}", enKucuk); Console.WriteLine("a dizisinin en buyuk elemani: {0}", enBuyuk); }
Bir Dizinin En Küçük ve En Büyük Elemanını Bulma //Kendine arguman olarak aldigi dizinin en kucuk ve en buyuk elemanini bulan metodun tanimi //Referans kullanarak geriye birden fazla degerin donduruldugune dikkat ediniz!!!!!!! public static void KucuguBuyuguBul(int[ ] b, out int minimum, out int maksimum) { minimum = b[0]; //Dizinin en kucuk elemaninin ilk eleman oldugunu varsay maksimum = b[0]; //Dizinin en buyuk elemaninin ilk eleman oldugunu varsay for (int i = 1; i < b.Length; i++) //i’nin 1 den basladigina dikkat ediniz!!!! if (b[i] < minimum) minimum = b[i]; if (b[i] > maksimum) maksimum = b[i]; }
“Selection Sort” Sıralama Algoritması ile Küçükten Büyüğe Sıralama (Ascending Sort) using System; class DizilerleIslemler { static void Main(string[ ] args) const int DIZI_BOYUTU = 10; //Dizinin boyutunu saklayan sabit degisken int[ ] a = new int[DIZI_BOYUTU]; Random rastgele = new Random(); Console.WriteLine("Siralanmamis Dizinin Icerigi:"); for (int i = 0; i < a.Length; i++) a[i] = rastgele.Next(5, 50); //Dizinin i. elemanina 5 ile 50 arasinda rastgele bir sayi ata Console.Write("{0} ", a[i]); } Console.WriteLine(); Ikinci bir dizi kullanmadan yapilan bu siralamaya IN-PLACE SORT denir.
“Selection Sort” Sıralama Algoritması ile Küçükten Büyüğe Sıralama (Ascending Sort) DiziyiKucuktenBuyugeSirala(a); Console.WriteLine("Siralanmis Dizinin Icerigi:"); foreach (int eleman in a) Console.Write("{0} ", eleman); Console.WriteLine(); }
“Selection Sort” Sıralama Algoritması ile Küçükten Büyüğe Sıralama (Ascending Sort) //Kendisine arguman olarak aldigi diziyi kucukten buyuge dogru siralayan fonksiyonun tanimi public static void DiziyiKucuktenBuyugeSirala(int[ ] b) { int minimumunIndeksi; int geciciDegisken; for(int i=0;i<(b.Length-1);i++) minimumunIndeksi=i; for(int j=i+1;j<b.Length;j++) if(b[j]<b[minimumunIndeksi]) minimumunIndeksi=j; //swap yap geciciDegisken=b[i]; b[i]=b[minimumunIndeksi]; b[minimumunIndeksi]=geciciDegisken; } System isim uzayinin Array sinifi zaten bir Sort fonksiyonuna sahip Array.Sort(a); Array.Reverse(a);