C# programlama dilinin temel taşlarından biri olan değişkenler ve veri tipleri, uygulamalarımızın yapı taşıdır. Bu yazımda, .NET Framework 4 çatısı altında C# dilinde değişkenlerin ne anlama geldiğini, hangi temel veri tiplerini desteklediğini ve bu tiplerin bellek yönetimiyle ilişkisini detaylı bir şekilde inceleyeceğiz.
Değişken Kavramı
Tıpkı matematikteki değişkenler gibi, C#'taki
değişkenler de programımızın yürütülmesi sırasında değerleri saklamak için
kullandığımız isimlendirilmiş bellek alanlarıdır. Bir değişken
tanımladığımızda, bellekte belirli bir boyutta bir yer ayrılır ve bu alana
atadığımız değer, değişkenin o anki içeriğini oluşturur. Bu değer, programın
akışı içerisinde değişebilir, bu yüzden "değişken" adını alır.
Veri Tiplerinin
Sınıflandırılması
C#'ta veri tipleri temel olarak iki ana kategoriye
ayrılır: basit (değer) tipler ve karmaşık (referans) tipler. Bu
ayrım, verilerin bellekte nasıl saklandığı ve işlendiği açısından kritik bir
öneme sahiptir.
Basit (Değer) Tipler
Değer tipleri, değişkenin doğrudan değerini içerir ve
bu değer belleğin Stack adı verilen bölgesinde saklanır. Bir değer
tipindeki değişkeni başka bir değişkene atadığımızda, değerin bir kopyası
oluşturulur. Bu nedenle, kopyalanan değişkendeki bir değişiklik, orijinal
değişkeni etkilemez.
Basit tipler kendi içinde de alt kategorilere ayrılır:
- Sayısal Tipler: Tam sayıları (byte,
short, int, long, sbyte, ushort, uint, ulong) ve ondalıklı sayıları
(float, double, decimal) içerir.
- Karakter Tipi: Tek bir Unicode
karakterini temsil eden char tipidir.
- Mantıksal Tip: true veya false
olmak üzere iki değer alabilen bool tipidir.
- Yapısal Tipler (Struct): Birden
fazla farklı tipteki değişkeni bir arada tutabilen değer tipleridir.
- Numaralandırma Tipleri (Enum):
Adlandırılmış sabit değerler kümesini tanımlamak için kullanılır.
Karmaşık (Referans)
Tipler
Referans tipleri ise değişkenin doğrudan değerini
değil, değerin bellekteki adresini (referansını) saklar. Bu değerler genellikle
belleğin Heap adı verilen bölgesinde tutulur. Bir referans tipindeki
değişkeni başka bir değişkene atadığımızda, aslında değerin kopyası değil, aynı
bellek adresini işaret eden bir referans kopyalanır. Bu durumda, her iki
değişken de aynı bellek alanını gösterdiği için, birinde yapılan değişiklik
diğerini de etkiler.
Referans tiplerine örnek olarak şunları verebiliriz:
- Sınıflar (Class): Nesne yönelimli
programlamanın temelini oluşturan yapılardır.
- Arayüzler (Interface): Sınıfların
uygulaması gereken bir sözleşmeyi tanımlar.
- Diziler (Array): Aynı türden birden
fazla öğeyi sıralı bir şekilde saklamak için kullanılır.
- Dizeler (String): Metinsel verileri
temsil eder.
- Nesne Tipi (Object): Tüm diğer
tiplerin temel sınıfıdır ve herhangi bir türden değeri alabilir.
- Dinamik Tip (Dynamic): Derleme
zamanında tür kontrolü yapılmayan bir tiptir.
Bellek Yönetimi Açısından Farklar:
Değer tipleri Stack'te hızlı bir şekilde oluşturulup
yok edilirken, referans tipleri Heap'te daha karmaşık bir bellek yönetimi
sürecine tabidir. Heap üzerindeki nesnelerin ne zaman serbest bırakılacağını
.NET'in otomatik bellek yönetimi (Garbage Collection) mekanizması belirler.
Heap üzerindeki işlemleri Stack üzerindeki işlemlere göre daha yavaş olması da
bu karmaşık yapıdan kaynaklanır.
Temel Değer ve Referans
Tipleri
Aşağıda C# .NET Framework 4'te en sık kullanılan değer
ve referans tiplerinin bir listesi ve kısa açıklamaları bulunmaktadır:
Değer Tipleri:
Tür |
.NET Yolu |
Açıklama |
bool |
System.Boolean |
true veya
false değerlerini alır. |
byte |
System.Byte |
0 ile 255
arasında işaretsiz tam sayı değerlerini alır. |
sbyte |
System.SByte |
-128 ile
127 arasında işaretli tam sayı değerlerini alır. |
char |
System.Char |
Tek bir
Unicode karakterini temsil eder (0 ile 65535 arası tam sayı). |
decimal |
System.Decimal |
Yüksek
duyarlıklı ondalık sayıları temsil eder (finansal işlemler için ideal). |
double |
System.Double |
Çift
duyarlıklı kayan noktalı sayıları temsil eder. |
float |
System.Single |
Tek
duyarlıklı kayan noktalı sayıları temsil eder. |
int |
System.Int32 |
-2,147,483,648
ile 2,147,483,647 arasında işaretli tam sayıları alır. |
uint |
System.UInt32 |
0 ile
4,294,967,295 arasında işaretsiz tam sayıları alır. |
long |
System.Int64 |
-9 x 10¹⁸
ile 9 x 10¹⁸ arasında işaretli tam sayıları alır. |
ulong |
System.UInt64 |
0 ile 18 x
10¹⁸ arasında işaretsiz tam sayıları alır. |
short |
System.Int16 |
-32,768
ile 32,767 arasında işaretli tam sayıları alır. |
ushort |
System.UInt16 |
0 ile
65,535 arasında işaretsiz tam sayıları alır. |
enum |
System.Enum |
Adlandırılmış
sabit değerler kümesini tanımlar. |
struct |
System.ValueType |
Birden
fazla farklı tipteki değişkeni bir arada tutan yapısal tiptir. |
Referans Tipleri:
Tür |
.NET Yolu |
Açıklama |
string |
System.String |
Metinsel
verileri temsil eder. |
class |
System.Object |
Nesnelerin
oluşturulduğu temel yapıdır. |
object |
System.Object |
Tüm diğer
tiplerin temel sınıfıdır, herhangi bir türden değeri alabilir. |
array |
System.Array |
Aynı
türden birden fazla öğeyi sıralı bir şekilde saklar. |
interface |
System.Interface |
Sınıfların
uygulaması gereken bir sözleşmeyi tanımlar. |
delegate |
System.Delegate |
Metotlara
referans tutmak için kullanılır. |
Önemli Not: object tipi, tüm diğer
tiplerin atasıdır. Bu, herhangi bir türdeki bir değeri bir object türündeki
değişkene atayabileceğimiz anlamına gelir.
Değişken Tanımlama
Kuralları
C#'ta değişken tanımlarken uymamız gereken bazı
kurallar vardır:
- Değişken isimleri Türkçe karakter içeremez.
- C#'a özgü anahtar kelimeler (örneğin if, else, for, foreach,
while, switch, do vb.) değişken adı olarak kullanılamaz.
- Değişken isimleri bir sayı ile başlayamaz.
- Değişken isimleri arasında boşluk olamaz (ayrı iki kelime
şeklinde yazılamaz).
Ancak, değişken isimlerinde şunlara izin verilir:
- Harfler (a-z, A-Z)
- Rakamlar (0-9)
- Alt çizgi (_)
Unutmayın: C# büyük-küçük harf
duyarlı bir dildir. Bu nedenle degiskenAdi ve DegiskenAdi farklı
değişkenlerdir.
Değişken Tanımlama Söz
Dizimi
Bir değişkeni tanımlamanın temel söz dizimi şöyledir:
veriTipi değişkenAdı = değişkenDeğeri;
Örneğin:
string mesaj = "Merhaba Dünya!";
int sayi = 10;
bool aktifMi = true;
double piSayisi = 3.14;
Değişken İsimlendirme
Konvansiyonları
Kodun okunabilirliğini artırmak için yaygın olarak
kullanılan bazı değişken isimlendirme konvansiyonları vardır:
- Pascal Case (DegiskenAdi): Her
kelimenin ilk harfi büyük yazılır. Genellikle sınıf, metot ve özellik
isimlerinde kullanılır.
- Camel Case (degiskenAdi): İlk
kelimenin ilk harfi küçük, sonraki her kelimenin ilk harfi büyük yazılır.
Genellikle yerel değişken isimlerinde kullanılır.
- Underscore Case (degisken_adi): Kelimeler
alt çizgi ile ayrılır ve genellikle tamamı küçük harflerle yazılır. Bazı
durumlarda (özellikle özel alanlarda) kullanılabilir.
Global ve Yerel
Değişkenler
Değişkenlerin erişilebilirlik kapsamı (scope), nerede
tanımlandıklarına bağlıdır:
- Yerel Değişkenler (Local Variables): Bir metot
(method) veya bir kod bloğu içinde tanımlanan değişkenlerdir. Bu
değişkenlere yalnızca tanımlandıkları metot veya blok içinden
erişilebilir. Bir kod bloğunun işlevi sona erdiğinde, o blok için ayrılan
bellek alanı serbest bırakılır ve bu değişkenlere dışarıdan erişim mümkün
olmaz. Yerel değişkenlere bir değer atanması zorunludur.
- Global Değişkenler (Global Variables) / Alanlar (Fields): Bir sınıf (class) seviyesinde, metotların dışında tanımlanan
değişkenlerdir. Bu değişkenlere, tanımlandıkları sınıfın tüm metotlarından
erişilebilir. Global değişkenlere başlangıçta bir değer atanmayabilir; bu
durumda varsayılan bir değere sahip olurlar (sayısal tipler için 0,
boolean için false, referans tipler için null gibi).
Basit Veri Tipleri ve
Detaylı Açıklamaları
Aşağıdaki tabloda basit veri tiplerinin .NET
üzerindeki karşılıkları ve detaylı açıklamaları yer almaktadır:
Tür |
.NET Yolu |
Açıklama |
bool |
System.Boolean |
Mantıksal
değerleri (doğru/yanlış) temsil eder. Program akışını kontrol etmek için
sıklıkla kullanılır. |
byte |
System.Byte |
0 ile 255
arasındaki işaretsiz 8-bit tamsayıları temsil eder. Genellikle ikili veri
işlemleri için kullanılır. |
sbyte |
System.SByte |
-128 ile
127 arasındaki işaretli 8-bit tamsayıları temsil eder. |
char |
System.Char |
Tek bir
Unicode karakterini (16-bit) temsil eder. Metin manipülasyonu ve karakter
tabanlı işlemler için kullanılır. Tek tırnak içinde tanımlanır ('a', 'W', '3'
gibi). Tam sayı karşılığı 0 ile 65535 arasındadır. |
decimal |
System.Decimal |
128-bitlik
yüksek duyarlıklı ondalık sayıları temsil eder. Finansal ve parasal işlemler
için kayıpsız hesaplama imkanı sunar. Değerin sonuna m veya M eklenerek
belirtilir (örneğin, 3.14m). |
double |
System.Double |
64-bitlik
çift duyarlıklı kayan noktalı sayıları temsil eder. Bilimsel ve mühendislik
hesaplamalarında yaygın olarak kullanılır. Ondalıklı değerler varsayılan
olarak double kabul edilir (örneğin, 3.14). |
float |
System.Single |
32-bitlik
tek duyarlıklı kayan noktalı sayıları temsil eder. Daha az bellek kullanır
ancak double kadar hassas değildir. Değerin sonuna f veya F eklenerek
belirtilir (örneğin, 3.14f). |
int |
System.Int32 |
32-bitlik
işaretli tamsayıları temsil eder. En sık kullanılan tam sayı tipidir. |
uint |
System.UInt32 |
32-bitlik
işaretsiz tamsayıları temsil eder (0 ve pozitif değerler). |
long |
System.Int64 |
64-bitlik
işaretli tamsayıları temsil eder. Çok büyük veya çok küçük tam sayı değerlerini
saklamak için kullanılır. Değerin sonuna L veya l eklenerek belirtilir
(örneğin, 100L). |
ulong |
System.UInt64 |
64-bitlik
işaretsiz tamsayıları temsil eder (0 ve çok büyük pozitif değerler). Değerin
sonuna UL veya ul eklenerek belirtilir (örneğin, 100UL). |
short |
System.Int16 |
16-bitlik
işaretli tamsayıları temsil eder. int kadar büyük değerlere ihtiyaç
duyulmayan durumlarda bellek tasarrufu sağlar. |
ushort |
System.UInt16 |
16-bitlik
işaretsiz tamsayıları temsil eder (0 ile 65,535 arası). |
string |
System.String |
Unicode
karakter dizilerini (metinleri) temsil eden bir referans tipidir. Çift tırnak
içinde tanımlanır ("Merhaba", "C#"). |
Ayrıca, datetime (tarih ve saat bilgisi), object (tüm
tiplerin atası) ve kullanıcı tanımlı class tipleri de sıkça kullanılan referans
tiplerindendir.
String Kaçış Karakterleri
string ifadeleri içinde özel anlamları olan bazı kaçış
karakterleri kullanılır:
Kaçış
Karakteri |
Üretilen
Değer |
Unicode
Karşılığı |
\' |
Tek tırnak |
0x0027 |
\" |
Çift
tırnak |
0x0022 |
\\ |
Sola eğik
çizgi |
0x005C |
\b |
Geri al
(Backspace) |
0x0008 |
\n |
Yeni satır |
0x000A |
\r |
Satır başı |
0x000D |
\t |
Sekme
(Tab) |
0x0009 |
\a |
Zil sesi
(Alert) |
|
\f |
Form
besleme |
|
\v |
Dikey
sekme |
|
\? |
Soru
işareti |
|
\xhh.. |
16'lık
karakter |
|
\uhhhh |
Unicode
karakter |
|
Ayrıca, @ sembolü ile başlayan string literal'leri (verbatim
string literals) kaçış karakterlerini yorumlamaz. Bu özellikle dosya
yolları gibi ters eğik çizgi (\) içeren metinleri tanımlarken oldukça
kullanışlıdır. Normal bir string literal'inde ters eğik çizgiyi kullanmak için
çift ters eğik çizgi (\\) yazmanız gerekirken, verbatim string literal'lerinde
tek ters eğik çizgi yeterlidir.
Verbatim String Literal Örneği:
string dosyaYoluNormal = "C:\\Users\\Kullanici\\Belgeler\\dosya.txt";
string dosyaYoluVerbatim = @"C:\Users\Kullanici\Belgeler\dosya.txt";
Console.WriteLine(dosyaYoluNormal); // Çıktı: C:\Users\Kullanici\Belgeler\dosya.txt
Console.WriteLine(dosyaYoluVerbatim); // Çıktı: C:\Users\Kullanici\Belgeler\dosya.txt
string cokSatirliMetin = @"Bu bir
çok satırlı
metindir.";
Console.WriteLine(cokSatirliMetin);
/* Çıktı:
Bu bir
çok satırlı
metindir.
*/
Gördüğünüz gibi, @ sembolü ile başlayan string literal'lerinde
ters eğik çizgiler özel bir anlam taşımaz ve olduğu gibi kabul edilir. Ayrıca,
verbatim string literal'leri birden fazla satıra yayılan metinleri tanımlamak
için de kolaylık sağlar.
var Anahtar Kelimesi (Implicitly Typed Local
Variables): C# 3.0 ile gelen var anahtar kelimesi, yerel
değişkenleri tanımlarken türü açıkça belirtme zorunluluğunu ortadan kaldırır.
Derleyici, değişkene atanan ilk değere göre türü otomatik olarak çıkarır. Bu,
kodun daha kısa ve okunabilir olmasına yardımcı olabilir. Ancak, tür çıkarımı
sadece yerel değişkenler için geçerlidir ve değişken tanımlanırken mutlaka bir
başlangıç değeri atanmalıdır.
var sayi = 10; // Derleyici 'sayi' değişkeninin türünü 'int' olarak çıkarır.
var mesaj = "Merhaba"; // Derleyici 'mesaj' değişkeninin türünü 'string' olarak çıkarır.
var pi = 3.14; // Derleyici 'pi' değişkeninin türünü 'double' olarak çıkarır.
dynamic Anahtar Kelimesi: .NET Framework 4.0 ile gelen dynamic anahtar kelimesi, tür denetimini
derleme zamanından çalışma zamanına erteler. Bu, özellikle COM nesneleri veya
dinamik dillerle etkileşim kurarken faydalı olabilir. Ancak, dynamic tipinin
aşırı kullanımı, çalışma zamanında hatalara yol açabileceği için dikkatli
olunmalıdır.
dynamic degisken = 10;
Console.WriteLine(degisken.GetType()); // Çıktı: System.Int32
degisken = "Merhaba";
Console.WriteLine(degisken.GetType()); // Çıktı: System.String
// degisken.OlmayanMetot(); // Çalışma zamanında hata oluşur.
Nullable Değer Tipleri: Değer tipleri normalde null değerini alamazlar. Ancak, bazı durumlarda bir
değer tipinin "değer atanmamış" durumunu temsil etmek gerekebilir. Bu
durumda, soru işareti (?) kullanılarak nullable değer tipleri tanımlanabilir.
int? nullableInt = null;
double? nullableDouble = 3.14;
if (nullableInt.HasValue)
{
Console.WriteLine($"nullableInt değeri: {nullableInt.Value}");
}
else
{
Console.WriteLine("nullableInt değeri atanmamış.");
}
Tuple'lar (Değer Demetleri): .NET Framework 4.0 ile gelen Tuple sınıfları (ve sonraki C# sürümlerinde
daha basitleştirilmiş söz dizimi), farklı türlerdeki birden fazla değeri tek
bir veri yapısında gruplandırmak için kullanılır. Özellikle metotlardan birden
fazla değer döndürmek gerektiğinde kullanışlıdırlar.
var kisi = Tuple.Create("Ali", 30);
Console.WriteLine($"Adı: {kisi.Item1}, Yaşı: {kisi.Item2}"); // .NET 4.0 için kullanım
Evet sevgili Webkolog.net takipçileri, bu yazımızda C#
.NET Framework 4 dünyasına adım atarken karşımıza çıkan en temel yapı
taşlarından olan değişkenleri ve veri tiplerini derinlemesine inceledik.
Değişkenlerin ne olduğunu, temel veri tiplerini, değer ve referans tiplerinin
arasındaki farkları ve bellek yönetimini anlamak, sağlam temeller üzerine
kurulu uygulamalar geliştirmek için kritik öneme sahip.
Unutmayın ki her bir veri tipinin kendine özgü
kullanım alanları ve sınırları vardır. Uygulamanızın ihtiyaçlarına en uygun
veri tipini seçmek, hem performans hem de kodun doğruluğu açısından büyük önem
taşır.
Umarım bu kapsamlı rehber, C# yolculuğunuzda size ışık
tutmuş ve değişkenler ile veri tipleri konusundaki merakınızı gidermiştir. Bir
sonraki yazımızda, bu temel bilgileri kullanarak daha karmaşık konulara doğru
ilerleyeceğiz.
Webkolog'u takipte kalın!
Kod dolu günler dilerim!
0 yorum:
Yorum Gönder