Dodaj do ulubionych

zamiana opisu na kod

26.05.07, 21:30
Witam. Muszę napisać program, który tworzy listę 10 losowych liczb i wypisuje
listę na ekrean, na podstawie podanych słownie opisów procedur

type wsk=^rec
rec=record
liczba:integer;
next:wsk;
end;
var lista:wsk;

procedure tworz liste(var poczatek:wsk);
var pom, koniec:wsk;
i:integer;
begin
zainicjuj pom;
do pola liczba rekordu wskazywanego przez pom przypisz losową liczbę;
niech początek wskazuje na to samo co pom;
niech koniec wskazuje na to samo so pom;
niech pole next rekordu wskazywanego przez pom wskazuje na nil;
{mamy na liście jeden element}
for i:=2 to 10 do}
begin
zainicjuj pom;
do pola liczba rekordu wskazywanego przez pom przypisz losową liczbę;
niech pole next rekordu wskazywanego przez koniec wskazuje na pom;
niech koniec wskazuje na to samo co pom;
niech pole next rekordu wskazywanego przez pom wskazuje na nil;
end;
end;

procedure wypisz_liste(element:wsk);
begin
dopóki elementy<>nil rób
begin
wypisuj pole liczba rekordu na który wskazuje element;
niech element wskazuje na następny rekord na liście;
end;
end;

var lista:wsk;
begin
niech zmienna lista wskazuje na nil;
twórz liste(lista);
wypiszlistę(lista);
end.



Na razie mam tyle:

procedure tworz liste(var poczatek:wsk);
var pom, koniec:wsk;
i:integer;

begin
new(pom);
pom^:=random(100);
poczatek:=pom^;
koniec:=pom;
pom^.next:=nil;

for i:=2 to 10 do;
begin
new(pom);
pom^:=random(100);
koniec^.next:=pom^;
koniec^:=pom^;
pom^.next:=nil;
end;
end;

procedure wypisz_liste(element:wsk);
begin
while element<>nil do
begin
???
???
end;

var lista:wsk;
begin
lista^:=nil;
twórz_liste(lista);
wypisz_listę(lista);
end.

mógłby ktos ocenić, wytknąć błędy i ewentualnie pomóc? smilies/wink.gif
Obserwuj wątek
    • negevmc poprawny kod 27.05.07, 10:08
      type wsk=^rec;
      rec=record
      liczba:integer;
      next:wsk;
      end;

      var lista:wsk;

      // tam gdzie byl blad zaznaczylem to
      // oryginalnego kodu nie kasowalem tylko
      // poprzedzilem "//"

      // Cztery bledy wynikly moim zdaniem z malego nieporozumienia.
      // typ "wsk" jest wskaznikiem (pointerem). wskazuje na miejsce w
      // pamieci, gdzie znjduje sie pierwszy bajt recordu nazwanego
      // przez Ciebie "rec".
      // wsk a raczej kazda zmienna tego typu (np pom, koniec, poczatek) to pointer
      // aby otrzymac record na ktrory wskazuje uzwamy operatora ^.
      // Tak wiec liczba losowa (integer) musi byc przydzielona do pola recordu
      // a nie to wartosci pointera (miejsca w pamieci)
      // tzn pom^.liczba:=random(100);
      // zamiast
      // pom^:=random(100);
      // Mysle jednak, ze to raczej z roztargnienia niz z braku zrozumienia.
      // Natomiast w miejscu gdzie napisales
      // koniec^.next:=pom^;
      // nieporozumienie jest oczywiste pole next jest typu wsk a nie typu rec
      // dlatego mozesz
      // mu przyporzadkowac tylko zmienna takiego typu a wiec pom a nie pom^ czyli:
      // koniec^.next:=pom;
      // Bledy powyzsze sa o tyle proste, ze kompilator je prawdopodobnie wychwyci.
      // Jeden tylko nie: petla od 2 do 10 (patrz komentarz tam)

      procedure tworz_liste(var poczatek:wsk);
      var pom, koniec:wsk;
      i:integer;
      begin
      new(pom);

      // blad
      // pom^:=random(100);
      pom^.liczba:=random(100);

      // blad
      // poczatek^:=pom;
      poczatek:=pom;

      koniec:=pom;
      pom^.next:=nil;

      // blad tym bardziej fatalny, ze nie powoduje
      // bledu kompilacji. Po prostu petla sie kreci
      // od 2 do 10 nic nie robiac
      // for i:=2 to 10 do;
      for i:=2 to 10 do
      begin
      new(pom);

      // blad
      // pom^.liczba:=random(100);
      pom^.liczba:=random(100);

      // blad
      // koniec^.next:=pom^;
      koniec^.next:=pom;

      koniec:=pom;

      pom^.next:=nil;

      end;
      end;

      // troche zmienilem deklaracje tej procedury bowiem
      // jej argumentem nie jest jakis tam element tylko
      // pierwszy element listy (por. poczatek z proc. tworz_liste)
      procedure wypisz_liste(poczatek:wsk);
      var pom:wsk;
      begin

      pom := poczatek;

      // "krec" petle az do momentu gdy pole "next" nie bedzie na nic
      // wskazywalo (ono zawsze wskazuje na nastepny record)
      while pom.next<>nil do
      begin

      // standardowa procedure i/o writeln wypisuje na domyslnym urzadzeniu
      // wej/wyj (prawdopodobnie monitor) i przechodzi do nastepnej linii
      // argumentem musi byc string wiec zeby wypisac liczbe (integer) trzeb ja
      // najpierw na string zamienic - IntToStr to robi - standardowa funkcja
      // pascala

      writeln( IntToStr( pom^.liczba ) );

      // tu podmianka, teraz pom bedzie wskazywal na nastepny record
      pom := pom.next;

      end;
      end;


      begin
      lista:=nil;
      tworz_liste(lista);
      wypisz_liste(lista);
      end.

      To powinno dzialac.
      Chciales jednak uwagi wiec postaram sie jakies poczynic ;-)
      1. Pascal nie zwalnia (jak np C) zarezerwowanej pamieci (np przez procedure new)
      wiec trzeba na kniec ja "recznie" zwolnic za pomoca procedury dispose.
      2. Rozumiem, ze miales z gory zdefiniowane zadanie i to kazalo Ci uzyc - kurcze
      nie pamietam jak to sie mowi - listy storzonej za pomoca polczenia recordow
      Tzn, pole "next" wskazuje na poczatek nastenego elementu (recordu) listy.
      Sprawe jednak moznaby bylo zalatwic w kilku linijkach kodu uzywajac tablicy
      (array).
      Tu jednak moznaby dyskutwac na "za i przeciw" roznym rozwiazaniom.
      Zaprezentowany powyzej wymaga kilkudziesieciu linii kodu ale za to oszczedza
      pamiec i dlugosc listy zdefiniowana jest tylko w jednym miejscu (w petli for)
      co nie jest takie bez znaczenia jesli oceniamy "elegancje" programu.
      W innym mozliwym rozwiazaniu - np uzycie tablicy array [1..10] of integer kod
      bylby moze o polowe krotszy ale za to uruchomienie programu rezerwuje od razu
      miejsce na 10 liczb w pamieci. Niby nic ale co bedzie jesli program ma sluzyc
      do list 10 elementowych albo o dlugosci 100 mln. Wtedy rezerwacja taka jest juz
      znaczaca.

      mam nadzieje, ze co nieco pomoglem
      Pozdrawaim

Nie masz jeszcze konta? Zarejestruj się


Nakarm Pajacyka