C/C++ Programlama Dillerindeki Diziler ve Önemli Hususlar

Diziler aynı türden birden fazla elemanı taşımak için kullanılan veri yapılarıdır. Elemanları bellekte ardışık olarak tutulur. Uzunlukları sabittir fakat uzunluklarının belirlenme zamanı değişkenlik gösterebilir. Çalışma anında veya derlenme anında dizilerin uzunlukları belirlenebilir. Birkez belirlendikten sonra uzunlukları değişmez. Diziyi genişletmenin yegane yolu, genişletilmek istenen yeni kapasite kadar yeni bir dizi oluşturup elemanları teker teker kopyalamaktan geçer. C/C++ dilleri için karakter dizileri hariç dizilerin uzunlukları bulunamaz dolayısıyla dizi üzerinde bir işlem yapılacaksa uzunluk yanında verilmelidir. Dizilerin elemanlarına erişim anlıktır. 1. Elemanına erişim süresi ile 10000. elemanına erişim süresi aynıdır. Bunu ilk elemanın adresini tutarak gerçekleştirmektedir. Verilen indekse erişmek için bir çarpma ve bir toplama yapılması yeterlidir. Diziler ilk elemanın adresini tutarak erişildikleri için aşağıdaki atama geçerlidir.

int sayilar[]={2, 56, 42};
int *p=sayilar;
cout<<*p;

p ilk elemanın adresi göstereceği için ekrana yazdırıldığında 2 sayısını yazacaktır. Yukarıdaki örnekte uzunluk 3’tür ve devamında değiştirilemez. Bu derlenme anında dizinin uzunluğunun belirlenen koda örnektir. Aşağıda ise çalışma anında dizinin uzunluğu belirlenip dizi elemanları sıfırlanmaktadır. Uzunluğu kullanıcı belirlemektedir.

int uzunluk;
cout<<"Dizi Uzunlugu:"; cin>>uzunluk;
int sayilar[uzunluk];
for(int i=0;i<uzunluk;i++){
	sayilar[i]=0;
}

Burada dizi bir blok içinde tanımlandığı için lokal dizidir ve çalışma anı yığını bellek bölgesinde tutulur. Lokal dizilerle uğraşırken dikkatli olunmalıdır çünkü lokal bölge kapandığı gibi dizi yok edilir. Örneğin aşağıdaki koda bakıldığında DiziOlusturSifirla metodu girilen uzunluk değeri kadar bir diziyi oluşturup sıfırlayıp döndürmek istemektedir. Fakat kaçırılan nokta dizinin lokal bir dizi olup metot bittiğinde yok edileceğidir. Bu kod derlendiğinde bunu size uyarı olarak verir fakat kodu derler. Çalıştırdığınızda p dizisi aslında artık yoktur ve 1. İndeksine erişilemeyecek ve hata verecektir.

int* DiziOlusturSifirla(int uzunluk){
	int sayilar[uzunluk];
	for(int i=0;i<uzunluk;i++){
		sayilar[i]=0;
	}
	return sayilar;

}	

int main(){
	int uzunluk;
	cout<<"Dizi Uzunlugu:"; cin>>uzunluk;
	int *p = DiziOlusturSifirla(uzunluk);
	cout<<p[1];
	return 0;
}

Bunu gerçekleştirebilmek için yok edilmesi programcıya ait olan Heap bellek bölgesinde dizinin oluşturulması gerekmektedir. Doğru kod aşağıda verilmiştir.

int* DiziOlusturSifirla(int uzunluk){
	int *sayilar = new int[uzunluk];
	for(int i=0;i<uzunluk;i++){
		sayilar[i]=0;
	}

	return sayilar;	
}	

int main(){
	int uzunluk;
	cout<<"Dizi Uzunlugu:"; cin>>uzunluk;
	int *p = DiziOlusturSifirla(uzunluk);
	cout<<p[1];
	delete p;
	return 0;
}

Yine çok fazla gözden kaçırılan kısım mesala aşağıdaki gibi bir Kisi nesnelerinden oluşan bir dizi tanımlandığında aslında 10 adet kisi nesnesi oluşmaktadır. Fakat Kisi sınıfına bakıldığında parametre almadan çağrılabilecek bir yapıcı fonksiyon olmadığı için derlenme anında hata verecektir.

class Kisi{
	private:
		string isim;
		int yas;
	public:
		Kisi(string ism){
			isim=ism;
			yas=0;
		}
};

int main(){
	Kisi kisiler[10];
	return 0;

}

Bu hatayı giderebilmek için varsayılan bir yapıcı fonksiyon sınıfa eklenmelidir. Parametre almadığı durumda nesnenin nasıl oluşması gerektiğini gösteren bir yapıcı metot aşağıda sınıfa eklenmiştir.

class Kisi{
	private:
		string isim;
		int yas;

	public:
		Kisi(string ism){
			isim=ism;
			yas=0;
		}
		Kisi(){
			isim="";
			yas=0;
		}
};

C dilinde C++’ın aksine string tarzında bir tür yoktur. Karakter göstericisi (char*) şeklinde temsil edilirler. Yani aslında karakter dizisi şeklinde tutulmaktadırlar. Yazımızın başında dizilerin ilk elemanın adresi şeklinde tutulduklarını belirtmiştik dolayısıyla karakter dizisi bir char* ‘a atanabilir. Yine ilk kod örneğimizde *p ekrana yazdırdığımızda, ekrana 2 yazmıştı, karakter dizilerinde aşağıdaki örnekte de görünebileceği gibi aynı kullanım bir karakteri ekrana yazdıracaktır. Fakat karakter dizilerine has bir şekilde yıldız kullanılmadığında bütün bir string’i ekrana yazar. Peki nereye kadar yazacağını nasıl bilmektedir. Bu dizinin uzunluğunu bilmeyi gerektirir. Aslında dizinin uzunluğunu bilmek yerine sonuna dizinin bittiğini ifade eden ‘\0’ karakteri yerleştirilir. Böylelikle bu karakteri okuyana kadar ekrana yazacaktır.

int main(){
	char* str = "Kelaynak";
	cout<<*str<<endl; // sadece K harfini yazar
	cout<<str;   // Bütün bir string'i ekrana yazar.
	return 0;
}
Dolayısıyla ‘\0’ karakter kullanılarak bir karakter dizisinin uzunluğu bulunabilir. Aşağıda bunu bulan fonksiyon verilmiştir.
int Uzunluk(char *str){
	int u=0;
	for(int i=0;str[i] != '\0';i++) u++;
	return u;
}
Dizi atamaları, bir değişkenin ataması kadar kolay değildir. Örneğin aşağıdaki kod hatalıdır ve derlenmez.
int a[]={3,7,9};
int b[3];
b=a;

Böyle bir işlem ancak elemanların bir bir kopyalanması ile gerçekleşebilir. Aşağıdaki örnek yukarıda yapılmak isteneni doğru bir şekilde yapacaktır.

int a[]={3,7,9};
int b[3];
for(int i=0;i<3;i++) b[i]=a[i];

Yine dizi karşılaştırmasında aşağıdaki gibi bir karşılaştırma sadece ilk elemanlarının adreslerinin karşılaştırıldığı bir işlem olacaktır. Farklı iki dizinin ilk adresleri farklı olacağı için ekrana diziler eşit değil ifadesi yazacaktır.

int a[]={3,7,9};
int b[]={3,7,9};
if(a == b) cout<<"diziler esit";
else cout<<"diziler esit degil";

Doğrusu ise tüm elemanların karşılaştırılmasından sonra yapılabilir. Bu işlem bir fonksiyona verilecek olursa aşağıdaki gibi bir kod yazılabilir.

bool Esitmi(int d1[],int d2[],int u1,int u2){
	if(u1 != u2) return false;
	for(int i=0;i<u1;i++){
		if(d1[i] != d2[i]) return false;
	}
	return true;	
}

int main(){
	int a[]={3,7,9};
	int b[]={3,7,9};

	if(Esitmi(a,b,3,3)) cout<<"diziler esit";
	else cout<<"diziler esit degil";
	return 0;
}

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir