[Pascal] Problem z tablicą


(Wojtanos) #1

Witam, chciałbym żeby program zrobił tablicę z tylu elementów ile się mu poda.

Na chłopski rozum zrobiłbym tak:

var 

a:array[1..x] of string;

begin

readln(x);

end.

Bardzo proszę o pomoc.

P.S. Podawanie elementów do tablicy to już zrobie, pętle jeszcze jakoś mi idą :wink:


(inż. Piniol) #2

W pascalu nie ma czegoś takiego jak dynamiczne tablice, pojawiły się one dopiero w późniejszych wersjach Object Pascala (Delphi).

Jeżeli korzystasz z kompilatora FreePascal to możesz użyć skłądni Delphi, gdyż FP ją wspiera:

http://dyahayuni.wordpress.com/2008/04/ ... in-pascal/


(Wojtanos) #3

Z całym szacunkiem, ale musi być jakiś sposób. To jest zadanie z Turbo Pascala.


(somekind) #4

Dynamiczne tablice w Pascalu: http://4programmers.net/Turbo_Pascal/Tablice_dynamiczne_w_Pascalu (to pierwszy wynik z googla).

Aha - i wcale nie musi być sposobu.


(Wojtanos) #5

To też znalazłem, lecz ma się to nijak do mojego problemu.


(Cosik Ktosik) #6

Możesz utworzyć tzw. listę (jedno lub dwukierunkową, no i cykliczną), w której będzie przechowywany dany element+dowiązanie (wskaźnik) do poprzedniego elementu listy. Na początku tworzysz wskaźnik na listę i nadajesz jej NIL (NULL z C). Wstawiasz następny element listy, poprzez utworzenie nowego wskaźnika, w którym przechowujesz nowy element oraz dowiązanie do poprzedniego elementu listy.

Lista pozwala na w pełni dynamiczną alokację pamięci. Można także wstawiać i usuwać nowe elementy w takiej liście. Wtedy jest jednak potrzeba lista w dowiązaniem do elementu poprzedniego i następnego. Rozrywasz wtedy listę i wstawiasz do środka nowy element.


(Wojtanos) #7

Aaaa... Teraz rozumiem. Dzięki bardzo!


(Gina Gina) #8

W TurboPascalu_7.0 do utworzenia i przekształcania takiej tablicy można wykorzystać sposób

przekazywania danych do procedury/funkcji gdzie nie wymaga się deklarowania rozmiaru tablicy

ale programista musi sam rozwązać określenie jej rozmiaru. :wink:

Deklaracja procedury wygląda np tak:

procedure Wczytaj_osoby(var a_osoby2: array of osoba_; n: word);

gdzie pierwszy parametr a_osoby2: array of osoba_ określa strukturę zawartą w tablicy

a drugi n określa jej rozmiar i tylko od programisty zależy w jaki sposób tu wartość przypisze.

Poniższy przykład obejmuje wprowadzenie danych do tablicy i pliku zwykłą metodą

z wykorzystaniem statycznej tablicy oraz z wykorzystaniem w/w metody.

http://wklej.org/id/cedd2128c3

{ ----------------------------------------------------------------------- }

{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}

{$M 16384,0,655360}

{ dyna3.pas TurboPascal7.0} 

{ Prosty przyklad użycia tablicy o nieznanym rozmiarze }

{ http://wklej.org/id/cedd2128c3 }

{ ----------------------------------------------------------------------- }

type

  osoba_ = record

              nazwisko : string[20];

              imie : string[10];

              adres : string[30];

            end;

{ ----------------------------------------------------------------------- }            

const

  c_osoby : array[1..6] of osoba_ = 

    (

     (nazwisko:'Kowalski'; imie: 'Jan' ; adres:'W-wa'),

     (nazwisko:'Nowak' ; imie: 'Andrzej' ; adres:''),

     (nazwisko:'Wisnia' ; imie: 'Ryszard'),

     (nazwisko:'Zabek' ; imie: 'Marian' ),

     (nazwisko:'Menel'),

     ()

    );

{ ----------------------------------------------------------------------- }

var

  i : word;

  osoba : osoba_;

  a_osoby1: array[1..6] of osoba_;

  f_osoba : file of osoba_; 


  nazwisko_imie_adres,

  nazwisko_imie,

  nazwisko,

  puste : word;   


  fx,fy : file;

  Buf : ^osoba_;

  BufSize : word;

  Count : word;

{ ----------------------------------------------------------------------- }

procedure Wczytaj_osoby(var a_osoby2: array of osoba_; n: word);

var

  k: word;

  osoba: osoba_;

begin

  Write('-----Nazwisko-----------','-Imie-----','-Adres------------------------');

  for k:=1 to n do

  begin

    osoba:=a_osoby2[k-1];

    Write(#13#10,k:3,'. ',osoba.nazwisko,

                      ' ':20-length(osoba.nazwisko),osoba.imie,

                      ' ':10-length(osoba.imie), osoba.adres);

  end;

end;

{ ----------------------------------------------------------------------- }

procedure Zapisz_osoby(var a_osoby2: array of osoba_; n: word);

var

  k: word;

begin

  for k:=1 to n do

  begin

    a_osoby2[k-1].nazwisko:= '#'+a_osoby2[k-1].nazwisko;

  end;

end;

{ ----------------------------------------------------------------------- }

begin

  { --------------------------------------- } 

  { załadowanie danych -------------------- } 


  Assign(f_osoba,'Osoby.dat');

  Rewrite(f_osoba);


  for i:=Low(c_osoby) to High(c_osoby) do

    Write(f_osoba,c_osoby[i]);


  Close(f_osoba);

  { --------------------------------------- } 

  { odczyt danych -prosto do tablicy ------ } 


  nazwisko_imie_adres:=0;

  nazwisko_imie :=0;  

  nazwisko :=0;

  puste :=0;


  Reset(f_osoba);

  Writeln('Plik zawiera: ', FileSize(f_osoba),' pozycji danych adresowych');


  for i:=1 to FileSize(f_osoba) do read(f_osoba, a_osoby1[i]); { wczytanie z pliku do tablicy }


  Write('-----Nazwisko-----------','-Imie-----','-Adres------------------------');

  for i:=1 to FileSize(f_osoba) do

  begin

      osoba:= a_osoby1[i];

      Write(#13#10,i:3,'. ',osoba.nazwisko,

                        ' ':20-length(osoba.nazwisko),osoba.imie,

                        ' ':10-length(osoba.imie), osoba.adres);

      if (osoba.nazwisko<>'') and (osoba.imie <>'') and (osoba.adres<>'') then inc(nazwisko_imie_adres);

      if (osoba.nazwisko<>'') and (osoba.imie <>'') and (osoba.adres ='') then inc(nazwisko_imie);

      if (osoba.nazwisko<>'') and (osoba.imie ='') and (osoba.adres ='') then inc(nazwisko);

  end;

  Puste:= FileSize(f_osoba) - nazwisko_imie_adres - nazwisko_imie - nazwisko;


  Writeln(#13#10,'w tym: ');

  Writeln(nazwisko_imie_adres:6,' - z nazwiskiem/imieniem/adresem');

  Writeln(nazwisko_imie:6 ,' - z nazwiskiem/imieniem/-bez adresu');

  Writeln(nazwisko:6 ,' - z nazwiskiem/-bez imienia i adresu');

  Write(puste:6 ,' - pust(e/ych) lub uszkodzonych');

  Close(f_osoba);


  { ---------------------------------------------------------------------------------------- }

  { odczyt/zapis danych -blokiem-użycie tablicy o nie zadeklarownym wcześniej rozmiarze----- } 


  Assign(fx,'osoby.dat');

  {$i-}

    FileMode:=0;

    Reset(fx,1);

  {$i+}

  If (IOResult=0) then

  begin

    Writeln(#13#10#13#10,'Metoda tablicy o nie podanym rozmiarze: -----------------------',#13#10,

            ' Wolna pamiec :',MemAvail:8, ' B, obsluzy plik z: ',(MemAvail div SizeOf(osoba_)):6,' pozycjami',#13#10,

            ' Wielkosc pliku:',FileSize(fx):8,' B, plik zawiera : ',(FileSize(fx) div SizeOf(osoba_)):6,' pozycji',#13#10);


    Bufsize:=FileSize(fx);

    GetMem(Buf,Bufsize);


    BlockRead(fx,Buf^,BufSize,Count);

    Close(fx);

    Wczytaj_osoby(Buf^, BufSize div SizeOf(osoba_) ); {wczytuje poprzez tablicę}


    Zapisz_osoby(Buf^, BufSize div SizeOf(osoba_) ); {przekształca dane w tablicy }


    Assign(fy,'osoby_.dat');

    Rewrite(fy,1);

    BlockWrite(fy, Buf^, BufSize, Count);

    FreeMem(Buf,Bufsize);

    Close(fy);

  end;


end.

{ ----------------------------------------------------------------------- }

Inny sposób, z możliwością tworzenia dużych struktur można znaleźć pod:

http://turbopascal.helion.pl/r-20.htm