|
Microsoft Visual C++ .Net ile Diziler ve Topluluklar |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu yazıda giriş düzeyinde Diziler ve Topluluklara göz atıcaz.
Dizilerin üzerindeki hafıza yönetimi, Frameworkdeki dizi çeşitleri ve
bunların yönetilmesi yazı içeriğinde bulabileceğiniz başlıklar.
Bu yazıda dizileri 3 başlık altında toplayıp ele alıcaz. Bunlar
- Yerel Diziler (Native Arrays)
- Sistem Dizileri (System Arrays)
- Topluluklar (Collections)
1. Yerel Diziler (
Native Arrays ):
Yerel diziler "Garbage
Collector" tarafından takip edilmeyen değişkenlerdir. Bunlar sabit
eleman sayısına sahip olan değer tipindeki diziler olabilir veya bir
işaretçiye bağlı olarak eleman sayısının ihtiyaca göre ayarlandığı
referans tipi diziler de olabilir. Yerel dizilerin hafıza yönetiminden
bağımsız olması programcı için ayrılan hafızanın takibini zorunlu
kılmaktadır. Buna karşın hafıza yönetiminden bağımsız olması bu
dizileri performans bakımından daha güçlü kılmaktadır.
Aşağıda değer tipindeki sabit eleman sayısı bulunan bir dizi örneği
görebilirsiniz.
// valueTypeArrays.cpp
#include
"stdafx.h"
#include "stdlib.h"
#using
<mscorlib.dll>
using namespace
System;
#define SIZE 10
int main(void)
{
int
arr[SIZE];
for(int
i = 0; i < SIZE; i++) arr[i] = rand();
size_t size = sizeof arr /
sizeof arr[0]; //
dizinin tüm boyutu / bir elemanın boyutu bize
uzunluğu verir
for(size_t j
= 0; j < size; j++) Console::WriteLine(arr[j]);
return 0;
} |
Burda dikkat edilmesi gereken konu eğer son döngüyü
aşağıdaki gibi değiştirirseniz ekranda alakasız rakkamlar
görebilirsiniz; bunlar kesinlikle size ait olmayan bir belleğin
görüntüleridir. Bu yüzden değer veya referans tipindeki diziler ile
çalışırken sınırlar konusunda dikkatli olmalısınız.
for(size_t j = 0; j < 13; j++)
Console::WriteLine(arr[j]);
Aşağıdaki örnekte
ise referans tipinde integer cinsinden bir işaretçiye kullanıcının belirticeği büyüklükte
hafıza alanını malloc (memmory allocation) ile tahsis ediyoruz.
Ardından kullanıcının belirttiği eleman sayısının iki fazlasını
realloc ( re-memmory allocation) ile yeniden yapılandırıyoruz.
// refTypeArrays.cpp
#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"
#using
<mscorlib.dll>
using namespace
System;
int main(void)
{
int number;
int *ptr;
Console::WriteLine("Dizi eleman sayısı ?");
number = Convert::ToInt32(Console::ReadLine());
ptr = (int*)(malloc(number*sizeof(int)));
/* hafızadan yer ayrılır dönen hafıza bloğunun ilk
adresi integer cinsinden işaretçiye atanır */
if(ptr!=NULL)
/* Eğer malloc gerekli
hafıza bloğunu ayıramaz ise NULL döndürür */
{
for(int
i=0 ; i<number ; i++) *(ptr+i) = i;
/* Dizinin içi doldurulur
*/
size_t size = _msize( ptr ) / sizeof
ptr[0]; /* Dizinin
uzunluğunu tespit edilir */
for(size_t
i = 0; i < size; i++)
Console::WriteLine(ptr[i]);
ptr = (int*)(realloc(ptr,
(number+2)*sizeof(int)));
/* Hafıza bloğu yeniden
düzenlenir */
Console::Write("\nGirilen Eleman Sayısı: ");
Console::WriteLine(number);
Console::Write("Yeni Eleman Sayısı: ");
Console::WriteLine(_msize( ptr ) / sizeof ptr[0]);
free(ptr); /* realloc(ptr,0) da free
ile aynı işlevi görmekte */
}
else
{
printf("Hafızada yer ayrılamadı!\n");
// stdio.h kütühanesini eklediğimiz için printf
kullanabiliriz.
}
return 0;
} |
Bir önceki örnekte olduğu gibi dizinin boyutunu
sizeof operatörünü kullanarak
belirledik fakat birde _msize fonksiyonu görüyorsunuz. Kullanmamızın
nedeni ptr nin kendisi bir işaretçi olduğundan
sizeof operatörü ptrnin kapladığı
alanı döndürmekte buda bir integerın boyutuna eşit; fakat isteğimiz
ptrnin adresini tuttuğu dizinin boyutunu öğrenmek bunun için _msize
fonksiyonunu kullandık.
2.
Sistem Dizileri
( System Arrays ):
Esasında bu dizilere
nasıl hitap etmek gerektiğini tam çıkaramadım fakat bu dizilerin
System::Array den türüdeğini göze alarak sistem dizileri demek
sanırım yanlış olmayacak.
Ama internet üzerinde "Managed Arrays" olarak karşınıza çıkabilir.
Aşağıdaki örnekte sistem dizilerinden bir örnek
yaratıp içine rasgele sayılar yerleştirip ardından genişletmek için
yeni bir diziye kopyalamayı görücez.
// gcArrays.cpp
#include "stdafx.h"
#include "stdlib.h"
#using
<mscorlib.dll>
using namespace
System;
int main(void)
{
Int32 gcArray[] = new Int32[10];
// int gcArray __gc[] = new int __gc[10];
Console::WriteLine("Uzunluğu: {0}", __box(gcArray->get_Length()));
for(int i =
gcArray->GetLowerBound(0); i <
gcArray->GetUpperBound(0); i++)
gcArray[i] = rand();
Int32 temp[] = new Int32[20];
System::Array::Sort(gcArray); // statik bir metod
ile dizi sıraya sokulur
gcArray->CopyTo(temp,0); // dizinin 0. elemandan
sonrası kopyalanır
gcArray = temp; // işaretçiler eşitlenir
for(int i =
gcArray->GetLowerBound(0); i <
gcArray->GetUpperBound(0); i++)
Console::WriteLine(gcArray[i]);
return 0;
} |
Dikkat ettiyseniz ilk yarattığımız 10 elemanlı
int32 hafıza bloğunun işaretçisini program sonunda kaybediyoruz.
Bunu native arrayler ile yapmış olsaydık ve bu işlem herhangibi
rutin içinde yapılmış olsaydı belli bir süre sonra artık hafızada
yer ayıramicaktir ve "memory leak" gerçekleşecekti. Fakat sistem
arraylerinde bu tarz bir durumla karşılaştığımızda Garbage Collector
işaretçisini kaybettiğimiz dizilerin hafızalarını boşaltır ve
kullanıma açar. Veya diziyi kopyaladıktan sonra delete operatörü
ile gcArrayin içi boşaltılabilirdi.
Aşağıdaki örnekte iki boyutlu bir sistem dizisi
örneğini bulunmakta. Bu örnekte framework içerisindeki random sınıfı
ile dizinin içini doldurduk. Aynı zamanda dizinin boyut
değişimlerine bağlı kalmadan döngülerimizi hazırladık.
// gcMultiDim.cpp
#include "stdafx.h"
#using
<mscorlib.dll>
using namespace
System;
int main(void)
{
int x = 3 ,
y = 4;
double
gcMultiDim __gc[,]
= new
double
__gc[x,y];
Random* rnd = new Random();
Console::WriteLine("1. Boyutun Uzunluğu : {0}",
__box(gcMultiDim->GetLength(0)));
Console::WriteLine("2. Boyutun Uzunluğu : {0}",
__box(gcMultiDim->GetLength(1)));
Console::WriteLine("Toplam Dizi Boyutu : {0}",
__box(gcMultiDim->Rank));
Console::WriteLine("Toplam Dizi Uzunluğu: {0}\n",
__box(gcMultiDim->get_Length()));
for(int
i=0; i<gcMultiDim->GetLength(0); i++)
{
for
(int j=0;
j<gcMultiDim->GetLength(1); j++)
{
gcMultiDim->SetValue(__box(rnd->Next()),i,j);
// dizinin elemanları doldurulur
}
}
for(int
i = gcMultiDim->GetLowerBound(0); i <=
gcMultiDim->GetUpperBound(0); i++)
{
for
(int j =
gcMultiDim->GetLowerBound(1); j <=
gcMultiDim->GetUpperBound(1); j++)
{
Console::WriteLine("gcMultiDim[{0},{1}] = {2}",
__box(i),
__box(j),
gcMultiDim->GetValue(i, j));
// dizinin elemanlarını gösteriyoruz.
}
}
return 0;
} |
3.
Topluluklar ( Collections ):
Nesne yönelimli programlama esnasında integer ve
string gibi temel veri tiplerinden çok yarattığımız nesneleri bir
dizi içerisinde tutmak isteyebiliriz, bu esnada devreye
System::Collections sınıfı girer. Collectionsın bize sağladığı
avantajlardan sanırım en önemlisi diziye eklediğimiz nesnelere
kolayca bizim belirlediğimiz anahtarlar üzerinden erişmemizi
sağlaması "Associative Array özelliği". Aşağıdaki örnekte
yarattığımız nesnelere topluluklardan nasıl eklediğimizi ve
erişebildiğimizi görüceksiniz.
// gcSortedList.cpp
#include "stdafx.h"
#using
<mscorlib.dll>
using namespace
System;
using namespace
System::Collections;
public __gc class
Product{ // kendi
sınıfımızı yaratalım
public:
int id;
String* name;
double price;
Product(int p1, String*
p2, double p3)
// kurucu yöntem
{
id = p1;
name = p2;
price = p3;
}
public:
void pirntLine()
// tanımladığımı yazdırma
yöntemi
{
Console::WriteLine("ID:{0}\tNAME:{1}\tPRICE:{2}",
__box(id) , name,
__box(price));
}
};
int main(void)
{
SortedList* SList = new SortedList();
// yeni bir sıralanmış
topluluk
// nesnelerimizi yaratıp listemize istediğimiz
anahtar ile ekliyoruz
SList->Add(S"Çekiç", new
Product(0,S"Çekiç",1.87));
SList->Add(S"Kerpeten", new
Product(1,S"Kerpeten",2.07));
SList->Add(S"Kargaburun", new
Product(2,S"Kargaburun",5.80));
SList->Add(S"Ampul", new
Product(3,S"Ampul",1.02));
for(int i=0;
i<SList->get_Count(); i++)
// tüm listeyi yazdırıyoruz
{
((Product*)SList->GetByIndex(i))->pirntLine();
}
/* çıktıya dikkat ederseniz en son eklediğimiz
Ampul nesnesi en yukarda gözükmekte bu
SortedList topluluğunun bir özelliği eklediğiniz
nesneleri belirlediğiniz anahtara göre
sıralamakta*/
Console::WriteLine("\nLütfen bir ürün adı giriniz: ");
while(String* key = Console::ReadLine())
{
if(key->Equals("exit"))
// kullanıcı exit yazar
ise program terk edilir
break;
try
{
((Product*)SList->get_Item(key))->pirntLine();
/* girilen anahtara göre
nesne çekilir fakat topluluklar içinde veriler
Object olarak tutulur. yöntemlerine erişmek için
nesneyi tipine "cast" etmeniz gerekir */
}
catch(System::Exception* e)
{
Console::WriteLine("Ürün Bulunamadı!");
}
Console::WriteLine("\nLütfen bir ürün adı giriniz: ");
}
return 0;
} |
Topluluklardan sadece çok kullanılacağını düşündüğüm SortedListi
inceledik MSDN den amacınıza yönelik diğer topluluklarıda
araştırabilirsiniz.
Yazar : Sadun Sevingen
e-Posta : [email protected]
Makale:
Microsoft Visual C++ .Net ile Diziler ve Topluluklar C++ ve C++.NET dili Ahmet İpek
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|