Değişkenlerin özellikleri aşağıdakiler ile karakterize edilir:
isim (tanımlayıcı), örneğin yaş;
tür (sakladığı bilginin), örneğin int;
değer (depolanan bilgi), örneğin 25.
Değişken, belirli bir veri türünde değer saklayan adlandırılmış bir bellek alanıdır ve bu bellek alanına adıyla programda erişilebilir. Değişkenler programın işlevini sağlayan bellekte (yığın) doğrudan saklanabilir veya daha büyük nesnelerin (örneğin karakter dizeleri ve diziler gibi) saklandığı dinamik bellekte depolanabilir. Temel veri türlerine (sayılar, char, bool) değer türleri denir çünkü onlar program yığınında doğrudan kendi değerlerini depolarlar. Referans veri türleri (örneğin dizeler, nesneler ve diziler gibi) dinamik bellekte bunların değerinin saklandığı bir adrese işaret eder. Dinamik olarak onlara bellekte yer ayrılabilir ve serbest bırakılabilir, yani boyutları değer türlerinin aksine önceden sabit olarak belirli değildir. Değer ve referans veri türleri hakkında daha fazla bilgi "Değer ve Referans Türleri" Bölümü’nde bulunmaktadır.
2.4.2 Değişkenlerin Adlandırılması – Kurallar Derleyiciden programımızda kullanılan bazı bilgiler için bellek alanı ayırmasını istediğinizde bunun için bir ad sağlamanız gerekir. Bu ad abir tanımlayıcı gibi çalışır ve ilgili bellek alanına işaret edilmesini sağlar.
Değişkenin adı seçtiğimiz herhangi bir ad olabilir, ancak C# dilinin spesifikasyonunda belirlenmiş bazı kurallara uymanız gerekir:
Değişken adları a – z, A – Z harfleri, 0 – 9 rakamlarının yanı sıra '_' karakterini içerebilir.
Değişken adları rakam ile başlayamaz.
Değişken adları C# dilinin bir anahtar sözcüğü ile denk olamaz. Örneğin base, char, default, int, object, this, null ve diğerleri değişken adları olarak kullanılamazlar.
C# anahtar sözcüklerinin listesi "Programlamaya Giriş" Bölümü’nün "Anahtar Kelimeler" altbölümünden bulunabilir. Değişkene bir anahtar sözcük gibi bir ad vermek isterseniz, ada bir önek ekleyebilirsiniz – “@”. Örneğin char ve null geçersiz adlar olduğu halde, @char ve @null geçerli adlardır.
2.4.3 Değişkenlerin Adlandırılması – Örnekler Uygun adlar:
name
first_Name
_name1
Yanlış adlar (derleme hatasına yol açar):
1 (rakam)
if (anahtar sözcük)
1name (bir rakam ile başlıyor)
2.4.4 Değişkenlerin Adlandırılması – Öneriler Değişkenleri nasıl adlandıracağınıza dair bazı öneriler sunacağız, çünkü derleyici tarafından izin verilen adların tümü değişkenler için uygun değildir.
Adlar tanımlayıcı olmalı ve değişkenin ne için kullanıldığını açıklaması gerekir. Örneğin, bir kişinin adını saklayan bir değişken için uygun bir isim personName olup ve uygunsuz ad a37 olur.
Sadece Latin harfleri kullanılmalıdır. Kiril harflerine derleyici tarafından izin verilse de, bu değişkenleri veya program dahilinde kalan tanımlayıcıları adlandırmada kullanmak için iyi bir uygulama değildir.
C# için genellikle değişken adlarının küçük harfle başlaması ve küçük harfleri içermesi gerektiği kabul edilir, ancak, her yeni sözcük büyük harfle başlamalıdır. Örneğin, firstName adı firstname yada first_name kullanmaktan daha doğru ve daha iyidir. Değişken adlarında _ karakterinin kullanımı kötü bir adlandırma tarzı olarak kabul edilir.
Değişken adları ne çok uzun ne de çok kısa olmalıdır – onların sadece kendi bağlamında değişken amacını açıklığa kavuşturması gerekir.
Büyük ve küçük harfler C# onları ayırdığı için dikkatle kullanılmalıdır. Örneğin, age ve Age farklı değişkenlerdir.
İşte iyi adlandırılmış değişkenlerden bazı örnekler:
firstName
age
startIndex
lastNegativeNumberIndex
Ve işte kötü adlandırılmış değişkenlerden bazı örnekler (Adlar C# derleyicisine göre doğru olmasına rağmen):
a37(ad açıklayıcı değildir ve değişkenin amacını açıkça anlatmıyor)
fullName23, fullName24, vb. (Kullanılan değişkenin netliğini geliştirmediği sürece bir değişken adının rakam içermesi uygun değildir; eğer farklı bir sayı ile biten benzer adlara sahip değişkenler olması gerekiyorsa, aynı veya benzer tür veriyi depolamak için, tek bir koleksiyon veya dizi değişkeni oluşturmak ve onu örneğin fullNamesList olarak adlandırmak daha uygun olabilir.
Değişkenler kısaca amacını açıklayan adlara sahip olmalıdır. Değişken uygunsuz bir ad ile adlandırıldığı zaman, programın sonradan okunması ve değiştirilmesi çok zor hale gelir (nasıl çalıştığını bir süre sonra unutmuş olduğumuzda). Değişkenlerin doğru adlandırılması hakkında daha fazla açıklama için "Yüksek Kalite Programlama Kodu" Bölümü’ne bakınız.
Değişkenleri adlandırırken, her zaman kısa ve kesin adlar kullanmayı deneyin. Değişken adı ne için kullanıldığını belirtmelidir kuralını izleyin, örneğin ad şu soruyu cevaplamalıdır “bu değişkende ne değer saklanır”. Bu koşul yerine getirilmediği zaman daha iyi bir ad bulmaya çalışın. Rakamlar değişken adlarında kullanılmak için uygun değildir.
2.4.5 Değişkenlerin Bildirilmesi Bir değişkeni bildirdiğinizde, aşağıdaki adımları gerçekleştirsiniz:
değişkenin türünü belirtmek (int gibi);
adını belirtmek (age gibi bir tanımlayıcı);
isteğe bağlı olarak başlangıç değerini belirtmek (örneğin 25 gibi), ancak bu zorunlu değildir.
C# değişkenlerini bildirmek için sözdizimi aşağıdaki gibi şöyledir:
2.4.6 Değer Atanması Bir değişkene değer atanması, değişken içinde saklanması gereken bir değeri sağlamakla yapılır. Bu işlem "=" atama operatörü tarafından gerçekleştirilir. Operatörün sol tarafına değişken adını ve sağ tarafına – değişkenin yeni değerini koyarız.
2.4.7 Değişkenlerin Başlatılması Programlamada başlatma kelimesi bir başlangıç değerini belirtmek demektir. Değişkenlerin bildirilme anında onlara değer atayarak onları gerçekte başlatmış oluyoruz.
2.4.7.1 Standart Değişken Değerleri C# dilinde her veri türü varsayılan bir değere sahiptir (buna varsayılan başlatma değeri denir), belirli bir değişken için hiçbir değer açıkça atanmamış olduğunda varsayılan başlatma değeri kullanılır. Zaten alışmış olduğumuz türlerin varsayılan değerlerini görmek için aşağıdaki tabloyu kullanabilirsiniz:
Veri Türü
Varsayılan Değer
Veri Türü
Varsayılan Değer
sbyte
0
float
0.0f
byte
0
double
0.0d
short
0
decimal
0.0m
ushort
0
bool
false
Int
0
char
'\u0000'
uint
0u
string
null
long
0L
object
null
ulong
0u
Değişkenleri bildirmek, onları başlatmak ve onlara değer atamayı aşağıdaki örnek ile özetleyelim:
// Declare and initialize some variables
byte centuries = 20;
ushort years = 2000;
decimal decimalPI = 3.141592653589793238m;
bool isEmpty = true;
char ch = 'a';
string firstName = "John"; ch = (char)5;
char secondChar; // Here we use an already initialized variable and reassign it
secondChar = ch;
2.5 Değer ve Referans Türleri C# dilinde iki çeşit veri türü vardır: Değer ve referans. Değer türleri program yürütme yığıtında saklanır ve doğrudan kendi değerini içerirler. Değer türleri arasında temel sayısal türler, karakter türü ve Boole türü vardır: sbyte, byte, short, ushort, int, long, ulong, float, double, decimal, char, bool. Program onların değer kümesini tutan erişimden çıktığında onlar için ayrılan bellek serbest bırakılır, yani tanımlandığı kod bloğu yürütmeyi tamamladığında. Örneğin programın Main() yöntemi ile bildirilen erim içinde tanımlanan bir değişken, program bu yöntemin yürütülmesini tamamlayıncaya kadar, yani sona erene kadar, yığıt içinde saklanır, (yani program Main() metotunu tamamen yürüttükten sonra C# programı sonlanıncaya kadar). Referans türleri program yürütme yığıtında, bir başvuru (adresi) tutar, ve onların bu referans noktaları dinamik bellekte (yığın) sakladıkları değeri işaret eder. Referans bir göstericidir (bellek biriminin adresi) ve yığıttaki değerin gerçek konumunu göstermektedir. Örnek olarak, yürütme yığıtındaki bir adreste depolanan değer 0x00AD4934 olarak verilebilir. Referansın bir türü vardır. Referans sadece aynı türden nesnelere işaret edebilir, yani türe koşulsuz zorlanmıştır. Tüm referans türleri bir null değeri tutabilir. Bunun anlamı “hiçbir değeri yok” olan özel bir hizmet değeridir. Referans türlerinin yaratılması için dinamik bellekte yer ayrılır. Program tarafından artık kullanılmayan bellek için (çöp toplayıcı) gibi bir bellek temizleyicisi, dinamik belleğin bir kısmını serbest bırakır. Belirli bir referans değişkeninin çöp toplayıcısı tarafından tam olarak ne zaman serbest bırakılacağı bilinmemektedir, çünkü bu bellek yükü ve diğer faktörlere bağlıdır. Belleğin ayrılması ve serbest bırakma işlemi yavaş olduğu için, referans türlerinin değer türlerine göre daha yavaş olduğu söylenebilir. Referans veri türleri program yürütme sırasında dinamik olarak tahsis edilip serbest bırakıldığı için boyutları önceden bilinmeyebilir. Örneğin, string türünde bir değişkenin uzunluğu farklı metin verisi içerebilir. Gerçekte string değişkeni metin değerinin adresini depolarken, string metin değeri dinamik bellekte saklanır ve farklı bir boyutu (bayt sayısını) kaplayabilir. Referans türleri, tüm sınıflar, diziler ve arayüzleri içeren şu türlerden oluşur: object, string, byte[]. Bu kitabın sonraki bölümlerinde sınıflar, nesneler, dizeler, diziler ve arayüzleri öğreneceksiniz. Şimdilik, değer türü olmayan tüm türlerin, referans türü olduğunu ve değerlerinin yığında (dinamik olarak ayrılan bellekte) saklandığını bilmek yeterlidir.
2.5.1 Değer ve Referans Türleri ve Bellek Bu örnekte değer ve referans türlerinin bellekte nasıl temsil edildiğini göstereceğiz. Aşağıdaki programlama kodunun çalıştırılmasını düşünün:
int i = 42;
char ch = 'A';
bool result = true;
object obj = 42;
string str = "Hello";
byte[] bytes = { 1, 2, 3 };
Bu noktada değişkenler bellekte aşağıdaki gibi yer almaktadır:
Şimdi değişkenlerin değerlerini değiştiren aşağıdaki kodu çalıştırırsak, değer ve referans türlerinin değiştirilmesiyle bellekte neler olduğu görülecektir:
i = 0;
ch = 'B';
result = false;
obj = null;
str = "Bye";
bytes[1] = 0;
Bu değişiklikler sonrasında, değişkenler ve değerleri bellekte aşağıdaki gibi bulunur:
Şekilden görebileceğiniz gibi, bir değer türüne yapılan (i = 0) değişiklik, onun yığıt içindeki değerini doğrudan değiştirir. Bir referans türünün değiştirilmesiyle farklı şeyler olur: Değer yığında (bytes[1] = 0) değiştirilir. Dizi referansını tutan değişken ise değişmeden (0x00190D11) kalır. Bir referans türüne null değer atanmasıyla, bu referansın değişken değeri ile olan bağlantısı kesilir ve değişken boş değerle (obj=null) kalır. Bir nesneye (bir referans türü değişkenine) yeni bir değer atanmasıyla yığında (dinamik bellekte) yeni nesneye bellek tahsis edilir, eski nesne serbest (unreferenced) kalır. Referans yeni nesneye yönlendirilir, (str= "Bye"), eski nesne ("Hello") artık kullanımda olmadığı için çöp toplayıcı (otomatik bellek temizlemek için .NET Framework iç sistemi) tarafından gelecek bir zamanda temizlenecektir.
2.6 Simgedeğerler Daha önce değindiğimiz temel türler, C# diline yerleşik özel veri türleridir. Programın kaynak kodunda belirtilen değerlerine simgedeğerler denir. Bir örnek konuyu daha net yapacaktır:
bool result = true;
char capitalC = 'C';
byte b = 100;
short s = 20000;
int i = 300000;
Yukarıdaki örnekte, simgedeğerler, true, ‘C’, 100, 20000 ve 300000 olarak belirlenmiştir. Onlar programın kaynak kodunda doğrudan ayarlanmış değişken değerleridir.
2.6.1 Simgedeğerlerin Türleri C # dilinde, simgedeğerlerin çeşitli türleri vardır:
Boole
Integer
Real
Character
String
Object simgedeğeri null
2.6.2 Boole Simgedeğerleri Boole simgedeğerleri aşağıdaki gibidir:
true
false
bool türü bir değişkene bir değer atadığınızda, sadece bu iki değerden birini veya (true veya false olarak hesaplanan) bir Boole ifadesini kullanabilirsiniz. 2.6.2.1 Boole Simgedeğerleri – Örnek bool türü bir değişkenin bildirimi ve true Boole simgedeğerini temsil eden bir değer atanmasına bir örnek aşağıda verilmiştir:
bool result = true;
2.6.3 Integer Simgedeğerleri Tamsayı simgedeğerleri bir dizi basamaktan oluşur: bir (+, -) işareti, önek ve sonekler. Önekleri kullanarak onluk veya onaltılık sayı tabanı biçimindeki tamsayıları program kaynak kodunda sunabiliriz. "Sayısal Sistemler" bölümünde farklı sayı sistemleri hakkında daha fazla bilgiyi bulacaksınız.Tamsayı simgedeğerlerinde aşağıdaki önek ve sonekler yer alabilir:
“0x” ve “OX” önekleri onaltılık değerleri gösterir, örneğin 0xA8F1 gibi;
‘l’ ve ‘L’ sonekleri long veri türlerini gösterir, örneğin 357L gibi;
‘u’ ve ‘U’ sonekleri uint ve ulong veri türlerini gösterir, örneğin 112u gibi.
Varsayılan olarak (sonek kullanılmazsa) tamsayı simgedeğerleri int türündedir.
2.6.3.1 Tamsayı Simgedeğerleri – Örnek Tamsayı simgedeğerlerini kullanmaya bazı örnekler aşağıda verilmiştir:
// The following variables are initialized with the same value
2.6.4 Gerçek Sayı Simgedeğerleri Gerçek simgedeğerleri bir dizi basamaktan oluşur: (+, -) işareti, sonekler ve ondalık nokta karakteri. float, double ve decimal türlerindeki değerler için bunları kullanıyoruz. Gerçek simgedeğerleri üssel formatta temsil edilebilir. Bunlar, aynı zamanda aşağıdaki gösterimleri kullanır:
‘f’ ve ‘F’ sonekleri float veri türü anlamında;
‘d’ ve ‘D’ sonekleri double veri türü anlamında;
‘m’ ve ‘M’ sonekleri decimal veri türü anlamında;
‘e’ bir üssü belirtir, örneğin, "e-5" tamsayı kısmının 10-5 ile çarpıldığı anlamına gelir.
Varsayılan olarak (hiçbir soneki yoksa), gerçek sayılar double türündedir. 2.6.4.1 Gerçek Sayı Simgedeğerleri – Örnekler Gerçek sayı simgedeğerlerinin kullanımı için bazı örnekler aşağıda verilmiştir:
// The following is the correct way of assigning a value:
float realNumber = 12.5f; // This is the same value in exponential format:
realNumber = 1.25e+1f; // The following causes an error, because 12.5 is double
float realNumber = 12.5;
2.6.5 Karakter Simgedeğerleri Karakter simgedeğerleri kesme işareti (tek tırnak) içine alınmış tek karakterden oluşur. char türündeki değerleri atamak için kullanılır. Bir karakter simgedeğeri aşağıdakilerden biri olabilir: