aofsorular.com
BİL107U

Ünite 3: Temel Kavramlar

PROGRAMLAMA I
Giriş Bu ünitemizde program yazmak için kullanılacak temel bileşenlerden bahsedilmektedir. Çoğu programlama dilinde benzer kontrol elemanları mevcuttur ve çoğu da aynı şekilde kullanılır. C# Programlama Dilinin Özellikleri C#, nesne yönelimli, platform bağımsız, basit ve genel amaçlı, zengin kütüphaneleri bulunan, güvenli, kaynak kullanımı açısından optimize edilmiş, derleme ve çalıştırma süreleri kısa ve hızlı olan, kullanması ve öğrenmesi kolay, yüksek seviyeli modern bir dildir. Gömülü sistemler ve sunucu dâhil çeşitli kullanım amaçlarına yönelik olarak dizayn edilmiş, güçlü tip kontrollerine sahip, farklı işletim sistemlerinde de çalışabilen bir dildir. Anders Hejlsberg, C# programlama dilini geliştiren ekibin başında yer almaktadır ve bu dilin geliştirilmesi de ona atfedilmektedir. C#, nesne ve bileşen odaklı bir dil olma özelliklerini desteklemek amacıyla dil yapılarını sağlamaktadır. Bu da C# dilini, yazılım bileşenlerinin oluşturulup kullanıldığı bir dil olmasını sağlamaktadır. Yüksek seviyeli diğer diller gibi C# programlama dili de sağlam ve güvenilir programlar oluşturmamıza yardımcı olmaktadır. Kod içerisinde artık erişilemeyen nesnelerin temizlenmesi, özel durum yönetimleri ile hata algılama ve hata yönetimi, LINQ (Language Integrated Query) ile kaynak ayırt etmeksizin verilerin ortak bir şekilde işlenebilmesi, zaman uyumsuz işlem yönetimi, dağıtılmış sistemlerin yönetimi gibi özelliklere sahiptir. C# Dili Yazım Kuralları Diller dizayn edilirken kodun çalışması bazı kurallara bağlanmıştır. Bunlar ayrıca kodda tutarlı bir görünüm oluşturarak programa bakan bir kişinin içeriğe daha fazla odaklanmasını sağlar. Kod bloklarının işlevleri, algoritmanın akışı gibi kodun anlaşılabilirliği ve güncellemeleri daha kolay bir şekilde yapmaya imkân sağlar. Birincil amaçlardan biri de ortak çalışılan projede bir yazım birliği kurmak, tutarlılık ve okunabilirliği arttırmaktır. Böylece daha hızlı, kolay düzenlenebilen, herkesin anlayabileceği ve ekibe yeni katılanların da rahatlıkla dâhil olabileceği bir ortam hazırlanmış olacaktır. İsimlendirme Stilleri Programlama dillerinde, operatörler, işlemler ve değişkenler gibi anahtar kelimeler genellikle tek kelime şeklinde kullanılmaktadır. Bunun nedeni de derleyicinin her bir kelimeyi bir operatör ya da anahtar kelime olarak işleme almasından dolayıdır. Günümüzde kullanılmakta olan çeşitli isimlendirme kuralları mevcuttur. Camel Case (CamelCase): İlk kelimeden sonraki tüm kelimelerin ilk harfleri büyük harf yapılıp boşluklar kaldırılarak, kelimeler birleştirilir. Örnek: başarısızGirişSayısı
Pascal Case (PascalCase): İlk sözcük de dâhil olmak üzere tüm sözcüklerin ilk harfleri büyük harfe çevrilir ve aralardaki boşluklar kaldırılır. C# dâhil çoğu dilde sınıfları bildirirken bir kural olarak kullanılır. Örnek: BaşarısızGirişSayısı Snake Case (snake_case): Her boşluğu bir alt çizgi (_) ile değiştirerek kelimeleri birleştirir. Bu stil, büyük harfle yazıldığında, çoğu programlama dilinde sabitleri bildirirken bir kural olarak kullanılır. Küçük harfli olduğunda, geleneksel olarak veri tabanı alan adlarının gösteriminde kullanılır. Örnek: başarısız_giriş_sayısı Örnek: BAŞARI-SIZ_GİRİŞ_SAYISI Kebab Case (kebab-case): Bu stilde ise her bir boşluk (-) tire işareti ile değiştirilerek kelimeler birleştirilir. Bu stil genellikle URL’lerde kullanılır. İsimlendirme Kuralları C# da class, struct ve record yapıları isimlendirilirken Pascal stilinde büyük-küçük harf kombinasyonu kullanılır. Metotların parametrelerini belirtirken ise Camel stili kullanılmaktadır. Düzen Kuralları
• Yazılım geliştirme platformundaki varsayılan kod düzenleme ayarları kullanılmalıdır (otomatik girintileme, sekmeler vs.).
• Her satırda yalnız bir ifade geçmelidir.
• Her satırda yalnız bir bildirim olmalıdır.
• Devam eden satırlar otomatik olarak girintili değilse, bir sekme (dört boşluk) karakteri genişliğinde girinti olmalıdır.
• Metot tanımlamaları ve özellik tanımlamaları arasında en az bir boş satır eklenmelidir.
• Bir ifadedeki tümcelerin görünürlüğünü arttırmak amacıyla parantez kullanılmalıdır. Yorum Oluşturma Kuralları
• Yorum satırları kod ile aynı satırda olmamalı, yeni bir satırda belirtilmeli
• Açıklamalar büyük harf ile başlamalı
• Cümle biçiminde yazılmalı ve sonuna (.) koyulmalı
• Yorum işareti çift bölü (//) ile açıklama arasına bir boşluk bırakılmalı
• Projedeki tüm katılımcılar, açıklamalara ait yönergelere uygun şekilde yorumları girmeli Değişken ve Sabitler İçeriği, program çalıştığı sürece doldurulup değiştirilebilen hafızadaki bir alandır. Bir değişkeni tanımlayan iki parametre vardır: değişkenin türü ve ismidir. Tür bilgisi, hafızada saklanacak verinin içeriği hakkında bilgi verirken, isim bilgisinin de değişkenin hafızadaki yerine ulaşılmasını sağlayan bir etiket veya adres bilgisi olduğunu düşünebiliriz. Değişken tanımlanması:
C#’ta bir değişkene herhangi bir değer atamadan kullanmaya izin verilmez. Eğer bir değişkeni kullanmak istiyorsak, o değişkene bir ilk değer verilmesi zorunludur. Bu kural değer ve referans tipleri için de geçerlidir. Değişken tanımlamaları ise program içinde istenilen yerde yapılabilir, burada bir kısıtlama bulunmamaktadır. Değişken isimlendirmedeki kurallar:
• Değişken isimlendirmelerinde büyük-küçük harf duyarlılığı vardır. Değişkenlere benzer isimler vermek, ileride kodun yönetimi açısından da sorunlara neden olabilir.
• Değişken isimleri nümerik bir karakterle başlayamaz.
• Değişken isimlerinde boşluk karakteri, tire (-) işareti ve tırnak (“) işareti bulunamaz, tüm değişkenler tek kelimelik olmalıdır. Sabitler ise değişkenler ile aynı kurallara uymak zorundadır. İlk değer atamasının sabit ifadelerle yapılması zorunludur ve isimlendirmeleri değişkenler gibidir. Aralarındaki tek fark, hazırlanan program boyunca değerleri değişmeyecek veriler olmalarıdır. Sabit tanımlaması yapılması için sabit tipinin başına “const” anahtar sözcüğü eklenir. Sabitler, yapılarından dolayı “static” nesne olduğu için ayrıca “static” olarak belirtilmelerine gerek yoktur. Enum (Enumerations) Türü Alabileceği değerleri sabit olan değişkenler enum olarak tanımlanabilir. Program içerisinde sayısal türde yapılacak karşılaştırma ve işlemlerde kullanılır. Kodun okunurluğu ve hata ayıklamasını kolaylaştırır. Diğer değişken türlerindeki isimlendirme kuralları, enum için de geçerlidir. Enum sabitlerine değer ataması yapılmazsa, ilk elemanının değeri sıfırdan başlayarak birer birer artan sayısal değer alırlar. Varsayılan değişken türleri integer’dır. Enum sabitler ayrıca byte, sbyte, short, ushort, long, ulong, int, uint türlerinden de tanımlanabilirler. Anahtar Sözcükler (Keywords) Derleyicisi için özel anlamı olan, önceden tanımlanmış ve ayrılmış sözcüklere “Anahtar Kelimeler” denir. Anahtar kelimeler tanımlayıcı olarak (bir değişkenin adı, sınıf, arayüz vb.) kullanılamaz. Belirleyici Anahtar Sözcükler (Modifier Keywords) Belirleyici anahtar sözcükler, türleri ve tür üyelerini kimlerin değiştirebileceğini belirten, programlama dili tarafından tanımlanmış anahtar sözcüklerdir. C# da anahtar sözcükler: abstract, partial, async, readonly, const, sealed, event, static, extern, unsafe, new, virtual, override, volatile. Geçerlik Bölgesi Değişkenler sadece tanımlı olduğu bölgede geçerlidir. Sınıftan türetilen nesne bilgileri bellekte durdukça değişken de kendi adres bilgisini koruyacaktır. Kodun içerisindeki bloklarda tanımlı değişkenlere ise sadece tanımlandıkları bloktan ve varsa alt bloklardan erişilebilir. Blok aktif olduğu sürece değişkene erişilebilir, blok işlenip bittikten
sonra bellekteki adresi silinir. Bir metot, bir döngü, { } arasına yazılmış kod blokları içinde tanımlı değişkenlere “yerel değişen”, sınıf içerisinde tanımlı değişkenlere de “sınıf değişkenleri” ya da “sınıf ögeleri” denmektedir. Değer ve Referans Türleri C# programlama dilinde Değer ve Referans tipleri olmak üzere iki tür veri tipi yer almaktadır. Değer tipleri verinin değerini üzerlerinde taşırlar ve taşıdıkları veriye göre bellek üzerinde yer kaplarlar. Referans türleri ise bellekte veri yerine verinin tutulduğu yerin adresini tutarlar. Burada “string” türü için bir istisna mevcuttur. Metotlara parametre olarak aktarılan string değerler, referans türü olmasına rağmen değer türü gibi kopyalanır. Değer türleri: “int”, “long”, “float”, “double”, “decimal”, “char”, “bool”, “byte”, “short”, “struct”, “enum”. Referans türleri: “string”, “object”, “class”, “interface”, “array”, “delegate”, “pointer”. “ref” ve “out” Anahtar Kelimeleri ref: Metodun kendi parametresini değiştirmesine izin vermek “ref” anahtar sözcüğü, değerlerin metotlara referans ile geçirilmesini sağlar. Bu anahtar sözcüğünü referans tipleri için kullanmaya gerek yoktur, kullanımında da hata oluşmayacaktır. Dikkat edilmesi gereken nokta, metot bildiriminde “ref” sözcüğü kullanıldıysa, metodun çağrımında da kullanılması gerekmektedir. Değer atanmadan değişken gönderildiğinde de “Use of unassigned local variable” hatası alınacaktır. out: Metodun birden fazla değer döndürmesine izin vermek Bir metot içinde birden fazla geri dönüş yapılması bekleniyorsa kullanılır. “out” parametresi ile çağrılan değişkene ilk değer atama zorunluluğu bulunmamaktadır. Bu ifade ile kullanılan değişkenlere değer atanmamış olarak kabul edilmektedir. Kullanılan metotların içinde bir değer atanıp döndüreceği varsayılmaktadır. Kullanımı “ref” den farklı değildir. Veri Türleri Değişkenler, programda kullanılan verilerin bellekte tutulan yerlerini gösteren adreslere verilen isimlerdir. Değişkenler türlerine göre farklı boyutlarda verileri tutabilirler. Temel veri türleri kitabınız sayfa 55’te Tablo 3.2’de detaylı şekilde verilmiştir. En çok kullanılanları şu şekilde sıralayabiliriz. Int32 ya da int, pozitif ve negatif tam sayıları ifade etmektedir. UInt32 ya da uint, sadece pozitif sayıları ifade etmektedir. Hem pozitif hem de negatif kısa tam sayılar için de sbyte kullanılmaktadır. Virgüllü sayılar için float kullanılmaktadır. Bir diğer kesirli sayılar için geliştirilmiş tip olan decimal, diğer türlerden daha geniş bir değer aralığını desteklemektedir. Karar verme işlemlerinde kullanılan bool veri tipi true ya da false değerlerini alabilir. Boolean veya bool şeklinde kullanılabilir. char veri
tipindeki değerler her zaman tek tırnak ( ‘’ ) içinde yazılır ve yalnız bir karakter içerebilir. Metinler için ise char tipinin yeterli olmadığı yerlerde kullanılmak üzere geliştirilen string tipi kullanılmaktadır. Uzun ya da kısa, içerik olarak char tipinden oluşturulabilen tüm dizileri destekler. String tipindeki değerler çift tırnak ( “” ) içine yazılırlar. Referans tipi olduğu için kesin boyutları yoktur. Değişken tipi tanımlarken kararsız kalınan durumlarda C# derleyicisinin, tutulan değere göre otomatik olarak tip tanımlaması yaptığı “var” tipi mevcuttur. Tür Dönüştürme Veri türleri arasında dönüşüm yapılabilmektedir. Bu dönüşümler daha çok sayısal türler arasında açık/direk (explicit) ve kapalı/dolaylı (implicit) olarak gerçekleştirilir. Açık tür dönüşümü ve kapalı tür dönüşümü ile ilgili tablolar kitabımız sayfa 58’de verilmiştir. Açık (Explicit) Dönüşüm: Derleyici tarafından desteklenmeyen bir dönüşümün, belirli metotlar yardımıyla zor kullanarak dönüştürülmesidir. Büyük türün küçük türe dönüştürülmesi olarak da tanımlayabiliriz. Veri kaybı oluşması muhtemeldir. () ya da System.Convert ile dönüşüm yapılabilir. Kapalı (Implicit) Dönüşüm: Herhangi bir veri kaybı yaşanmayan dönüşümlerdir. Küçük türün büyük türe dönüştürülmesi de diyebiliriz. Bu tarz dönüşümler serbest bırakılmıştır. Programda herhangi bir bildirim yapılmasına gerek duyulmaz ve dönüşüm derleyici tarafından otomatik olarak yapılır. Kutulama ve Kutudan Çıkarma (Boxing ve Unboxing) C# programlama dilinde bulunan referans (reference type) ve değer (value type) veri türleri, bellekte farklı şekillerde tutulmaktadır. Değer tipleri (int, double, float, char vb.) belleğin stack (yığın) alanında, referans tipleri (Class, Object, Interface, String vb.) de heap (öbek) alanında tutulurlar. Bu nedenle boxing ve unboxing işlemleri yapılmaktadır. Boxing, değer tipindeki bir değişkeni, referans tipindeki bir nesneye aktarma işidir. Otomatik olarak yapılan bir işlemdir. Unboxing de bu işlemin tam tersidir. double db=555662215482; object obj; obj=db; Kutudan Çıkarma (Unboxing) ise biraz daha farklı bir işlemdir. Bu işlemde, başvuru nesnesinin işaret ettiği veri öbekten alınarak, yığına bir değer tipi olarak kopyalanır. İşlem sırasında tip uyuşmazlığı kavramı ile karşılaşırız. Öbekten yığına kopyalanacak verinin, yığında ayrılan yer ile aynı tipte ya da daha büyük veri tutabilecek büyüklükte olması gerekmektedir. double db=555662215482; object obj; obj=db; double doubDb ; doubDb = (double)obj;
İfadeler C# dilinde, +, -, *, /, %... gibi matematiksel operatörler kullanılarak bir değeri hesaplamak için oluşturulmuş matematiksel formüllere ifade adı verilmektedir. Temel İşlemler (Operatörler) Atama Operatörü: Bir değerin bir değişkene veya sabite atanmasında kullanılır. ( = ) ile gösterilir. Her zaman eşitliğin sağ tarafı, sol taraftaki değişkene atanır. C# dilinde kullanılan operatörleri: Çoklu Atama Bir satırda birden fazla değişkene atama yapılabilir. Buna çoklu atama denir. Fakat çoklu atama, kullanımı ve kodun anlaşılmasını zorlaştıracaktır. Tekli Aritmetik Operatörler ++ ve -- kullanıldığı işlemlerdir. Arttırma ve azaltma işlemleridir. Bileşik Atama Operatörleri Bileşik atamada +=, -=, *=, /=, %= gibi operatörler kullanılmaktadır. Bir ifadede birden fazla aynı tip operatör varsa birleşme özelliği uygulanır. İfadede farklı türlerde operatörler varsa bu sefer öncelik kuralı uygulanır. Aritmetik Operatörler Aritmetik işlemler için kullanılan operatörlerdir. +, -, *, /, %, ++, -- Karşılaştırma Operatörleri Bu operatörler de iki değeri karşılaştırır ve doğru (true), yanlış (false) değerini döndürürler. ==, !=, <, >, <=, >= Mantıksal Operatörler Yapılan karşılaştırma işlemlerinin doğru mu (true) veya yanlış mı (false) olduklarını birleştirmek için kullanılırlar:
• && (AND -ve anlamında-)
• || (OR -veya anlamında-)
• ! (NOT -değil, tersi anlamında-). Öncelik Kuralları Programlama dilinde, tek başlarına işlev ve anlamı olmayan fakat işlem yaparken kullanılan karakterlere operatör denilmektedir. +, -, *, / gibi sembollere operatör denilmektedir. “a / b” ifadesindeki / sembolü operatör, a ve b ise operatörün etki ettiği operand adı verilmektedir. Operatörler, ikiden fazla operand ile işlem yapmak için kullanıldıklarında kendi içlerinde bir işlem sırasını takip etmek zorundadırlar. Bu sıralamayı kitabınız sayfa 63’de Tablo 3.8’de bulabilirsiniz. İşlemlerde hata yapmayı önlemek için ifadeleri parantez kullanmak daha iyidir. Akış Kontrol Yapıları C# programlama dilinde, komutlar yazıldıkları sıra ile çalışır. Akış kontrol yapıları ihtiyaca yönelşk yönlendirmeler yapmakta ve bu yönlendirmelerdeki denetim görevini üstlenmektedir. Blok yapıları,
Yönlendiriciler (if-else, switch), Döngüler (for, foreach, while, do..while) olarak üçe ayrılır. Blok Yapıları { } arasına yazılmış kodlar sırasıyla çalıştırılır. Bu yapıya blok adı verilmektedir. Genellikle belli bir işin sırayla yapılması gereken adımları bu bloklara ayrılarak yazılmaktadır. İçi boş veya iç içe geçmiş blok yapıları da olabilir. Blok içerisinde tanımlanan bir değişken, blok çalıştırıldıktan sonra hafızadaki yeri silinerek erişilemez hâle gelmektedir. Blok içinde tanımlı değişkene yerel değişken denmekte ve blok dışından erişilememektedir. Fakat blok içinden dış bloklara erişim imkânı vardır. Yönlendiriciler (if-else, switch)
• if deyimi: Belirlenmiş koşullara göre farklı işlemlerin yapılmasını sağlar. Koşulumuz doğru (true) değeri alıyorsa, if bloğunun içi çalıştırılacaktır. Yanlış (false) değeri alan koşullarda ise, varsa başka “else if” ya da “else”koşulları test edilir. Koşulu sağlayan blok çalıştırılır. Hiçbir koşula uymuyorsa, kodun devam eden satırları çalıştırılır. if bloğunda birden fazla işlem satırı varsa işlemlerin { } program bloğuna alınması gerekmektedir. Tek satırlı bir if bloğu (Ternary If) kullanımı daha vardır.
• Switch deyimi: Kodun içerisinde aynı durum için yapılacak kontrol işlemleri sayıca çok ise ifelse blokları yerine switch deyimi kullanılabilir. Her case ifadesi, bir atlama deyimi (return, break, continue, goto) ile sonlandırılmalıdır. Continue deyimi ise switch kontrolü bir döngü (for, while gibi) içinde tanımlandığında, sonraki döngü elemanına geçmek için kullanılabilir. Bir case içinde hiçbir deyim verilmemişse atlama deyiminin kullanımına ihtiyaç yoktur. Kontrol edilecek değişken ifademiz ise byte, short, int, long, char veya string tiplerinden seçilerek kullanılmalıdır. İfademiz, float ve double tiplerinden seçilemez. case’den sonra gelecek ifadelerin sabit olması gerekmektedir. Akış bir case ifadesinden başka bir case ifadesine “goto” sözcüğü kullanılarak yönlendirilir. Bir switch bloğunda aynı case iki defa yazılamaz. Döngüler Tekrar eden işlemler için döngülerden yararlanırız. Döngüler sonsuz sayıda ya da istenildiği kadar çalıştırılabilir. Döngü komutundan sonraki deyimler döngü bloğunu oluşturmaktadır. Birden çok deyim varsa, döngü içerisinde çalıştırabilmek için { } arasına yazılmalıdır. Döngü komutları: for, foreach, while ve do while. for döngüsü: Belirli sayıda tekrar edecek ifadeler için kullanılır. for( başlangıç; koşul; arttırma/azaltma ) { deyim; } Başlangıç, döngüdeki akışı kontrol edecek indeks değişkenidir. Bu değişkene ilk değeri atanarak döngünün başlaması sağlanır. Koşul indek tarafınsan her adımda kontrol edilir. Koşul sağlandıkça döngü devam eder.
foreach döngüsü: Bu döngü için, for döngüsünün sınırlandırılmış şeklidir diyebiliriz. İçindeki “in” anahtar kelimesi ile herhangi bir dizi, koleksiyon yapısı üzerinde çalışmaktadır. Döngü içerisinde dizi türünde ya da “var” türünde tanımlanmış bir değişkene dizi elemanları sırayla atanır. Dizideki her bir eleman için döngü çalıştıktan sonra döngümüz sona erecektir. foreach( değişken in dizi/koleksiyon ) { deyim; } while döngüsü: Döngü içerisindeki koşul sağlandığı sürece kod bloğu çalışmaya devam edecektir. Dikkat edilmesi gereken husus, döngünün koşulunun yazılan kodun akışına uygun bir şekilde sonlandırılması gerektiğidir. Aksi hâlde yazılan kod sonsuz bir döngüye girecektir. while( koşul ) { deyim ; } do while döngüsü: do while döngüsünde kod bloğu her zaman en az bir kere çalıştırılır. Yani, önce kod bloğu mutlaka çalıştırılır, sonra döngünün tekrar çalıştırılması için koşul kontrol edilir. do { deyim ; } while( koşul ) ; Dizi Yapıları (Array) Diziler, aynı türden tanımlanmış birden çok elemanın tutulabileceği bir listedir diyebiliriz. Elemanların türleri kullanıcı tarafından da tanımlanabilir, bu amaçla elemanlar için bir sınıf tanımlayabiliriz. Ya da farklı türde elemanların aynı diziye atanabilmesi için dizi elemanları object olarak tanımlanabilir. İndisler, dizideki istediğimiz elemana kolayca erişebilmemizi sağlar. Dizilerin tanımlandıkları yerde uzunluklarının da belirtilmesi gerekmektedir. Boyutları sabittir, uygulama sürecinde dizilerin boyutları değiştirilemez. Tek Boyutlu Diziler Diziler referans türünde değişkenlerdir, isimlendirilmeleri beklenir. C# programlama dilinde, dizinin ilk elemanının indisi 0 ile başlar. Dizide n tane eleman varsa, eleman indisleri “0” ile “n-1” arasında olacaktır. değişken_türü[ ] diziAdı ; değişken_türü[ ] diziAdı = new değişken_türü[ eleman_sayısı ]; C# dilinde bütün sayısal değişkenlerin ilk değerleri 0, bool tipinde false ve referans tiplerinde ise null olmaktadır. Çok Boyutlu Diziler İki boyutlu diziler yani matrislerin tanımı da diziler gibi olmakla birlikte, sadece tanımlandıkları yerde ilave bir virgül ile belirtilmesi gerekmektedir. Ayrıca üç ve dört boyutlu diziler de tanımlanabilmektedir.