Kurs Pascal - V. Tablice dynamiczne i statyczne

D.F.

Były Moderator
Dołączył
Listopad 4, 2009
Posty
493
I. Wstęp

Witaj. Przed Tobą część piąta kursu programowania w Pascalu dla początkujących. Będzie w niej mowa o tablicach. Tak jak poznane we wcześniejszej części procedury i funkcje, korzystanie z tablic jest to również bardzo przydatna umiejętność.


II. Tablice statyczne

Tablica jak nazwa wskazuje jest to zbiór danych, ułożonych w postaci tablicy, macierzy. Tablice mogą być jedno, dwu i więcej wymiarowe, jednak korzysta się głównie z jedno i dwuwymiarowych.
Tablice jednowymiarowe

Deklaracja przykładowej tablicy jednowymiarowej wygląda następująco:

Kod:
var
 tab1 : array[0..100] of Integer;

Powyższy kod zadeklaruje zmienną tablicową o nazwie tab1 o elementach od 0 do 100 (czyli wszystkich elementów będzie 101), każdy element będzie typu Integer.

Do danego elementu tablicy możemy odwołać się podając numer indeksu w nawiasach kwadratowych. Np. przypiszmy elementowi o indeksie 4 wartość 1.

Kod:
tab1[4] := 1;

Dla przykładu wypełnijmy teraz całą tablicę losowymi liczbami:

Kod:
 program Tablice1;

 uses CRT;

 //program główny
 var
   tab1 : array[0..20] of Integer;
   i : Integer;
 begin
   ClrScr();
   Randomize();
   for i := 0 to 20 do
   begin
     tab1[i] := Random(9);
     Write(tab1[i],' ');
   end;
   ReadLn();
 end.

W powyższym kodzie widać zadeklarowaną tablicę jednowymiarową o elementach od 0 do 20. Każdy element jest typu Integer. Niżej jest też zmienna, która jest licznikiem w pętli, zawierać ona będzie też jednocześnie indeks aktualnego elementu tablicy. Dalej widzimy procedurę czyszczącą ekran, po niej procedurę zapewniającą, że program za każdym uruchomieniem nie będzie losował tych samych liczb. W kolejnych linijkach widzimy pętle typu for, która wypełnia tablicę losowymi wartościami. Pętla wykona się 21 razy, przypisując elementom tablicy od 0 do 20 pseudolosową wartość.

Teraz pokażę kolejny kod, który posortuje elementy w tablicy od najmniejszej wartości do największej.

Kod:
 program Tablice1;

 uses CRT;

 var
   tab1 : array[0..20] of Integer;
   i, p, j, k : Integer;

 procedure FillTab1();
 begin
   for i := 0 to 20 do
   begin
     tab1[i] := Random(99);
   end;
 end;

 procedure SortTab1();
 begin
   j := 0;
   k := 1;
   //pętla sortująca
   while k>0 do
   begin
     j := j + 1;
     k := 0;
     for i := 0 to 20-j do
     begin
       if tab1[i] > tab1[i+1] then
       begin
         p := tab1[i+1];
         tab1[i+1] := tab1[i];
         tab1[i] := p;
         k := k + 1;
       end;
     end;
   end;
 end;

 procedure ShowTab1();
 begin
   for i := 0 to 20 do
   begin
     Write(tab1[i]:2,' ');
   end;
   WriteLn();
   WriteLn();
 end;

 begin
   ClrScr();
   Randomize();

   //wypełnij tablicę pseudolosowymi wartościami
   FillTab1();

   WriteLn('Zawartość tablicy:');

   //wyświetl zawartość tablicy
   ShowTab1();

   //wywołanie procedury sortowania bąbelkowego
   SortTab1();

   WriteLn('Zawartość tablicy posortowana rosnąco:');

   //wyświetl zawartość tablicy
   ShowTab1();

   ReadLn();
 end.

W powyższym programie poszczególne działania zostały umieszczone w osobnych procedurach. Tak zaprojektowany program jest bardziej czytelny, lepiej zoptymalizowany i łatwiejszy do modyfikacji. W większych programach własne procedury i funkcje dobrze jest umieścić sobie nawet w osobnym module (tworzeniu własnych bibliotek poświęcona jest osobna część tego kursu). Do ułożenia wartości tablicy w kolejności rosnącej zostało użyte sortowanie bąbelkowe. Działa ono tak, że sprawdzane są dwa sąsiadujące ze sobą elementy i jeżeli element poprzedni (o mniejszym indeksie) jest większy to zostają one zamienione miejscami .


Tablice dwuwymiarowe

Deklarujemy je podobnie jak tablice jednowymiarowe:

Kod:
var
 tab2 : array[0..10, 0..20] of Integer;

Powyższy kod deklaruje tablicę dwuwymiarową o rozmiarze 11 wierszy na 21 kolumn (wliczając elementy o indeksie zero) o elementach typu Integer.

Do danego elementu tablicy możemy odwołać się podając numer indeksu w nawiasach kwadratowych. Najpierw podajemy numer wiersza, następnie numer kolumny.
Np. przypiszmy elementowi w piątym wierszu i drugiej kolumnie wartość 0.

Kod:
tab2[5,2] := 0;



Teraz czas na przykładowy kod. Oto program sortujący rosnąco tablicę dwuwymiarową. Widać, że jest to nieco bardziej skompilowane niż przy tablicy jednowymiarowej.

Kod:
 program Tablice2;

 uses CRT;

 //zadeklarowane zmienne globalne
 var
   tab2 : array[0..5, 0..10] of Integer;
   m, n, c, p, i, j : Integer;

 //wypełnianie tablicy pseudolosowymi wartościami
 procedure FillTab2();
 begin
   for m := 1 to 5 do
   begin
     for n := 1 to 10 do
     begin
       tab2[m,n] := Random(100);
     end;
   end;
 end;

 //wyświetlenie zawartości tablicy
 procedure ShowTab2();
 begin
   for m := 1 to 5 do
   begin
     //pętla wyświetlająca zawartość danego wiersza
     for n := 1 to 10 do
     begin
       Write(tab2[m,n]:3,' ');
     end;
     //po wyświetleniu wiersza musi nastąpić przełamanie linii,
     //aby kolejny wiersz wyświetlił się w kolejnej linii
     WriteLn();
   end;
 end;

 //procedura sortująca
 procedure SortTab2();
 begin
   m := 5;
   n := 10;

   for c := 1 to 50 do
   begin
     //pętla sortująca wartości w wierszach
     for i := 1 to m do
     begin
       for j := 1 to n-1 do
       if tab2[i, j] > tab2[i, j+1] then
       begin
         p := tab2[i, j];
         tab2[i, j] := tab2[i, j+1];
         tab2[i, j+1] := p;
       end;
     end;

     //pętla sortująca wartości w kolumnach
     for i := 1 to m-1 do
     if tab2[i, n] > tab2[i+1, 1] then
     begin
       p := tab2[i, n];
       tab2[i, n] := tab2[i+1, 1];
       tab2[i+1, 1] := p;
     end;
   end;
 end;

 //Program główny
 begin
   ClrScr();
   Randomize();

   //wypełnienie tablicy pseudolosowymi wartościami
   FillTab2();

   //wyświetlenie zawartości tablicy
   ShowTab2();

   WriteLn();
   WriteLn('Aby posortować tablicę naciśnij dowolny klawisz...');
   ReadLn();

   //wywołanie procedury sortującej tablicę
   SortTab2();

   //wyświetlenie posortowanej tablicy
   ShowTab2();

   ReadLn();
 end.

Powyższy program ma podobną budowę do poprzedniego (z tablicami jednowymiarowymi). Odnajdź w powyższym kodzie procedurę o nazwie SortTab2(). Zajmuje się ona sortowaniem naszej tablicy. Najpierw sortowane są wartości w wierszach, robimy to tak jak z tablicami jednowymiarowymi, niżej widzimy dodatkową pętlę sortującą wartości w kolumnach. Spróbuj skompilować i uruchomić powyższy program normalnie, a następnie ujmij w komentarz pętlę sortującą wartości w kolumnach. Zobaczysz, że wartości w każdym wierszu zostały posortowane, jednak ogólnie cała tablica nie jest posortowana.

W obu przykładach użyłem prostego algorytmu sortowania nazywanego "sortowaniem bąbelkowym".


III. Tablice dynamiczne

Wcześniej deklarowane tablice miały przypisany stały rozmiar. Co jednak, jeśli nie wiemy jakiego rozmiaru tablica będzie potrzebna? Można na wszelki wypadek zadeklarować jakąś 100 000 na 100 000, ale to nie najlepszy pomysł ;)

Stworzymy zatem tablicę dynamiczną, której rozmiar będzie określany w trakcie działania programu.

Deklaracja takiej tablicy wygląda następująco:

Kod:
var
 Tablica : array of Integer;

Piszemy nazwę tablicy, dwukropek, słowa kluczowe array of, a po nich typ bazowy (takiego typu będą elementy tablicy).

Natomiast rozmiar tablicy ustalamy procedurą SetLength() podając w pierwszym parametrze nazwę zmiennej tablicowej, a w kolejnym rozmiar.

Kod:
SetLength(Tablica, n);

Przykładowy program pytający użytkownika jak długą tablicę chce zarezerwować, następnie wypełniający ją losowymi wartościami i wyświetlający zawartość tablicy.

Kod:
 program TabliceDynamiczne1;

 uses CRT;

 var
   Tablica : array of Integer;
   n, i : Integer;
 begin
   ClrScr();
   Randomize();

   WriteLn('Jakiej długości tablicę chcesz zaalokować?');
   ReadLn(n);

   //ustawienie długości tablicy
   SetLength(Tablica, n);

   //wypełnienie jej losowymi wartościami
   //i wyświetlenie 
   for i := 0 to n-1 do
   begin
     Tablica[i] := Random(100);
     Write(Tablica[i],' ');
   end;

   ReadLn();
 end.

Możemy również tworzyć tablice dynamiczne wielowymiarowe. Deklarujemy je powtarzając słowa kluczowe array of, np. w ten sposób:

Kod:
 var
   Tablica : array of array of Integer;

Powyższy kod, tłumacząc dosłownie stworzy "tablicę tablic jednowymiarowych", czyli tablicę dwuwymiarową.

Oto przykładowy program pytający użytkownika o rozmiary dwuwymiarowej tablicy dynamicznej, ustawiający rozmiary tablicy, wypełniający ją losowymi liczbami i wyświetlający jej zawartość.

Kod:
 program TabliceDynamiczne2;

 uses CRT;

 var
   Tablica : array of array of Integer;
   m, n, i, j : Integer;
 begin
   ClrScr();
   Randomize();

   WriteLn('Ile wierszy ma mieć tablica?');
   ReadLn(m);
   WriteLn('Ile kolumn ma mieć tablica?');
   ReadLn(n);

   //ustawienie długości tablicy
   SetLength(Tablica, m, n);

   WriteLn('Oto ta tablica, wypełniona losowymi wartościami:');

   //wypełnienie jej losowymi wartościami
   //i wyświetlenie
   for i := 0 to m-1 do
   begin
     for j := 0 to n-1 do
     begin
       Tablica[i,j] := Random(100);
       Write(Tablica[i,j]:3,' ');
     end;
     WriteLn();
   end;

   ReadLn();
 end.


IV. Stałe tablicowe

Tablicę o stałej wartości możemy zadeklarować następująco:

Kod:
const
 Tablica : array[0..3] of Char = ('a', 'b', 'c', 'd');

Podajemy najpierw nazwę tablicy, po dwukropku i słowie kluczowym array w nawiasach kwadratowych podajemy rozmiar, dalej mamy słowo kluczowe of, po którym podajemy typ stałej, następnie po znaku równości w nawiasach okrągłych wypisujemy wartości poszczególnych elementów tablicy oddzielone przecinkiem.

Przykładowy program z zadeklarowanymi dwoma stałymi tablicowymi:

Kod:
 program StaleTablicowe;

 uses CRT;

 const
   Tablica : array[0..3] of Char = ('a', 'b', 'c', 'd');
   Tablica2 : array[0..9] of Byte = (1,2,3,4,5,6,7,8,9,0);
 var
   i : Integer;
 begin
   ClrScr();

   //wyświetl zawartość stałej tablicowej Tablica
   WriteLn('Tablica:');
   for i := 0 to 3 do
   begin
     Write(Tablica[i], ' ');
   end;

   //przejdź dwa wiersze niżej 
   WriteLn();
   WriteLn();

   //wyświetl zawartość stałej tablicowej Tablica2
   WriteLn('Tablica2:');
   for i := 0 to 9 do
   begin
     Write(Tablica2[i], ' ');
   end;

   ReadLn();
 end.

Kod powyżej ma zadeklarowane dwie stałe tablicowe. Jedna zawiera litery a, b, c, d, natomiast druga zawiera cyfry od 0 do 9. Niżej są dwie pętle wyświetlające wartości z tablicy.


V. Zakończenie

Piątą część kursu masz już za sobą. Poznałeś czym są tablice i jak wykonywać na nich różne operacje.
 
Do góry Bottom