Pascal, implemetacja stosu

0

Ucze sie dopiero pascala i mam problem ze zrozumieniem stosu. Zanczy wiem jak dziala stos, bo uzywalem go w c++ ale tam bylo calkiem inczej.

Ponizej kod

 
program abc;
type stos = ^element;
element = record
	wartosc:integer;
	nastepny:stos;
end;


procedure push(var s:stos; liczba:integer);
var
	tmp:stos; // nowy wskaznik na element
begin
	New(tmp);
	tmp^.wartosc:=liczba;
	tmp^.nastepny:=s;
	s:=tmp; // zamien ostatni wskaznik
end;

function empty(s:stos):boolean; // zwraca true gdy pusty stos
begin
	if s=nil then empty:=true
	else empty:=false;
end;

procedure pop(var s:stos);
var
	tmp:stos;
begin
	if not empty(s) then
		begin
			writeln(' Sciagamy ze stosu ',s^.wartosc);
			tmp:=s;
			s:=tmp^.nastepny;
			dispose(tmp);
		
		end
	else
		writeln('Nie mozna sciagnac bo stos jest pusty');


end;


var
	s:stos;
begin
	s:=nil; // na poczatku nie pokazuje na nic, inicjalizacja stosu
	
end.

Kod ten dziala ale nie rozumie 2 linijek z procedury Push

  1. tmp.nastepny:=s; Dlaczego tak a nie tmp.nastepny:=nil; ? Przeciez jest to ostatni element

oraz

  1. s:=tmp; // tego w ogole nie rozumie

Z gory dzieki za odpowiedz

0

ZNACZY wiem jak dziala stos, bo uzywalem go w c++ ale tam bylo calkiem INACZEJ.

No jak używałeś STL to coś podobnego można uzyskać tylko że w nieco nowszych kompilatorach niż TP 4 DOS.

  1. tmp.nastepny:=s; Dlaczego tak a nie tmp.nastepny:=nil; ? Przeciez jest to ostatni element

Jaki ostatni? Pierwszy.

  1. s:=tmp; // tego w ogole nie rozumie

Polski język, ciężki język.

0
type stos = ^element;

Przyjęło się nazywanie (prefix) typów od T (pomijając parę wyjątków z biblioteki standardowej :P), a wskaźników od P.

function empty(s:stos):boolean; // zwraca true gdy pusty stos
begin
        if s=nil then empty:=true
        else empty:=false;
end;

Lepiej jest zrobić po prostu empty := s = nil i do tego inline, jeżeli już chcesz mieć funkcję.

s:=tmp;   // tego w ogole nie rozumie

Przypisanie wskaźnika.
Od momentu tego przypisania, zmienna s wskazuje na ten sam obszar pamięci, co tmp.

Przeczytaj rozdział w Twoim tutorialu lub książce o wskaźnikach, a zrozumiesz ten kod...


PS: na przyszłość takie wątki dawaj do działu `newbie` oraz **TAGUJ** je!
0

Nastepnym razem dam do dzialu newbie. Co do funkcjonowania wskaznikow to wiem w jaki sposob one dzialaja, ale nie wiedzialem w jakim celu sluzylo tam to przypisanie. Teraz po wypowiedzi -123oho jeszcze bardziej mi sie to pomieszalo. Jak moze to byc pierwszy element ?
Pomijajac implementacje wedlug mnie to powinno byc cos takiego :

  • mam poczatkowo pusty stos i inicjalizuje go jako nil
  • dodaje 1 element, w tym elemencie trzymam wartosc i jako ze jest to pierwszy i zarazem ostatni element to trzymam nil
  • dodaje 2 element, zmieniam wskaznik 1 i od teraz pokazuje na 2 element, a do drugiego wpisuje wartosc i oznaczam wskaznik jako nil.
    itd
    i jak pozniej chce sciagac to bym sciagal od gory n-element, n-1 element itd
0

Masz hipokryzję w nazwach, stąd to całe zamieszanie.
Zamiast następny powinieneś był nazwać to poprzedni w rekordzie element (a w każdym razie tak to pole traktujesz w kodzie), wtedy kod byłby bardziej czytelny i nie byłoby takiego zamieszania.

0

Dzieki za odpowiedzi. Teraz juz rozumie dokladnie dzialanie tego. Kod nie byl moj wiec trudno mi sie go analizowalo. Mam jeszcze tylko ostatnie pytanie. Wiem ze w sekcji var deklaruje sie np zmienne. W procedurach push i pop mamy odpowiednio var oraz tmp:stos; czyli tworzymy zmienne wskaznikowe. I stad moje pytanie dlaczego w procedurze push jest New(tmp) a w pop nie ma, choc dziala takze gdy jest, a gdy usuniemy z procedury push to wywala blad.

0

W procedurach push i pop mamy odpowiednio var oraz tmp:stos; czyli tworzymy zmienne wskaznikowe.

Oczywiście, bo dla ciebie nie ma różnicy czy var jest w parametrach czy jako deklaracja.

I stad moje pytanie dlaczego w procedurze push jest New(tmp) a w pop nie ma, choc dziala takze gdy jest, a gdy usuniemy z procedury push to wywala blad.

www.google.pl -> kurs Pascala -> Wskaźniki. Nie jesteśmy tutaj aby robić za kurs.

0

a gdy usuniemy z procedury push to wywala blad.

Jeżeli to dodasz do pop, masz memory leak.
Poczytaj do czego służy New oraz Dispose (hint: new alokuje pamięć, a dispose ją zwalnia, więc jeżeli nie wywołasz new w funkcji push, piszesz po pamięci pod adresem najprawdopodobniej 0x0).

1 użytkowników online, w tym zalogowanych: 0, gości: 1