Respond needs javascript to run. To find out more click here
C++ » Sayfa 2 » Serdar Demir
RSS
 

Archive for the ‘C++’ Category

C++ Win32 Uygulaması Oluşturmak

24 Eki

Win32 Uygulaması Oluşturmak

Öncelikle söyleyeyim de sonradan kafanıza takılmasın; bu konuda herhangi bir hazır kütüphane (MFC, ATL veya .NET) kullanmadan Windows Penceresi nasıl oluşturulur bunu göreceğiz. Dil olarak C++ kullanıyoruz.

Öncelikle projemizi oluşturalım. Bunun için Visual Studio’ da FileNewProject’ e tıklıyoruz ve çıkan pencereden Visual C++ altındaki Win32 Project’ i seçiyoruz.

Karşımıza Win32 Application Wizard geliyor. Next’ e tıklayıp Application Settings adımına geliyoruz. Burada Windows Application’ un seçili olmasına dikkat edin. Additional Options altında Empty Project’ i işaretleyip Finish diyoruz.

Şimdi projeye yeni bir C++ kod dosyası eklememiz lazım.Bunun için Solution Explorer’ da Source Files’ a sağ tıklayıp AddNew Item seçeneğini seçiyoruz ve yeni bir C++ File(.cpp) oluşturuyoruz (İsmi önemli değil).

Dosyayı oluşturduktan sonra öncelikle Windows API ve diğer kütüphaneleri kod dosyasına eklememiz lazım.

#include <windows.h>
#include <tchar.h>

Win32 Uygulamaları da Konsol uygulamaları gibi bir ana fonksiyona sahiptir. Bu fonksiyonumuz WinMain fonksiyonudur. WinMain 4 adet parametre alır. WinMain fonksiyonu şuna benzer.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

}

Bununla birlikte oluşturacağımız Windows penceresinin kullanacağı bir fonksiyon daha gerekiyor bize. Bu fonksiyon da aşağıdakine benzer bir şekilde tanımlanabilir.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

}

Şimdi WinMain fonksiyonuna gerekli kodları eklemeye başlayabiliriz. Öncelikle bize oluşturacağımız windows penceresi için WNDCLASS türünden bir değişken gerekiyor. Gerekli yerleri yorum satırlarıyla açıkladım.

WNDCLASS wc;

wc.style = CS_HREDRAW | CS_VREDRAW; // Penceremizin özellikleri.

wc.lpfnWndProc = WndProc; // Penceremizin kullanacağı fonksiyon ismi.

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance; // WinMain fonksiyonuna gelen ilk parametre.

wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); // Pencerenin simgesi

wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Pencerenin işaretçisi

wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); // Arkaplan rengi

wc.lpszMenuName = NULL; // Pencerenin kullanacağı menü. Biz menü kullanmayacağımız için NULL atıyoruz.

wc.lpszClassName = TEXT(“Win32App”); // Pencereninin Sınıf Adı. Başka bir yerde kullanılacağından bu ismi unutmamanız gerek.

Şimdi bu fonksiyonu RegisterClass fonksiyonuyla kayıt ettirmemiz gerek.

if (!RegisterClass(&wc))

{

MessageBox(NULL, TEXT(“RegisterClass Hatası!”), TEXT(“Win32 Uygulaması”), NULL);

return EXIT_FAILURE;

}

Sonra, pencereyi oluşturmalıyız. Bunu CreateWindow fonksiyonuyla gerçekleştiriyoruz. Aldığı parametreleri yorum satırlarıyla açıkladım.

HWND hWnd = CreateWindow(TEXT(“Win32App”), // Pencerenin sınıfının adı. Daha önce unutmamanız gerekli dediğim şey.

TEXT(“Win32 Uygulaması”), // Pencerenin başlığı

WS_OVERLAPPEDWINDOW, // Pencerenin görünüm stili.

CW_USEDEFAULT, CW_USEDEFAULT,// Pencerenin açılacağı koordinatlar. Sırasıyla X ve Y

500, 100, // Pencerenin boyutları. Sırasıyla Genişlik ve Yükseklik

NULL, NULL,

hInstance, // WinMain’ e gelen ilk parametre

NULL);

if (!hWnd)

{

MessageBox(NULL, TEXT(“CreateWindow Hatası!”) ,TEXT(“Win32 Uygulaması”), NULL);

return EXIT_FAILURE;

}

Şimdi bu pencereyi gösterelim.

// hWnd : CreateWindow fonksiyonunun dönüş değeri

// nCmdShow : WinMain fonksiyonunun son parametresi

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

Ve WinMain fonksiyonunun son görevi, mesaj döngüsü. Bu döngü uygulamanın hayat döngüsü olarak adlandırılabilir ve siz durdurmadığınız sürece durmaz.

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int) msg.wParam; // ve WinMain fonksiyonu biter

Şimdi bu mesaj döngüsünün ürettiği mesajları işleme koyacak WndProc fonksiyonunu oluşturmalıyız. Bu fonksiyon daha önce de belirttiğim gibi pencerenin işlemlerini gerçekleştirecek olan fonksiyondur. Aşağıdaki kodları WndProc fonksiyonuna yazmalısınız.

PAINTSTRUCT ps;

HDC hdc;

TCHAR Yazi[] = _T(“Merhaba Dünya!”); // Ne yapayım bende bir programcıyım

switch (message) // Fonksiyonun ikinci parametresi

{

case WM_PAINT: // Ön tanımlı mesajlardan biri

hdc = BeginPaint(hWnd, &ps);  // hWnd parametre olarak geliyor

TextOut(hdc,

5, 5, // Yazının konumu. Sırasıyla X ve Y

Yazi, _tcslen(Yazi)); // Üstte tanımladığımız yazıyı gösteriyoruz.

EndPaint(hWnd, &ps);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam); // Eğer mesaj işleme alınmazsa öntanımlı pencere işlem fonksiyonunun değeri döndürülüyor.

break;

}

return 0; // ve WndProc fonksiyonunun sonu

Ayrıca; programı sonlandırmak için switch bloğuna,

case WM_DESTROY:

PostQuitMessage(0);

break;

durumunu da eklersek iyi olur. Daha fazla öntanımlı mesaj için IntelliSense kullanabilirsiniz. Daha sonraki yazılarımda Resource dosyalarını kullanarak daha işlevsel ve dinamik uygulamalar yapmayı göstereceğim.

Bu da ortaya çıkan şey :

Kod dosyasını indirmek isteyenler tıklasın.

 
No Comments

Posted in C++

 

Java Script’e Giriş-Java Script kodları indir örnek uygulamalar

21 Eki

Javascript’le Tanışalım

Javascript programı yazmak için ihtiyacınız olan alet-edavat, bu kitapçığın yanı sıra, iyi bir bilgisayar ve bir düz yazı programıdır.

Bilgisayarınız ecza dolabı kılıklı bir PC ise Notepad, bilgisayarınız mandalina, çilek veya şeftali renkli bir iMac ise SimpleText bu iş için biçilmiş kaftan sayılır. Eğer bu amaçla bir kelime-işlem programı kullanacaksanız, oluşturacağınız metnin dosyasını diske veya diskete kaydederken, düz yazı biçiminde kaydetmesini sağlamalısınız. Çalışmaya başlamadan önce örnek kodlarınızı bir arada tutabilmek ve gerektiğinde gerçek sayfalarınızda yararlanabilmek için sabit diskinizde bir dizin açmanız yerinde olur.

Javascript, HTML’in bir parçasıdır ve içinde bulunduğu HTML ile birlikte Web Browser programı tarafından yorumlanır. Dolayısıyla, Javascript programı yazmak demek, bir Web sayfası hazırlamak ve bu sayfadaki HTML kodlarının arasına Javascript kodları gömmek demektir.

O halde, kolları sıvayıp, ilk Javascript programımızı yazalım. Şu kodu yazıp, merhaba1.htm adıyla kaydedin:

Merhaba Dünya

Sonra ya bu dosyayı iki kere tıklayın; ya da favori Browser programınızı çalıştırın ve bu dosyayı açın. Karşınıza çıkacak düğmeyi tıklayın. İşte sonuç:

Şimdi kendi kendinizi kutlayın: Birazcık yardımla da olsa, Javascript programcısı olarak dünyaya merhaba demiş bulunuyorsunuz. Yazdığınız koddan tek kelime bile anlamıyorsanız da hiç önemli değil. Önemli olan ilk adımı atmaktı.

Bu adımı attığınıza göre şimdi yazdığınız kodu biraz irdeleyelim. Bütün Web sayfaları gibi, Javascript kodunuzun yer aldığı sayfa da tipik bir HTML kod kümesi:

1. Browser programına kendisinin bir HTML dosyası olduğunu birinci satırda beyan ediyor; ve bittiği yer açıkça gösteriliyor.

2. HTML kodu iki bölüm içeriyor: Başlık (Head) ve gövde (Body) bölümleri. Her bölümün nerede başladığı ve nerede bittiği açıkça belirtiliyor.

3. Gövde bölümünde bir Form unsuruna yer veriliyor; fakat bu formun tek ögesi var: Düğme (Button).

4. Daha önce Web sayfalarınıza düğme koyduysanız, bu düğmenin onlardan farklı bir tarafı var: Türü, değeri, vs. belirtilmiyor; sadece “onclick=”alert(‘Merhaba Dünya!’)” şeklinde bir ifadeye yer veriliyor.

5. Ve ilk Javascript programınızda ne Javascript’in adı geçiyor; ne de HTML ile Javascript bölümlerini birbirinden ayırteden, etiketine yer veriliyor!

Özellikle bu son husus, size şunu gösteriyor: Günümüzde Netscape ve IE Javascript ile o kadar içiçe geçmiş ve Javascript özellikle 1.2’nci sürümü ile o kadar Browserların Belge Nesnesi Modeli (Document Object Model) ile kaynaşmıştır ki, kimi zaman HTML’in işlevi nerede bitiyor, Javascript’in işlevi nerede başlıyor, kolaylıkla ayırt edilemez.

Javascript’ten söz ederken, bu dilin imla kuralları olmakla birlikte bu kurallara yüzde 100 uymanın zorunlu olmadığını ifade ettik. Kural olarak, Javascript bölümü, HTML’in içine etiketlerinin arasına gömülür. İşte size bütün kuralları yerine getirilmiş bir Javascript bölümü yazma örneği:

Merhaba Dünya

Bu metni merhaba2.htm adıyla kaydeder ve Browser’ınızda açarsanız, görüntünün ve işlevin tıpatıp aynı olduğunu göreceksiniz. İki metin arasındaki fark, ikincisinin Javascript yazma kurallarına yüzde 100 uymasından ibaret. Bununla birlikte Javascript ile HTML’i birbirinden dikkatlice ayırmanız gereken durumlar, ikisinin birbiriyle kaynaştığı noktalardan daha çoktur. Hatta o kadar ki, Javascript’in ileri sürümüne ilişkin komutlar kullanıyorsanız, eski sürüm Browser’ların kafasının karışmaması ve dolayısıyla ziyaretçinizin bilgisayarının kilitlenmemesi için bunu bile belirtmeniz gereken durumlar olabilir.

Bir de şunu deneyin: önce merhaba.js adıyla şu metni kaydedin:

function merhaba()

{

alert(“Merhaba, Dünya!”)

}

Sonra, merhaba2.htm dosyasında şu değişikliği yapın ve merhaba3.htm adıyla kaydedin:

Merhaba Dünya

Ve merhaba3.htm’i açtığınızda yine aynı görüntü ve aynı işlevle karşılaştığınızı göreceksiniz. Bu üçüncü yöntemde sadece Javascript kodlarını içeren ve dosya adının uzatması “.js” olan bir düzyazı dosyasını HTML’e dışardan da eklemiş olduk.

Bu esnekliğe bakarak, Javascript diline, “Ne yapsam olur! Nasıl yazsam işler!” anlayışıyla yaklaşamazsınız. Javascript, bütün bilgisayar dilleri gibi yorumlanabilmesi (çalışabilmesi) için kendi imla ve dilbilgisi kurallarına son derece bağlı kalınmasını ister. Bunu sınamak isterseniz, şu ana kadar oluşturduğunuz herhangi bir HTML dosyasında Javascript bölümündeki bir parantezi veya süslü parantezi kaldırın; dosyayı başka bir isimle kaydedin ve Browser’ınıza açtırmaya çalışın! Merhaba3.htm dosyasında “onclick=”merhaba()” komutunun bir parantezini kaldırdığımızda, Netscape ve IE’nin şu hata mesajlarını verdiğini görüyoruz:

HTML sayfalarınının Web Browser programlarında yapabileceği bir başka hata ise, kodu icra etmek yerine içerik gibi görüntülemektir. Web ziyaretçilerinin halâ kullandığı eski sürüm Browser programları, Javascript programlarını ya hiç anlamazlar, ya da eski sürümlerini anlarlar. Netscape 2.0 öncesi ile IE 3.0 öncesi Browser programlarının, Javascript kodlarını icra etmek yerine sayfanın içeriği imiş gibi görüntülemesini önlemek için Script bölümlerini eski sürüm Browser’lardan, merhaba2.htm sayfasında yaptığınız gibi gizlemeniz gerekir. Merhaba2.htm’e bakarsanız:

şeklinde bir bölüm göreceksiniz. Bu bölümün başında ve sonunda yer alan “” işaretlerinin arasındaki herşey, eski sürüm Browserlar tarafından HTML dili kurallarına göre “yorum” sayılacak ve görmezden gelinecektir. Javascript dilinin yorumları ise “//” işaretiyle başlar ve satır sonunda sona erer. Merhaba2.htm’de Javascript kodlarının bütün satırlarında böyle yorumlar koydunuz. Eğer yorumlarınız bir satırdan uzun olacaksa, bunu şöyle belirtebilirsiniz:

/* yorumun birinci satırı

yorumun ikinci satırı

yorumun üçüncü satırı */

Javascript veya başka bir dille program yazarken, iyi programcılar, programlarını kendilerinden başkası denetlemeyecek ve yeniden kullanmayacak da olsa, önemli işleri yaptıkları satırlara mutlaka yorum koyarlar. Bunun yararını, kendi yazdığınız bir programı bile bir yıl sonra yeniden açtığınızda görürsünüz!

Ziyaretçinin Web Browser programı Javascript anlıyor ise sayfanızdaki Javascript kodları, ya ilk yazdığınız programda olduğu gibi, ziyaretçinin sayfanızda bir yeri tıklaması veya klavyede bir tuşa basmasıyla harekete geçer; ya da HTML sayfası ziyaretçinin Browser’ında görüntülendiği anda otomatik olarak çalışmaya başlar. Otomatik çalışan Javascript kodu ise iki ayrı yöntemle çalıştırılabilir: HTML kodları icra edilmeden önce (yani sayfanız ziyaretçinin Web Browser’ında görüntülenmeden önce, veya sayfa görüntülendikten sonra.

Davranın düz yazı programınıza ve şu kodları girin:

Merhaba Dünya

Bu dosyayı da merhaba4.htm adıyla kaydedin ve Browser’ınızda açın. Sayfanızın içeriğini oluşturan “Merhaba Dünya” yazısı ile Javascript programınızın icra ettirdiği uyarı kutusunun görüntülenmelerindeki sıraya dikkat edin.

Bu dosyada, küçük bir değişiklik yapalım ve kodlarımıza şu şekli verelim:

Merhaba Dünya

merhaba5.htm adıyla kaydedeceğiniz bu dosyayı Browser’ınızda açtığınızda, sayfa metni ile uyarı kutusunun görüntülenme sırasına dikkat edin. Merhaba4’de önce uyarı kutusunun görüntülenmesinin sebebi, Browser’ın HTML kodundaki komutları yukarıdan aşağı sırayla yerine getirmesi ve bu arada karşısına çıkan Javascript komutunu da icra etmesidir. Oysa merhaba5’te, Javascript komutunu bir fonksiyon olarak tanımladınız ve bu fonksiyonun icrasını HTML’in BODY etiketinin içeriğinin Browser’ın penceresine yüklenmesine bağladınız. Bunu Javascript’in “onLoad” komutuyla yaptık. (onLoad’ın nasıl kullanıldığını ve nerelerde kullanıldığını daha sonra ayrıntılı ele alacağız. Şimdiden telaşa kapılmaya gerek yok!)

Buraya kadar gördüğümüz bir kaç örneği, Javascript kodlarının ne zaman ve nasıl işlediğini göstermek amacıyla verdik. Fakat bu örneklerden çıkartacağımız başka bir sonuç daha var: Dikkat etti iseniz Javascript komutları, daima HTML sayfasının bir unsuruna bağlı olarak veriliyor. Yani Javascript’in konusu veya hedefi, Web Browser programının (Netscape veya IE’nin) bilgisayarın ekranında oluşturduğu pencerenin içindeki belgenin bir ögesi. Bu öge, şimdilik ya bu belgenin içindeki FORM unsurunun bir bölümü (örneğin, düğmesi), ya da sayfanın BODY bölümünün bizzat kendisi oldu.

Bu ögeler, unsurlar, unsurların bölümlerine programcılık dilinde “Nesne” (Object) denir. Ya kendisi bir nesne oluşturabilen veya içinde çalıştığı programın ya da işletim sisteminin nesnelerini konu alan ve bu nesnenin unsurlarını, ögelerini, parçalarını hedef olarak alan dillere Object-oriented (nesne-yönelimli) diller denir. Bu dillerle yazılan programlara (isterse bir Script dilinin düz yazı şeklindeki komutları olsun) Object-oriented Program (OOP) adı verilir.

Javascript programları da OPP sınıfına girdiği için, Javascript programcısı olacaksanız, programlarınızın mutlaka Web Browser’ın bir nesnesinin bir özelliğini belirlemeye veya değiştirmeye ve Web Browser’ı bir nesne oluşturmaya ve nesnenin şu özelliğini şöyle veya böyle yapmaya yönelik olması gerektiğini akıldan hiç çıkartmamalısınız. Bu nesne, Browser’ın penceresinin menü çubuğunun olması ya da olmaması, pencerenin bilgisayar ekranında ne büyüklükte olması, pencerenin alt çerçevesindeki statü mesajının içeriğinin değiştirilmesi bile olabilir. Javascript programı açısından HTML etiketleri ile oluşturacağınız hemen herşey nesnedir. Bu nesnelerin nasıl etkileneceği ise Javascript programının içeriğini oluşturur.

Özetlersek, Javascript ile Web Browser programını penceresini ve Browser programının yorumladığı HTML etiketlerinin oluşturacağı sayfa ögelerini, bu ögelerin biçimini, değerini belirler, sorgulayabilir ve değiştirebilirsiniz.

Şimdi kısaca bu işlevselliğin temeli olan ve adına Document Object Model (DOM, Belge Nesne Modeli) denen kurallar demetinden söz edelim. Javascript kodu, DOM’u hedef alır: bu bağlamda DOM, bir Browser’ın penceresi ve penceresinin içindeki herşey demektir. Ama henüz herşey için bir olay ve metod standardı geliştirilmiş değil.

“Olay” (Event) ve “Metod” (Method) burada dikkat etmeniz gereken iki kelime. Olay, Web Browser’ın veya kullanıcının yaptığı bir iş, eylem, hareket demektir; “Metod” ise programcı olarak sizin bu “Olay”ı veya nesnenin bir özelliğini (Property) kullanarak, Belge’nin bir unsuruna yaptırtabileceğiniz iş, eylem, hareket veya değişikliktir. Bu “teori” ilk bakışta sanıldığı kadar kavranması zor değil. Bir örnekle açıklayalım:

Diyelim ki, HTML sayfanızda şöyle bir bölüm var:

WEB KİTAPÇISI

Roman

Hikaye

Biyografi

Şimdi bu HTML kodu sayfanızda şu Nesne’leri oluşturur:

1. Bir adet Form

2. Dört adet “checkbox” türü INPUT alanı

3. Bir adet metin alanı

Şimdi dikkat: Sizin açınızdan “form01” isimli bu formu oluşturan FORM ögesi, Javascript açısından “document.form01” adlı nesnedir. Ziyaretçinin içine işaret koyduğu kutu, Javascript tarafından “document.checkboxSelected” diye tanınır. Sizin “sonuc” isimli metin alanınızın içinde yazılı olacak metin ise Javascript bakımından “document.form01.sonuc.value” (value=değer) diye bilinir.

HTML dilini geliştirenler, türü “checkbox” olan INPUT nesnesinin başına gelebilecek “olay” türlerinin neler olabileceğini düşünürken, “Mesela,” demişler, “Kullanıcı bu kutuyu tıklayabilir!” Yani, bu nesnenin Browser açısından yol açabileceği “olay”lardan biri tıklanması halinde olan olaydır. Tıklamanın İngilizcesi ne? “click!” O halde bu olayın adı “Click,” bu olayı yönlenrdiren metodun adı ise “onClick”tir (on, İngilizce -de, -da eki veya üzerinde, halinde kelimesinin karşılığıdır). Bu durumda “onClick,” olayı, bu kutu açısından bir olaydır ve Javascript prnogramcısı olarak bu olayı yakalayabilir, kullanabiliriz. Başka bir deyişle, Browser’a, Javascript yoluyla “Ey Browser; kullanıcı benim INPUT nesnelerimden “roman” adlı olanı tıkladığı zaman şu, şu işi yap!” emrini verebiliriz. Bu noktada bilgisayar programının, hangi dille yazılırsa yazılsın, alt alta gelmiş komutlar listesi olduğunu hatırlatalım.

Peki, yine aynı örnekte, Browser’a Javascript yoluyla ne gibi bir iş yaptırtabiliriz? Mesela, “Ey Browser, kullanıcı benim INPUT nesnelerimden ‘roman’ adlı olanı tıkladığı zaman benim ’sonuc’ adlı TEXTAREA nesnemin değerini ‘Roman’ yap!” diyebiliriz. Biliyorsunuz ki, TEXTAREA nesnelerinin değeri, ekranda çizdikleri kutunun içine koydukları içerik demektir. Tabiî aynı mantıkla, “hikaye” kutusu işaretlenince Sonuç kutusuna “Hikaye,” “biyografi” kutusu işaretlenince de Sonuç kutusuna “Biyografi” yazdırtmak elimizde.

Kısaca, Javascript herşeyi, bir HTML ögesine göre tanımlar, adlandırır ve bilir. Unutmayacağınız kural: “Javascript, sayfanın bir şeyini alır, sayfanın bir şeyine hitabeder!”

Bu gayet anlamlı şekilde ifade ettiğimiz kuralı yerine getirmekte sorun, sadece Javascript’in on-onbeş kelimesini, yedi-sekiz işlemini öğrenmek değil, aslında HTML belgesinin nesnelerinin olaylarını ve metodlarını öğrenmektir.

Dolayısıyla, önce Javascript’in on-onbeş kelimesi ve yedi-sekiz işleminden ibaret temel kurallarını ele alacağız; sonra da bunlarla Belge Nesneleri’ne hangi olay halinde ne yapabileceğimizi ve bunu nasıl yapabileceğimizi göreceğiz.

 
1 Comment

Posted in C++

 

Veri yapıları ve algoritmalar-Kuyruklar (queue) örnek uygulama

21 Eki
KUYRUK
Kuyrukların Özellikleri
·         Giriş Sırası = Çıkış Sırası
Tek bir kasanın hizmet verdiği bir süpermarkette ödeme yapmak için bekleyen insanların oluşturduğu sıra gibi bir diziye “kuyruk” (queue) adı verilir. Bu ödeme kuyruğuna ilk giren kişi sonra girenlerden önce ödemesini yapıp gider (ilk-gir, ilk-çık, yani first-in, first-out, ya da kısaca FIFO). En son giren işi ise en son ödeme yapacak olan kişidir (son-gir, son-çık, yani last-in, last-out ya da kısaca LILO). Bu FIFO ve LILO özellikleri beraberce “giriş sırasıyla çıkış sırasıyla aynıdır” diye ifade edilebilirler.
·         Sırayla erişim
Bir kuyruk oluşturacak bir veri grubundaki elemanlar birbirleriyle bağlantılı olmalıdır ki kuyruktaki her eleman kuyruğa girdiği sırayla işlem görebilsin. Bağlantılı bir listede olduğu gibi bir kuyrukta da her eleman bir sonraki elemanın yerini bildiren bir adres değişkenine sahip olmalıdır, veya kuyruk elemanlarının adresleri ayrı bir adres değişkenleri dizisinde saklanmalıdır.
Kuyruklarla İlgili Özel İşlemler
·         Sona Ekleme
Bir süpermarket kasası önündeki ödeme kuyruğuna aradaki bir noktadan girilmez. Fiziksel bariyerler yoksa bile etik prensipler veya toplum baskısı bunu engeller. Aynı şey kuyruk oluşturacak şekilde sıralanıp bağlanmış değişkenler için de doğrudur. Bir kuyruğa ancak en son konumdan yeni bir eleman eklenebilir.
Eğer kuyruğun son elemanının adresi pSON gibi bir değikleme için tek gereken şey yeni elemanı son elemandan sonraki eleman olarak tanıtmaktır. Bu işlemden sonra yeni eleman yeni son eleman olacaktır:
2‑8 Bir kuyruğun sona yeni bir eleman eklenmesi
pSON.pSonraki=pYeniEleman
pSON=pYeniEleman
·         Önden Çıkartma
Bir dizi veya listedeki elemanlar, eğer programcı belli bir andan sonra hiç ama hiç gerekli olmayacak elemanları silmek için komutlar yazmamışsa, program çalışıp bitinceye kadar var olmaya devam ederler. Halbuki bir kuyruktaki elemanlar, üzerlerinde gerekli işlemler yapıldığı zaman –tıpkı ödemesini yapmış süpermarket müşterileri gibi- kuyruktan ayrılmalıdırlar. Kural gereği olarak, kuyruğun ilk elemanı kuyruktan ilk ayrılan eleman olacaktır:
2‑9 Öndeki elemanın kuyruktan çıkartılıp silinmesi
pİLK.Değer = BOŞ
pİLK = pİLK.pSonraki
BOŞ değer atanması başlangıçta en önde yer alan elemanın hafızadan silinmesi içindir. Bu işlem yapılmayıp bu değişken hafızada bırakılsa bile ikinci komuttaki işlemle kuyruktan çıkartılmış olacaktır.
Yığınlar (Stacks)[1]
Yığınların Özellikleri
·         Son Giren İlk Çıkar
Aynı anda çok sayıda müşteriye hizmet veren büyük bir lokantada tabaklar bir yandan yıkanıp yığılırken bir yandan da yeni müşterilere servis yapmak için yığından çıkartılırlar. Bu tabak yığınının ilginç bir özelliği vardır: Yığına ilk giren tabak en altta kalmış olacağı için yığındaki diğer tabakları devirmeden yerinden kolayca alınamaz. Dolayısıyla servis yapacak bir garson çabucak işine dönmek için yığının en üstündeki tabağı, yani yığına en son eklenmiş tabağı alıp gidecektir. Kısacası bir yığını diğer veri yapılarından ayırt eden özellik son-gir, ilk-çık (last-in, first-out, kısaca LIFO) diye adlandırılır. Bir yığına ilk giren elemansa son çıkacak olan elemandır (first-in, last-out, kısaca FILO).
·         Bağlantılılık
Bir yığın oluşturacak bir veri grubundaki elemanlar da birbirleriyle bağlantılı olmalıdır. Üstteki eleman çıkartılırsa sıra onun altındakine gelecektir. Üstteki elemanın bir altındaki eleman zaman sırasında göre önceki elemandır, ama liste ve kuyruklarda yaptığımız gibi alttaki elemanı sonraki eleman olarak düşüneceğiz.
Yığınlarla İlgili Özel İşlemler
·         Üste Ekleme
Bir yığına da ancak en üst konumdan yeni bir eleman eklenebilir.
Eğer yığının en üst elemanının adresi pÜST gibi bir adres değişkeniyle belirlenmişse, tek gereken şey bu üst elemanı yeni eklenecek elemandan sonraki eleman olarak tanıtmaktır. Bu işlemden sonra yeni eleman üst eleman olacaktır:
Kod Örneği 2‑10 Bir yığının üstüne yeni bir eleman eklenmesi
pYeniEleman.pSonraki = pÜST
pÜST = pYeniEleman
·         Üstten Çıkartma
Yığındaki en üst eleman üzerinde gerekli işlemler yapıldığı zaman yığından çıkarılmalıdır. Bunun için yapılacak şey boş elemanı “silmek” için gereken işlem neyse onu yapmak ve ondan bir önceki elemanı yeni üst eleman olarak işaretlemektir.
Kod Örneği 2‑11 Yığının üst elemanının çıkartılması
pÜST.Değer = BOŞ
pÜST = pÜST.pSonraki
Nesneye Yönelik Programlama Dillerinde Veri Yapıları
Sınıf Değişkenleri
Bu bölümde kısaca gözden geçirdiğimiz en temel türden veri yapıları üzerinde yapılabilecek işlemler (yeni eleman sokma veya silme, önden çıkartma, sona ekleme, vb.) veri yapısını oluşturan elemanların türlerine bakmaksızın, belli adımlar atılarak gerçekleştirilirler. Dolayısıyla, programında bir bağlantılı liste, bir kuyruk vb. yarataıp kullanacak olan bir programcı belli işlemler için gereken belli adımları bilip o adımları gerçekleştirecek komutları programına eklemelidir. Yüzbinlerce programcı bu tür veri yapıları üzerinde çalışacak komut dizilerini tekrar tekrar yazmak zorunda kalmasınlar diye bu komut dizilerini önceden hazırlanmış fonksiyonlar halinde paketleyip programcıların kullanımına sunmak en mantıklı çözümdür. Yapısal programlama dillerine ait derleyicilerle birlikte gelen fonksiyon kütüphaneleri veri yapılarının kullanımını kolaylaştırabilirler. Nesneye yönelik programlama dilleri ise belli bir veri yapısı üzerinde belli işlemler yapabilecek fonksiyonları veri yapısının kendisiyle birlikte paketleyip sunarak programcıların işlerini daha da kolaylaştırırlar. Nesneye yönelik bir programlama dilinde, bir programcı belli bazı değişkenleri gruplandırarak bir karmaşık değişken veya bir veri yapısı tanımı yatattığında, o değişken grubu üzerinde gerekli işlemler yapacak belli fonksiyonları da değişken grubu tanımına ekleyebilir. Kendisiyle ilişkili fonksiyonları da tanımında barındıran bir veri grubuna “sınıf değişkeni” (class variable) denir.
Üye Fonksiyonlar
Bir sınıf değişkeninin tanımına dahil edilmiş fonksiyonlara “üye fonksiyonlar” (member functions) veya “metodlar” denir. Bir sınıf değişkeni olarak tanımlanmış bir veri yapısını bir programda kullanmak için sınıf değişkeninin üye fonksiyonlarını çağırmak yeterlidir. Örneğin, C++ dilinde bir bağlantılı liste list türü bir sınıf değişkeni ile temsil edilebilir. Tamsayı elemanlardan oluşan bir liste türü değişken
list tamsayi_liste;
şeklinde, ondalıklı sayılardan oluşan bir liste ise
list ondalikli_liste;
şeklinde tanımlanabilir. Aşağıdaki kod örneği bu türden bir tamsayı listesi yaratıp ona elemanlar ekleyip çıkartan bir C++ programının parçasını gösteriyor:
Kod Örneği 2‑12 Bir C++ programında bir bağlantılı liste tanımlanması ve eleman eklenmesi
list tamsayi_liste;
tamsayi_liste.push_back(1);
tamsayi_liste.push_front(2);
tamsayi_liste.push_back(3);
tamsayi_liste.pop_front();
tamsayi_liste.push_back(5);
tamsayi_liste.pop_back(6);
İngilizce bilmeyen okuyucularımız için açıklayalım: Bu örnekte kullanılan push_back() üye fonksiyonu liste sonuna, push_front() üye fonksiyonu ise liste önüne eleman eklemek için kullanılabilir. pop_back() liste sonundan, pop_front() liste başından eleman çıkartmak için kullanılırlar.
Listeler, kuyruklar veya daha karmaşık veri yapılarını temsil eden sınıf değişkenlerini kullanmak programcıların işlerini kolaylaştırdığı gibi, onlara kısa ve kolay anlaşılır programlar yazma imkanını da verir, ama veri yapıları üzerinde yapılacak işlemleri ortadan kaldırmaz veya kısaltmaz. N adım gerektiren bir arama işlemi veya N2 adım gerektiren bir sıralama işlemi, ilgili üye fonksiyonlarını çağıran birer komuttan ibaret bile olsalar aynı sayıda adım gerektirirler. Bu tür bir üye fonksiyon kullanan bir algoritmanın adım sayısını hesaplarken, her bir komutun gerektirdiği adım sayısını bilip ona göre hesap yapmalıyız. Biz bu ders notlarının metin kısmında gerçek program örnekleri vermeyeceğiz, ama bazı kod örneklerimizi daha kısa ve anlaşılır olsunlar diye nesneye yönelik bir programlama dilini kullanıyormuş gibi yazacağız.
[1] Bülent Sankur’un Bilişim Sözlüğü (1) stack terimi için “yığıt” karşılığını öneriyor. Bu kitapta kulağa daha tanıdık gelen bir karşılık seçtik.
ÖRNEK1
#include
#include
using namespace std;
int main ()
{
queue<int> myqueue;
int myint;
cout << “Tam sayi giriniz (enter 0 to end):n”;
do {
cin >> myint;
myqueue.push (myint);
} while (myint);
cout << “kuyrugun icerigi: “;
while (!myqueue.empty())
{
cout << ” ” << myqueue.front();
myqueue.pop();
}
return 0;
}
Örnek 2
// queue::empty
#include
#include
using namespace std;
int main ()
{
queue<int> myqueue;
int sum (0);
for (int i=1;i<=10;i++) myqueue.push(i);
while (!myqueue.empty())
{
sum += myqueue.front();
myqueue.pop();
}
cout << “total: ” << sum << endl;
return 0;
}
çıktı:
total: 55

KUYRUK

Kuyrukların Özellikleri

·         Giriş Sırası = Çıkış Sırası

Tek bir kasanın hizmet verdiği bir süpermarkette ödeme yapmak için bekleyen insanların oluşturduğu sıra gibi bir diziye “kuyruk” (queue) adı verilir. Bu ödeme kuyruğuna ilk giren kişi sonra girenlerden önce ödemesini yapıp gider (ilk-gir, ilk-çık, yani first-in, first-out, ya da kısaca FIFO). En son giren işi ise en son ödeme yapacak olan kişidir (son-gir, son-çık, yani last-in, last-out ya da kısaca LILO). Bu FIFO ve LILO özellikleri beraberce “giriş sırasıyla çıkış sırasıyla aynıdır” diye ifade edilebilirler.

·         Sırayla erişim

Bir kuyruk oluşturacak bir veri grubundaki elemanlar birbirleriyle bağlantılı olmalıdır ki kuyruktaki her eleman kuyruğa girdiği sırayla işlem görebilsin. Bağlantılı bir listede olduğu gibi bir kuyrukta da her eleman bir sonraki elemanın yerini bildiren bir adres değişkenine sahip olmalıdır, veya kuyruk elemanlarının adresleri ayrı bir adres değişkenleri dizisinde saklanmalıdır.

Kuyruklarla İlgili Özel İşlemler

·         Sona Ekleme

Bir süpermarket kasası önündeki ödeme kuyruğuna aradaki bir noktadan girilmez. Fiziksel bariyerler yoksa bile etik prensipler veya toplum baskısı bunu engeller. Aynı şey kuyruk oluşturacak şekilde sıralanıp bağlanmış değişkenler için de doğrudur. Bir kuyruğa ancak en son konumdan yeni bir eleman eklenebilir.

Eğer kuyruğun son elemanının adresi pSON gibi bir değikleme için tek gereken şey yeni elemanı son elemandan sonraki eleman olarak tanıtmaktır. Bu işlemden sonra yeni eleman yeni son eleman olacaktır:

2‑8 Bir kuyruğun sona yeni bir eleman eklenmesi

pSON.pSonraki=pYeniEleman

pSON=pYeniEleman

·         Önden Çıkartma

Bir dizi veya listedeki elemanlar, eğer programcı belli bir andan sonra hiç ama hiç gerekli olmayacak elemanları silmek için komutlar yazmamışsa, program çalışıp bitinceye kadar var olmaya devam ederler. Halbuki bir kuyruktaki elemanlar, üzerlerinde gerekli işlemler yapıldığı zaman –tıpkı ödemesini yapmış süpermarket müşterileri gibi- kuyruktan ayrılmalıdırlar. Kural gereği olarak, kuyruğun ilk elemanı kuyruktan ilk ayrılan eleman olacaktır:

2‑9 Öndeki elemanın kuyruktan çıkartılıp silinmesi

pİLK.Değer = BOŞ

pİLK = pİLK.pSonraki

BOŞ değer atanması başlangıçta en önde yer alan elemanın hafızadan silinmesi içindir. Bu işlem yapılmayıp bu değişken hafızada bırakılsa bile ikinci komuttaki işlemle kuyruktan çıkartılmış olacaktır.

Yığınlar (Stacks)[1]

Yığınların Özellikleri

·         Son Giren İlk Çıkar

Aynı anda çok sayıda müşteriye hizmet veren büyük bir lokantada tabaklar bir yandan yıkanıp yığılırken bir yandan da yeni müşterilere servis yapmak için yığından çıkartılırlar. Bu tabak yığınının ilginç bir özelliği vardır: Yığına ilk giren tabak en altta kalmış olacağı için yığındaki diğer tabakları devirmeden yerinden kolayca alınamaz. Dolayısıyla servis yapacak bir garson çabucak işine dönmek için yığının en üstündeki tabağı, yani yığına en son eklenmiş tabağı alıp gidecektir. Kısacası bir yığını diğer veri yapılarından ayırt eden özellik son-gir, ilk-çık (last-in, first-out, kısaca LIFO) diye adlandırılır. Bir yığına ilk giren elemansa son çıkacak olan elemandır (first-in, last-out, kısaca FILO).

·         Bağlantılılık

Bir yığın oluşturacak bir veri grubundaki elemanlar da birbirleriyle bağlantılı olmalıdır. Üstteki eleman çıkartılırsa sıra onun altındakine gelecektir. Üstteki elemanın bir altındaki eleman zaman sırasında göre önceki elemandır, ama liste ve kuyruklarda yaptığımız gibi alttaki elemanı sonraki eleman olarak düşüneceğiz.

Yığınlarla İlgili Özel İşlemler

·         Üste Ekleme

Bir yığına da ancak en üst konumdan yeni bir eleman eklenebilir.

Eğer yığının en üst elemanının adresi pÜST gibi bir adres değişkeniyle belirlenmişse, tek gereken şey bu üst elemanı yeni eklenecek elemandan sonraki eleman olarak tanıtmaktır. Bu işlemden sonra yeni eleman üst eleman olacaktır:

Kod Örneği 2‑10 Bir yığının üstüne yeni bir eleman eklenmesi

pYeniEleman.pSonraki = pÜST

pÜST = pYeniEleman

·         Üstten Çıkartma

Yığındaki en üst eleman üzerinde gerekli işlemler yapıldığı zaman yığından çıkarılmalıdır. Bunun için yapılacak şey boş elemanı “silmek” için gereken işlem neyse onu yapmak ve ondan bir önceki elemanı yeni üst eleman olarak işaretlemektir.

Kod Örneği 2‑11 Yığının üst elemanının çıkartılması

pÜST.Değer = BOŞ

pÜST = pÜST.pSonraki

Nesneye Yönelik Programlama Dillerinde Veri Yapıları

Sınıf Değişkenleri

Bu bölümde kısaca gözden geçirdiğimiz en temel türden veri yapıları üzerinde yapılabilecek işlemler (yeni eleman sokma veya silme, önden çıkartma, sona ekleme, vb.) veri yapısını oluşturan elemanların türlerine bakmaksızın, belli adımlar atılarak gerçekleştirilirler. Dolayısıyla, programında bir bağlantılı liste, bir kuyruk vb. yarataıp kullanacak olan bir programcı belli işlemler için gereken belli adımları bilip o adımları gerçekleştirecek komutları programına eklemelidir. Yüzbinlerce programcı bu tür veri yapıları üzerinde çalışacak komut dizilerini tekrar tekrar yazmak zorunda kalmasınlar diye bu komut dizilerini önceden hazırlanmış fonksiyonlar halinde paketleyip programcıların kullanımına sunmak en mantıklı çözümdür. Yapısal programlama dillerine ait derleyicilerle birlikte gelen fonksiyon kütüphaneleri veri yapılarının kullanımını kolaylaştırabilirler. Nesneye yönelik programlama dilleri ise belli bir veri yapısı üzerinde belli işlemler yapabilecek fonksiyonları veri yapısının kendisiyle birlikte paketleyip sunarak programcıların işlerini daha da kolaylaştırırlar. Nesneye yönelik bir programlama dilinde, bir programcı belli bazı değişkenleri gruplandırarak bir karmaşık değişken veya bir veri yapısı tanımı yatattığında, o değişken grubu üzerinde gerekli işlemler yapacak belli fonksiyonları da değişken grubu tanımına ekleyebilir. Kendisiyle ilişkili fonksiyonları da tanımında barındıran bir veri grubuna “sınıf değişkeni” (class variable) denir.

Üye Fonksiyonlar

Bir sınıf değişkeninin tanımına dahil edilmiş fonksiyonlara “üye fonksiyonlar” (member functions) veya “metodlar” denir. Bir sınıf değişkeni olarak tanımlanmış bir veri yapısını bir programda kullanmak için sınıf değişkeninin üye fonksiyonlarını çağırmak yeterlidir. Örneğin, C++ dilinde bir bağlantılı liste list türü bir sınıf değişkeni ile temsil edilebilir. Tamsayı elemanlardan oluşan bir liste türü değişken

list tamsayi_liste;

şeklinde, ondalıklı sayılardan oluşan bir liste ise

list ondalikli_liste;

şeklinde tanımlanabilir. Aşağıdaki kod örneği bu türden bir tamsayı listesi yaratıp ona elemanlar ekleyip çıkartan bir C++ programının parçasını gösteriyor:

Kod Örneği 2‑12 Bir C++ programında bir bağlantılı liste tanımlanması ve eleman eklenmesi

list tamsayi_liste;

tamsayi_liste.push_back(1);

tamsayi_liste.push_front(2);

tamsayi_liste.push_back(3);

tamsayi_liste.pop_front();

tamsayi_liste.push_back(5);

tamsayi_liste.pop_back(6);

İngilizce bilmeyen okuyucularımız için açıklayalım: Bu örnekte kullanılan push_back() üye fonksiyonu liste sonuna, push_front() üye fonksiyonu ise liste önüne eleman eklemek için kullanılabilir. pop_back() liste sonundan, pop_front() liste başından eleman çıkartmak için kullanılırlar.

Listeler, kuyruklar veya daha karmaşık veri yapılarını temsil eden sınıf değişkenlerini kullanmak programcıların işlerini kolaylaştırdığı gibi, onlara kısa ve kolay anlaşılır programlar yazma imkanını da verir, ama veri yapıları üzerinde yapılacak işlemleri ortadan kaldırmaz veya kısaltmaz. N adım gerektiren bir arama işlemi veya N2 adım gerektiren bir sıralama işlemi, ilgili üye fonksiyonlarını çağıran birer komuttan ibaret bile olsalar aynı sayıda adım gerektirirler. Bu tür bir üye fonksiyon kullanan bir algoritmanın adım sayısını hesaplarken, her bir komutun gerektirdiği adım sayısını bilip ona göre hesap yapmalıyız. Biz bu ders notlarının metin kısmında gerçek program örnekleri vermeyeceğiz, ama bazı kod örneklerimizi daha kısa ve anlaşılır olsunlar diye nesneye yönelik bir programlama dilini kullanıyormuş gibi yazacağız.

[1] Bülent Sankur’un Bilişim Sözlüğü (1) stack terimi için “yığıt” karşılığını öneriyor. Bu kitapta kulağa daha tanıdık gelen bir karşılık seçtik.

ÖRNEK1

#include

#include

using namespace std;

int main ()

{

queue<int> myqueue;

int myint;

cout << “Tam sayi giriniz (enter 0 to end):n”;

do {

cin >> myint;

myqueue.push (myint);

} while (myint);

cout << “kuyrugun icerigi: “;

while (!myqueue.empty())

{

cout << ” ” << myqueue.front();

myqueue.pop();

}

return 0;

}

Örnek 2

// queue::empty

#include

#include

using namespace std;

int main ()

{

queue<int> myqueue;

int sum (0);

for (int i=1;i<=10;i++) myqueue.push(i);

while (!myqueue.empty())

{

sum += myqueue.front();

myqueue.pop();

}

cout << “total: ” << sum << endl;

return 0;

}

çıktı:

total: 55

 
3 Comments

Posted in C++