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

2) 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.

2) 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, botów: 0