Nieskończona pętla i błąd wskaźnika w programie

2015-04-10 14:40

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

Witam. Mam dwa problemy. Pierwszy dotyczy procedury wyswietl. W momencie kiedy do bazy zostanie dodana jedna książka procedura działa normalnie. Kiedy dodam jednak więcej niż jedną książkę program wpada w nieskończoną pętle. Drugi problem dotyczy wskaźnika. Chce aby ID książki nadawane było automatycznie z numerem o jeden większy od poprzedniego. Myślałem zrobić to w ten sposób:


procedure nadaj_id;
   begin
      if head^.id=0 then
         begin
         head^.id:=1;
         end
      else
         begin
         head^.id:=head^.id+1;
         end;
   end;

ale niestety nie działa. Poniżej jest program główny.


program ksiazki;
uses crt;
type

  wksiazka=^ksiazka;
  ksiazka=record
    id:integer;
    tytul:string[30];
    rok:integer;
    im_aut:string[20];
    naz_aut:string[20];
    gatunek:string[15];
    ile_w_sumie:integer;
    ile_wypo:integer;
    next:wksiazka;
    prev:wksiazka;
  end;

  var

    tmp:wksiazka;

  procedure dodaj(var head:wksiazka);

  {Procedura ma za zadanie dodac nowa ksiazke do bazy danych}

  var
    tmp,pom:wksiazka;  {Zmienna tmp sluzy do stworzenia nowego elemntu, zmienna pom do poruszania sie po liscie}
    ile,i:integer;       {Licznik petli for}
    licznik_id:integer;
    begin
      clrscr;
      new(tmp);
      writeln('Podaj ile ksiazek chcesz dodac do biblioteki: ');
      readln(ile);
      for i:=1 to ile do
      begin
      clrscr;
      writeln('Podaj tytul ksiazki: ');
      readln(tmp^.tytul);
      writeln;
      writeln('Podaj rok wydania ksiazki: ');
      readln(tmp^.rok);
      writeln;
      writeln('Podaj imie autora ksiazki: ');
      readln(tmp^.im_aut);
      writeln;                                                            {Dodawanie danych o ksiazkach do listy}
      writeln('Podaj nazwisko autora ksiazki: ');
      readln(tmp^.naz_aut);
      writeln;
      writeln('Podaj gatunek ksiazki: ');
      readln(tmp^.gatunek);
      writeln;
      writeln('Podaj liczbe WSZYSTKICH dostepnych ksiazek: ');
      readln(tmp^.ile_w_sumie);

      if head=nil then
      begin
         tmp^.prev := nil;    {Jesli lista jest pusta przypisz do pierwszego elementu}
         tmp^.next := nil;
         head := tmp;
      end
      else
      if head^.tytul > tmp^.tytul then
    begin
      tmp^.prev := nil;
      tmp^.next := head;    {Jesli pierwszy element jest "wiekszy" od dodawanego przypisz do nastepnego i az do skutku}
      head^.prev := tmp;
      head := tmp;
    end
      else
    begin
      pom := head;
      while (pom^.next <> nil) and (pom^.next^.tytul < tmp^.tytul) do
            pom := pom^.next;
      tmp^.next := pom^.next;                 {Jesli dodawany element jest "wiekszy" od obecnie pierwszego zajmuje jego miejsce}
      tmp^.prev := pom;
      if pom^.next <> nil then
          pom^.next^.prev := tmp;
      pom^.next := tmp;
    end;
    end;
    end;

procedure wyswietl(head : wksiazka);
begin
  clrscr;

  if head = nil then
     write('Brak ksiazek w bazie!')
  else begin
    while head <> nil do
    begin
         {wszystkie writelny sluza do wyswietlania poszczegolnych pol}
         writeln('Id ksiazki: ',head^.id);
         writeln('Tytul ksiazki: ',head^.tytul);
         writeln('Rok wydania ksiazki: ',head^.rok);
         writeln('Imie i nazwisko autora: ',head^.im_aut, ' ', head^.naz_aut);
         writeln('Gatunek ksiazki: ',head^.gatunek);
         writeln('Ilosc ksiazek dostepnych w bibliotece: ', head^.ile_w_sumie);
         head := head^.next;   {przypisanie nastepnika do pierwszego elementu}
    end;
    readln;
  end;

end;

procedure menu;
var
  numer:byte;
begin
     repeat
       clrscr;
       writeln('Podaj liczbe odpowiadajaca opcji');
       writeln('1. Dodawanie nowej ksiazki do bazy');
       writeln('2. Wyswietlanie wszystkich ksiazek w bibliotece');
       readln(numer);
       case numer of
       1: dodaj(tmp);
       2: wyswietl(tmp);
       else halt;
          end;
           until numer>3;
           end;

  begin

    menu;

  end.
Nie używaj prefiksów/postfiksów w tytułach wątków - od podawania nazwy języka/technologii są tagi; - furious programming 2015-04-10 16:41

Pozostało 580 znaków

2015-04-10 14:47

Rejestracja: 6 lat temu

Ostatnio: 8 godzin temu

0

Wskaźniki. Listy jedno i dwukierunkowe

edytowany 1x, ostatnio: furious programming, 2015-04-10 18:25
Link prowadzi do 404... :( - furious programming 2015-04-10 16:42
To coyote psuje, już któryś raz z rzędu - spartanPAGE 2015-04-10 16:50
@Adam Boduch, zobacz na ten link - ostatnia kropka należy do adresu, ale Coyote ją obcina; - furious programming 2015-04-10 17:01
Działanie jak najbardziej prawidłowe. Natomiast w URL nie powinna na końcu znaleźć się kropka co też poprawiłem. - Adam Boduch 2015-04-10 18:22
Ooo, usunąłem kropkę z linku i zmieniło na krótszą wersję; Trzeba dodać poprawkę wykluczającą możliwość istnienia kropki w adresie; - furious programming 2015-04-10 18:26

Pozostało 580 znaków

2015-04-10 16:48
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 godziny temu

Lokalizacja: Tuchów

2

@mikra25 - po co procedura dodaj ma kupę instrukcji wyświetlających i pobierających dane?

Przede wszystkim podziel sobie kod na sensowne procedury, gdzie część z nich będzie modyfikować listę, a pozostałe tylko pobierać z niej dane (np. do ich wyświetlenia); Po drugie - używaj tylko angielskich identyfikatorów, bo całość wygląda źle; Zobacz sobie do tego artykułu i na jego podstawie stwórz listę i zestaw procedur; Jeżeli nie chcesz lub nie możesz użyć programowania obiektowego, to pola klasy zamień na zwykłe zmienne, a publiczne metody na zwykłe procedury; Reszta pozostaje, bo jest uniwersalna.


Pozostało 580 znaków

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