28 Aralık 2011 Çarşamba

C# ile Değişkenler ve Veri Tipleri

 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