Stacks Yardım.....

Başlatan newhollandd, 10 Nisan 2009 - 16:08:13

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

newhollandd

Öncelikle ilginiz için çok teşekkur ederim.Ben pc muh. okuyorum daha dogrusu okumaya çalışıyorum:) c++  derssinde hoca bir program yazdı konu başlığı stcak bu programın ne işe yaradıgını ve nasıl kullanıldıgı hakkında hiçbir bilgim yok.Bilen arkadaşlar varsa yardım edebilirmi.Program ne işe yarar ve nasıl kullanılır.



#include <iostream.h>
#include <stdio.h>
struct elem { int key; elem *next; } *SP1=NULL, *TEMP=NULL, *SP2=NULL;
void push (int n, elem *&START);
int pop(int &n, elem *&START);
void main()
{
int choice;
int n;
do {
cout<<"\nMenu:\n";
cout<<"1 - Push into SP1.\n";
cout<<"2 - Pop All (Pointer SP1).\n";
cout<<"3 - Copy SP1 to SP2.\n";
cout<<"4 - Pop All (Pointer SP2).\n";
cout<<"5 - Exit.\n";
cout<<"Enter your choice: ";
cin>>choice;
switch (choice)
{
case (1):
cout<<"n= ";
cin>>n;
push(n, SP1);
break;
case(2):
while(pop(n, SP1)) cout<<n<<"\t";
break;
case(3):
while(pop(n, SP1))
push(n, TEMP); // Move SP1 to TEMP (reversed).

while(pop(n, TEMP))
{
push(n, SP2);
push(n, SP1);
}
cout<<"SP1 copied to SP2\n";
break;
case(4):
while(pop(n, SP2)) cout<<n<<"\t";
break;

}
}
while (choice!=5);
}
void push (int n, elem *&START)
{
elem * p=START;
START=new elem;
START->key=n;
START->next=p;
}
int pop(int &n, elem *&START)
{
if (START)
{
elem * p=START;
START=START->next;
n=p->key;
delete p;
return 1;
} else return 0;
}


Not: Mesajlarınızda kalın harf kullanmanıza gerek yoktur. Düzenlenmiştir.
Not2: Code etiketi güzel durdu:)

yvz

Stack mantığı yanlış hatırlamıyorsam lifo(last in first out) yani; attığın ilk değer en altta kalacak şekilde bağlar birbirine verileri. Bunu üst üste konulan tabaklar gibi düşünebilirsin. Her bir tabağı diğerinin üstüne koyduğunda, ilk eklenen öğeye erişebilmek için diğerlerini tek tek kaldırman gerekir. Son eklediğin de en üstte olur ve ilk ona erişirsin. Kodda bir struct yapısı ve linked listle bağlanması var. Bu dediğim şekilde eklenmiş. Dikkat edersen push fonksiyonunda, veri yapısı START olarak tanımlanmış yani sen her veri girdiğinde, son girilen veri başlangıç değeri haline geliyor. SP1 pointerı her seferinde başlangıç değeri oluyor, fonksiyonun içinde onu başka bir p pointerına atıyor, yeni değeri ekledikten sonra, bir önceki SP1 değerini attığı p yi, yeni gelenin next değerine atıyor.

Arka arkaya 1 ve 2 değerlerini girdin n olarak diyelim. *SP1'i yukarıda struct ın tanımında zaten belirtmişiz (NULL olarak). ilk push fonksiyonunda, sen 1'i girdikten sonra, p pointerına mevcut SP1'i yani NULL değerini atıyacak. Sonra yeni bir yer açacak ve orada key değerine 1'i atayacak. Bundan sonra tekrar push edip 2 değerini girdiğindeyse, mevcut SP1 biraz önce 1 eklediğin yapıyı gösterdiğinden, onun adresini p ye atmış olacaksın, yeni bir yer açacaksın, bunun değerini 2 olarak eklemiş olacaksın ve bunun next'ine de p yi, yani biraz önce 1 değerini attığın yapının adresini atmış olacaksın. Şöyle bağlanmış olacak; SP1(2)->SP1(1)->NULL. Aynı zamanda bu son durumda senin elindeki *SP1 2 değerini attığın yapıyı gösteriyor olacak.

Pop fonksiyonu bu linked list yapısını açar. Eğer başlangıç değeri NULL değilse, yani push fonksiyonu en az bir kez çalıştırıldıysa pop fonksiyonu kendi içinde çalışacak, en üstteki birimin n değerini alıp bir TEMP yapısına push edecek (dolayısıyla en üsttekiler bu kez en altta kalıyor, en son girilen değeri ilk olarak çektiği ve ilk olarak eklediği için TEMP'e). Şöyle bir şey elde etmiş olacağız; TEMP(1)->TEMP(2)->NULL. Bunu stack yapısının en sonundaki NULL'a ulaşana dek yapıyor ve bu kez TEMP'ten pop ederek bunu SP2'ye ve SP1'e atıyor. Farkettiysen bu aynı işlem, biraz önce tersine çevrilen sırayı yeniden tersine çevirecek dolayısıyla ilk SP1 yapımızı olduğu gibi SP2 ve SP1'e atmış olacağız yeniden. Sonuçta SP1(2)->SP1(1)->NULL ve SP2(2)->SP2(1)->NULL gibi iki yapı elde etmiş oluyoruz. 4üncü seçenekte SP2yi olduğu gibi çıkarıp bırakıyor. Ayrıca C++'ta açtığınız hafızayı kapatmak da sizin işiniz olduğu için delete p diye bir seçenek var. Hafızayı şişirmemek için bunu yapmak gerekiyor.

Eksiğim ve yanlışım varsa diğer arkadaşların düzeltmelerini rica ediyorum. Ama bildiğim kadarıyla işin özü bu.

newhollandd

Alıntı yapılan: yvz - 10 Nisan 2009 - 18:26:41
Stack mantığı yanlış hatırlamıyorsam lifo(last in first out) yani; attığın ilk değer en altta kalacak şekilde bağlar birbirine verileri. Bunu üst üste konulan tabaklar gibi düşünebilirsin. Her bir tabağı diğerinin üstüne koyduğunda, ilk eklenen öğeye erişebilmek için diğerlerini tek tek kaldırman gerekir. Son eklediğin de en üstte olur ve ilk ona erişirsin. Kodda bir struct yapısı ve linked listle bağlanması var. Bu dediğim şekilde eklenmiş. Dikkat edersen push fonksiyonunda, veri yapısı START olarak tanımlanmış yani sen her veri girdiğinde, son girilen veri başlangıç değeri haline geliyor. SP1 pointerı her seferinde başlangıç değeri oluyor, fonksiyonun içinde onu başka bir p pointerına atıyor, yeni değeri ekledikten sonra, bir önceki SP1 değerini attığı p yi, yeni gelenin next değerine atıyor.

Arka arkaya 1 ve 2 değerlerini girdin n olarak diyelim. *SP1'i yukarıda struct ın tanımında zaten belirtmişiz (NULL olarak). ilk push fonksiyonunda, sen 1'i girdikten sonra, p pointerına mevcut SP1'i yani NULL değerini atıyacak. Sonra yeni bir yer açacak ve orada key değerine 1'i atayacak. Bundan sonra tekrar push edip 2 değerini girdiğindeyse, mevcut SP1 biraz önce 1 eklediğin yapıyı gösterdiğinden, onun adresini p ye atmış olacaksın, yeni bir yer açacaksın, bunun değerini 2 olarak eklemiş olacaksın ve bunun next'ine de p yi, yani biraz önce 1 değerini attığın yapının adresini atmış olacaksın. Şöyle bağlanmış olacak; SP1(2)->SP1(1)->NULL. Aynı zamanda bu son durumda senin elindeki *SP1 2 değerini attığın yapıyı gösteriyor olacak.

Pop fonksiyonu bu linked list yapısını açar. Eğer başlangıç değeri NULL değilse, yani push fonksiyonu en az bir kez çalıştırıldıysa pop fonksiyonu kendi içinde çalışacak, en üstteki birimin n değerini alıp bir TEMP yapısına push edecek (dolayısıyla en üsttekiler bu kez en altta kalıyor, en son girilen değeri ilk olarak çektiği ve ilk olarak eklediği için TEMP'e). Şöyle bir şey elde etmiş olacağız; TEMP(1)->TEMP(2)->NULL. Bunu stack yapısının en sonundaki NULL'a ulaşana dek yapıyor ve bu kez TEMP'ten pop ederek bunu SP2'ye ve SP1'e atıyor. Farkettiysen bu aynı işlem, biraz önce tersine çevrilen sırayı yeniden tersine çevirecek dolayısıyla ilk SP1 yapımızı olduğu gibi SP2 ve SP1'e atmış olacağız yeniden. Sonuçta SP1(2)->SP1(1)->NULL ve SP2(2)->SP2(1)->NULL gibi iki yapı elde etmiş oluyoruz. 4üncü seçenekte SP2yi olduğu gibi çıkarıp bırakıyor. Ayrıca C++'ta açtığınız hafızayı kapatmak da sizin işiniz olduğu için delete p diye bir seçenek var. Hafızayı şişirmemek için bunu yapmak gerekiyor.

Eksiğim ve yanlışım varsa diğer arkadaşların düzeltmelerini rica ediyorum. Ama bildiğim kadarıyla işin özü bu.
üstat ben yeniyim forumda özel msj atma imkanım yok sana. mail adresi verebilirimisn sana sormam gerekn bazı şeyler var.
Çok teşekkur ederim yardımlarin için...

yvz

İlk önce üstat çok ağır olmuş, ben de öğrenciyim henüz. Eksik yanlış, elimden geldiğince.

İkincisi, soruları özelden sormak yerine buradan sorarsan daha iyi olur. Hem herkes faydalanabilir cevaplardan hem de benim bilmediğim ya da yanlış bildiğim konuları bilen birileri çıkıp düzeltebilir (diye düşünüyorum).

newhollandd

#4
Menüden 4 ve 3. secenegin işlevlerini tam alayamadım.Sade bir dil ile anlatabilirsen memnun olurum.

Sypro

Öncelikle merhaba, bir konuda ufak bir uyarım bir de ufak bir sorum olacak:
uyarı demek doğru mudur bilemiyorum; ama pc mühendisliği değil, bilgisayar mühendisliği. İlk olarak buna alışmaya çalışın ki bölümünüze saygınız olsun. Diğer konu da şu ki, stack konusunda hiç araştırma yaptınız mı? Mesela google ilk olarak http://en.wikipedia.org/wiki/Stack_(data_structure) linkini çıkartıyor ve gayet açıklayıcı bilgiler var.
Yanlışsam düzeltin fakat diğer konunuzdan da gördüğüm kadarıyla pek vaktiniz yok ve nasıl yapacağınızı bilmediğiniz işlere bulaşmışsınız. Size tavsiyem biraz araştırın, elinizden geleni yapın, biz üstüne koyalım. Böylesi biraz dokunuyor insana.


"Milliyetin çok belirgin vasıflarından biri dildir. Türk milletindenim diyen insan, her şeyden evvel ve mutlaka Türkçe konuşmalıdır. Türkçe konuşmayan bir insan, Türk kültürüne, topluluğuna bağlılığını iddia ederse buna inanmak doğru olmaz."

newhollandd

Alıntı yapılan: Sypro - 10 Nisan 2009 - 21:05:42
Öncelikle merhaba, bir konuda ufak bir uyarım bir de ufak bir sorum olacak:
uyarı demek doğru mudur bilemiyorum; ama pc mühendisliği değil, bilgisayar mühendisliği. İlk olarak buna alışmaya çalışın ki bölümünüze saygınız olsun. Diğer konu da şu ki, stack konusunda hiç araştırma yaptınız mı? Mesela google ilk olarak http://en.wikipedia.org/wiki/Stack_(data_structure) linkini çıkartıyor ve gayet açıklayıcı bilgiler var.
Yanlışsam düzeltin fakat diğer konunuzdan da gördüğüm kadarıyla pek vaktiniz yok ve nasıl yapacağınızı bilmediğiniz işlere bulaşmışsınız. Size tavsiyem biraz araştırın, elinizden geleni yapın, biz üstüne koyalım. Böylesi biraz dokunuyor insana.
Haklısın belkide.Pc konusunda bidaha aynı şeyi yapmamaya gayet gostercem.Stack konusunu araştırdım anlamınıda öğrendim.Yanlız pek vaktim yok bu aralar.Dizüstüne ubuntuyu 2. işletim sistemi olarak kurma ile meşgulum.onunla ilgili 1 2 küçük sorunlarla ugraşıyorum.Ayrıca bu siteden Çağatay Cebir adlı üyenin paylaştığı kitap var onu indirdim ve c++ öğrenmeye çalışıyorum.Bu konular aciliyet gosterıyor yoksa bende hakkında hiç bişey bilmediğim konuyu başkarına sorup insalara zülüm etmezdim.Hatalıysam Özür dilerim tüm forumdan.

plymouth

Var olan tum buffer sistemlerinde ve işlemcilerde Stack yapısını görmek mümkündür ve bu bir senkronizasyon ya da multi tasking amaçlı olarak üretilmiş ve yıllardır kullanılan bir register yönetim biçimidir. Ancak sizin direkt olarak stack yapısını öğrenmeniz zor da değildir. Stack aslında şöyle de düşünülebilir. Önemli bir işiniz çıktığında elinizde ki daha az öneme sahip işi bir kenara bırakıp bu işle ilgilenirsiniz. Ama yapmakta olduğunuz ve sonra yarıda bıraktığınız eski işinize geri döndüğünüzde kaldığınız yerden devam etmek için işi bırakmadan önce kaldığınız noktayı bir yere not edersiniz(Bu örnekte stack Multi tasking amaçlı olarak ele alınmıştır.) İşte bu Stack işlemidir. Temel yazılım dillerinden Assembly de "pop"ve "push" komutları bu işe yarar. Daha üst düzey diller bunu otomatik olarak yapar. (İşte Assembly bilmek bundan dolayı cok güzeldir. Bütün yazılım dilleri Assembly gibi esnek değildir.) FIFO ve LIFO ise tasarım odaklı mecburiyetlerdir. Intel (ve uyumlu)işlemciler Stack pointer diye bir yapı kullanır ve belli bir kapasitesi vardır. Tam anlamıyla donanımsal bir yapı olan stack aslında tüm işlemcilerde bulunur ama özellikler tam olarak aynı değildir. Stack kaldığınız yeri not ettiğiniz minik bir yazı tahtası olarak düşünebileceğiniz yapıdır.
         Az önceki örnek üzerinde Stack ve multi-tasking yapısını inceleyelim.
Cpu muz daha önce verilen emir üzre ramden belli bir bilgiyi alıyor. Diyelim ki bu tam olarak 12 Micro saniye sürecek bir iş ve şu anda da tam olarak yeni başladı. ilk adres olan 0x3ADE adresini okumaya başladı. Tam o anda kullanıcı klavyeden bir tuşa bastı. Cpu ya ilk önce bir kesme (IRQ-interrupt request) geldi. tabiki klavye tarayıcısı artık hangi IRQ ye programlanmışsa o sınıfın IRQ (klavye genelde int 20 IRQ kullanır) numarası ile işlemciye "elindeki işi kes ve IRQ numarasında belirttiğim Kesme vektorune git" der. bu emri alan CPU önce ram okuma programında kaldığı yeri stack registerine alır. Bir sonra ki adım da cpu kendi içsel yazmaçlarını (AX,BX,LX gibi) bir yere not eder ve gelen kesme isteğine uyar. burada ki işini bitirirse (başka kesme gelmezse eğer) geri döner ve registerleri geri yukleyip (LIFO-Last in First Out yapısına sahipse eğer-ki genelde öyledir-) Ram okuma programında kaldığı yeri almak için Stack den adresi alır. Böylece veri kaybı olmadan 1 işlemci 2 işi yapmış olur. LIFO ya gelince En son Stack e atılan bilgi ilk olarak geri döner çünkü kesme geldikten sonra başka kesmelerde gelebilir.bu kez de kesmeden kesmeye geçer stack yığınına 2 değeri girer. (tabanca sarjörüne mermi doldururken en son taktığınız mermi ilk attığınız mermidir.)yani ondan önce yığına atılan 1. veri bir alta iner.
Cpu lar çok hızlı veri işledikleri için biz aynı anda bir çok işi yapıyor gibi düşünürüz. Bu senaryo bazı kısımları eksik olan bir multi tasking örneğidir. FIFO ise CPU kadar hızlı çalışamayan tüm çevre birimlerinde kullanılan bir senkronizasyon yardımcısı olan Buffer yapısıyla ilgilidir. Ama konuyla pek ilgisi yok. Temel fark İlk giren ilk çıkar.
Yanlışlarım için şimdiden özür dilerim.
Assembly çok güzeldir ama iş uzun programlar yazmaya gelince bazen insan olduğunuzu bile unutursunuz. işte o zaman C ve C++ gibi daha üst seviye diller daha makul oluyor...
umarım mantığı anlmamanıza faydam dokunur.
Tahtaya bu tip bir program yazan bir hoca size (kanaatimce) işlemcilerle yakından ilişkili olan C++ gibi bir dilde aslında Stack Pointer, IRQ, MultiTasking, gibi işlemci yetenekleri hakkında nasıl çalıştıklarına dair bilgi vermeye çalışıyor derim.
This life is not the real thing.
It is not even in Beta.
If it was, then OpenBSD would already have a man page for it