C# değişkenleri, programın verileri bellekte adlandırılmış kutularda tutmasını sağlar. Kutunun türünü saklayacağın verinin yapısı belirler: int tam sayı, double ondalıklı sayı, string metin, bool ise yalnızca true ya da false değeri içindir. Doğru türü seçmek için değerin ne anlama geldiğine bakman yeterlidir. Bu yazıda dört türü tanımlamayı, birbirine dönüştürmeyi ve en sık yapılan hataları küçük örneklerle göreceksin.
Dört tür, dört iş: Hangi veri hangi türe gider?
Değişken türü, yalnızca bellekte yer ayıran bir etiket değil, programın o değeri nasıl yorumlayacağını belirleyen sözleşmedir. Tür seçerken değere şu soruyu sor: "Bu değer neyi temsil ediyor?"
- Sayılabilen bir şey mi? Tam sayı olan her değer için
intkullan. Örnek: ders puanı, yaş, kitap sayısı. - Ölçülen ya da kesirli bir şey mi? Küsuratlı değerler için
doublekullan. Örnek: boy uzunluğu, sıcaklık, not ortalaması. - Metin mi? Harf ve karakter dizileri için
stringkullan. Örnek: öğrenci adı, e-posta adresi. - Evet/hayır durumu mu? İki durumdan birini taşıyan değer için
boolkullan. Örnek: kayıt durumu.
Telefon numarası ya da öğrenci numarası sayıya benzer, ama onlarla toplama ya da ortalama almazsın. Baştaki sıfırın korunması da gerekir. Bu yüzden böyle veriler string olarak saklanır. Para hesaplarında ise double yerine decimal türü bulunur; Microsoft dokümantasyonu parasal hesaplar için bu türü önerir. Burada ayrıntısına girmiyoruz.
int puan = 85;
double boy = 1.72;
string ad = "Elif";
bool kayitli = true;
Console.WriteLine(ad + " " + puan + " " + boy + " " + kayitli);
Her tür tek satırda tanımlandı. Çıktı Elif 85 1,72 True olur. Ondalık ayracı bilgisayarın bölge ayarına göre virgül ya da nokta görünebilir. bool değeri ekrana büyük harfle, True biçiminde yazılır.
Tanımlama, başlangıç değeri ve tür uyumu: int'e ondalıklı değer neden atanamaz?

Tanımlama üç parçadan oluşur: tür adı, değişken adı ve atama. int yas = 16; satırında int türü, yas adı, 16 ise başlangıç değeridir. Başlangıç değerini atlayıp değişkeni okumaya çalışırsan derleyici "atanmamış yerel değişken kullanıldı" anlamında bir hata verir (CS0165). Bu hata seni, rastgele bir değerle çalışan programdan korur.
Tür uyumsuzluğunu adım adım okuyalım:
int sayi = 3.5;
Derleyici CS0266 koduyla durur. Mesajın anlamı şudur: double türündeki değer int türüne örtük olarak dönüştürülemez, ama açık bir dönüştürme yazarsan olabilir. Sebebi basit. Yazdığın 3.5 değişmezi bir double değerdir. int küsurat taşıyamadığı için atama sırasında .5 sessizce kaybolurdu. Derleyici veri kaybını senin bilgin dışında yapmaz.
Üç çözüm yolu vardır:
double a = 3.5;
int b = (int)3.9;
int c = (int)Math.Round(3.9);
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Çıktı sırasıyla 3,5 (bölge ayarına göre 3.5), 3 ve 4 olur.
- Değişkeni double yapmak: Değer küsuratlıysa en doğru çözüm budur, hiçbir şey kaybolmaz.
- (int) dönüştürmesi: Küsuratı bilinçli olarak atar. 3.9 değeri 3 olur, yuvarlama yapılmaz.
- Math.Round: Değeri en yakın tam sayıya yuvarlar. Sonuç yine
doubletüründedir, bu yüzdenintdeğişkene atarken(int)yazman gerekir. Tam ortadaki değerlerde (2.5 gibi) varsayılan davranış en yakın çift sayıya yuvarlamaktır, yani sonuç 2 olur.
var anahtar sözcüğü türü ortadan kaldırmaz. Derleyici türü sağ taraftan çıkarır: var x = 5; bir int, var y = 3.5; bir double olur ve sonrasında türleri değişmez.
string birleştirme ve bool ile if: Metni ve kararı yönetmek
string değerleri iki yolla birleştirebilirsin: + operatörüyle ya da $"..." biçimindeki string enterpolasyonuyla. Parça sayısı arttıkça enterpolasyon daha okunaklıdır, çünkü değişkenleri süslü parantez içinde cümlenin içine yazarsın. Sayıyı metne eklediğinde sayı otomatik olarak metne çevrilir.
string ad = "Elif";
int puan = 85;
Console.WriteLine("Öğrenci: " + ad + ", puan: " + puan);
Console.WriteLine($"Öğrenci: {ad}, puan: {puan}");
Console.WriteLine("5" + "3");
Console.WriteLine(5 + 3);
İlk iki satır aynı çıktıyı verir: Öğrenci: Elif, puan: 85. Son iki satırda fark görünür: iki metin yan yana yazıldığı için "5" + "3" sonucu 53, iki sayı toplandığı için 5 + 3 sonucu 8 olur. + operatörü işlenenlerin türüne göre davranır.
bool değeri doğrudan atanabilir ya da >=, ==, != gibi karşılaştırma operatörleriyle üretilebilir. Üretilen değer if koşulunda kullanılır. && (ve) iki koşulun birlikte, || (veya) en az birinin doğru olmasını ister.
int puan = 72;
bool gectiMi = puan >= 50;
bool devamEdiyor = true;
if (gectiMi && devamEdiyor)
{
Console.WriteLine("Sınıfı geçti.");
}
else
{
Console.WriteLine("Tekrar gerekli.");
}
72 >= 50 doğru olduğu için gectiMi değeri true olur. İki koşul da sağlandığından çıktı Sınıfı geçti. şeklindedir. C#'ta bool değişkene 0 ya da 1 atanamaz; yalnızca true ve false kabul edilir.
Metinden sayıya çevirme: int.Parse mi, int.TryParse mi?
Console.ReadLine() ile konsoldan okunan her değer, kullanıcı 42 yazsa bile bir string olarak gelir. Toplama, ortalama ya da karşılaştırma yapmadan önce bu metni sayıya çevirmen gerekir. Bunun için iki yol var ve geçersiz girişte farklı davranırlar.
int.ParsedönüştüremezseFormatExceptionistisnası fırlatır; yakalamazsan program durur.int.TryParsebirbooldöndürür, dönüştürülen sayıyıoutparametresiyle verir ve hatalı girişte programı çökertmez.
Aynı hatalı girdiyle ikisini deneyelim:
int sayi = int.Parse("abc"); // FormatException: program burada durur
if (int.TryParse("abc", out int sonuc))
{
Console.WriteLine("Sayı: " + sonuc);
}
else
{
Console.WriteLine("Geçersiz giriş, lütfen bir sayı yaz.");
}
İlk satır çalıştığında istisna oluşur ve altındaki kodlara hiç ulaşılmaz. TryParse kullanan blok ise ekrana Geçersiz giriş, lütfen bir sayı yaz. yazar. Önceki bölümde gördüğün bool burada iş görüyor: TryParse'ın döndürdüğü true ya da false doğrudan if koşulu olur. Başarısız dönüşümde sonuc değişkeni 0 olur, bu yüzden değerine güvenmeden önce dönüş değerine bakmak gerekir.
Ondalık ayırıcı kültüre bağlıdır
Parse ve TryParse varsayılan olarak bilgisayarın geçerli kültür ayarını kullanır. Türkçe kültürde ondalık ayırıcı virgüldür (3,5), değişmez (invariant) kültürde nokta (3.5). Aynı metin farklı kültürlerde farklı sonuç verebilir: nokta, Türkçe kültürde binlik ayırıcı sayıldığından 3.5 beklenmedik bir değere dönüşebilir ya da dönüşüm başarısız olabilir. Sonucu ekrana yazarken de aynı kural geçerlidir: değer 83,33 ya da 83.33 görünebilir.
Girdinin biçimini sen belirlemek istiyorsan kültürü açıkça ver:
using System;
using System.Globalization;
class Program
{
static void Main()
{
string metin = "3.5";
if (double.TryParse(metin, NumberStyles.Float, CultureInfo.InvariantCulture, out double d))
{
Console.WriteLine(d + 1);
}
}
}
Bu kod 3.5 metnini nokta ayraçlı biçimde okur ve 4,5 değerini hesaplar. Ekranda Türkçe kültürde 4,5, invariant kültürde 4.5 görünür; çünkü yazdırma işlemi yine geçerli kültüre göre yapılır.
Kontrol listesi: Kullanıcıdan gelen veride TryParse tercih edilir; ondalık sayıda hangi ayırıcıyı beklediğine karar verip kültürü açıkça belirt.
Tamsayı bölmesi tuzağı: 7 / 2 neden 3 çıkar?

İki işlenen de int olduğunda C# sonucu da int olarak üretir ve küsuratı atar. Tamsayı bölmesi sonucu sıfıra doğru kırpar; yani yuvarlama yapmaz, ondalık kısmı keser (-7 / 2 de -3 verir).
Console.WriteLine(7 / 2); // iki işlenen de int
Console.WriteLine(7.0 / 2); // işlenenlerden biri double
Beklenen çıktı:
3
3,5
İkinci satır, Türkçe kültürde 3,5, invariant kültürde 3.5 yazar. Küsuratı korumanın üç yolu var:
- İşlenenlerden birini double yaz:
7.0 / 2. - Dönüştürme kullan:
(double)a / b. Buradaaönce double'a çevrilir, bölme ondan sonra yapılır. - Bölmeden önce bir double değişkene ata:
double x = a; x / b.
Sık yapılan hata şudur: double sonuc = 7 / 2; satırında sonuç yine 3 çıkar. Bölme iki int arasında yapılıp küsurat atıldıktan sonra 3 değeri double'a çevrilir; ekranda 3 görünür. Dönüştürme bölmeden önce gerçekleşmelidir. Bölmenin kalanını ise % operatörü verir: 7 % 2 sonucu 1'dir.
Mini proje: Puanlardan ortalama ve kayıt durumu hesaplayan konsol programı
Dört türü tek programda toplayalım: öğrenci adı string, üç ders puanı int, ortalama double, kayıt durumu bool. İlk akla gelen yazım şudur:
int ortalama = (p1 + p2 + p3) / 3;
Puanlar 80, 85 ve 85 ise toplam 250 olur, 250 / 3 tamsayı bölmesi olduğu için 83 çıkar; 83,33 değil. Düzeltme, paydayı 3.0 yapmaktır. Aşağıdaki program iki sürümü yan yana gösterir:
using System;
class Program
{
static void Main()
{
string ad = "Elif";
int p1 = 80;
int p2 = 85;
int p3 = 85;
int yanlisOrtalama = (p1 + p2 + p3) / 3;
Console.WriteLine("Yanlış ortalama: " + yanlisOrtalama);
double ortalama = (p1 + p2 + p3) / 3.0;
bool kayitAktif = ortalama >= 60;
Console.WriteLine(ad + " için ortalama: " + ortalama.ToString("F2"));
if (kayitAktif)
{
Console.WriteLine("Kayıt durumu: aktif");
}
else
{
Console.WriteLine("Kayıt durumu: ortalama yetersiz");
}
}
}
Beklenen çıktı (Türkçe kültürde):
Yanlış ortalama: 83
Elif için ortalama: 83,33
Kayıt durumu: aktif
ToString("F2") sayıyı virgülden sonra iki basamakla yazar. Böylece 83,3333333 gibi uzun bir çıktı yerine okunaklı bir değer görürsün. Biçimlendirme de kültüre duyarlıdır: aynı kod invariant kültürde 83.33 yazar. Puanları konsoldan almak istersen her girişi int.TryParse ile kontrol etmen yeterli; hatalı girişte else koluyla yeniden sorabilirsin.
Programda her türün işi ayrıdır: string adı taşır, int tam sayı puanları saklar, double küsuratlı ortalamayı tutar, bool ise if'in vereceği kararı tek bir true ya da false değerine indirir.
Pekiştirmek için kontrol listesi ve sonraki adım
Bir değişken yazmadan önce aşağıdaki altı soruyu sırayla sor. Her satır, yukarıdaki bölümlerde gördüğün bir tuzağa karşılık gelir.
- Bu değer gerçek dünyada neyi temsil ediyor: sayım, ölçüm, metin ya da evet/hayır durumu?
- Seçtiğim tür buna uyuyor mu? Sayım için
int, ölçüm içindouble, metin içinstring, durum içinbool. - Değişkene başlangıç değeri verdim mi?
- Kullanıcıdan gelen veriyi
TryParseile mi okuyorum, yoksa hatalı girişte programın çökmesine izin mi veriyorum? - Bölme işleminde en az bir işlenen
doublemı? Yoksa sonuç sessizce kırpılır. - Ondalık ayırıcı çalıştığım kültüre uygun mu? Türkçe ayarlı bir makinede kullanıcı
3,5yazabilir; kod içindeki sabitler ise her zaman noktayla yazılır.
Sık yapılan hataları da şöyle eşleyebilirsin:
- int'e ondalıklı değer atamak: değişkeni
doubleyap ya da dönüşümü bilerek, açıkça uygula. - 7 / 2 sonucunun 3 çıkması: işlenenlerden birini
7.0yap ya dadoubletürüne çevir. - Girişte FormatException almak:
ParseyerineTryParsekullan ve false dönerse kullanıcıdan yeniden değer iste. - Karşılaştırma yerine atama yazmak: koşulda
=değil==kullan.
Pekiştirmek için mini projedeki puan ortalaması programını yeniden yaz. Bu kez puan sayısını değiştir, geçme eşiğini farklı bir değere çek ve her seferinde kontrol listesini baştan geçir. Kod yazmadan önce adımları kâğıda dökmek de işe yarar. Bunu ölçmek istersen dilden bağımsız çalışan Algoritmik Düşünme Testi iyi bir ek pratik olabilir.
Sık Sorulan Sorular
double ile decimal arasında nasıl seçim yapılır?
Ölçüm, bilimsel hesap ve genel amaçlı ondalıklı işlemlerde double yeterli olur. Para gibi ondalık basamakların birebir korunması gereken hesaplarda decimal daha uygundur. double değerleri ikili düzende tuttuğu için 0.1 + 0.2 gibi toplamlar beklediğin sayıdan çok küçük bir farkla sapabilir. decimal sabitleri sayının sonuna m eklenerek yazılır, örneğin 19.99m.
var kullanırsam değişkenin türü kaybolur mu?
Kaybolmaz. var kullandığında tür, atadığın değerden derleme sırasında belirlenir ve sonradan değişmez. var sayi = 5; yazdığında değişken int olur, ona sonradan metin atayamazsın. Sağ taraftan türün açıkça anlaşıldığı yerlerde işe yarar. Başlangıçta türleri açık yazmak, her değişkenin ne tuttuğunu öğrenmeni kolaylaştırır.
bool değişkene 0 veya 1 atayabilir miyim?
Hayır. C# dilinde bool yalnızca true ya da false değerini alır; sayıdan bool'a örtük dönüşüm yoktur. Bir sayının sıfırdan farklı olup olmadığını öğrenmek istiyorsan bool varMi = adet != 0; gibi açık bir karşılaştırma yazarsın.
Dört temel türü doğru seçmek, hataların büyük kısmını daha kod çalışmadan önlemeni sağlar. Kontrol listesini her yeni programın başında kısa bir alışkanlık olarak kullan, kalan ayrıntılar pratikle yerine oturur.