Struktury i typy danych
Do czego służą
W Turbo Pascalu można używać różnych formatów danych, takich jak liczba, napis, znak.
Istnieją różne typy, niektóre zajmują mniej pamięci i są mniej dokładne, inne zajmują więcej
pamięci, za co mają większą precyzję. Te dłuższe zazwyczaj wymagają też więcej czasu
pracy procesora. Podstawowe typy danych zostały opisane w rozdziale Pierwsze programy,
Zmienne.
Struktury danych pozwalają komputerowi w łatwiejszy sposób przetwarzać informacje,
szybciej zapisywać do pliku, lepiej organizować w pamięci, szybciej wyszukiwać i ułatwić
pracę programiście.
Tablice
W bibliotece znajdują się szafki z kartotekami skatalogowanych książek. W każdej szafce są
takie kartoteki. Tych szafek jest dość dużo. Są poustawiane obok siebie. Każda szuflada ma
swój numer, czy literę. Są w nich tylko kartoteki. Jeśli biblioteka jest duża, regałów z
kartotekami może być wiele.
Tablice są podobne do szuflad bibliotecznych. Tablica składa się z wielu 'schowków',
poustawianych obok siebie w pamięci. W tablicy znajdują się tylko zmienne i to zmienne
jednego typu. Każdy element tablicy ma swój indeks. Tablice mogą być wielowymiarowe, nie
tylko w poziomie, ale i w pionie a nawet wgłąb.
Do czego służą? Przechowują grupy danych. Mogą zawierać listę liczb. Mogą zawierać
kartoteki pracowników -ich nazwiska, imiona, bądz całe rekordy z danymi.
Aby je zadeklarować używa się w sekcji var wyrażenia: Array[{min}..{max}] of {...}
var tablica : Array[0..30] of Integer;
tablica_imion : Array[1..10] of string;
tab2 : Array[0..30, 1..3] of Integer; {tablica dwuwymiarowa}
A jak się odwoływać w programie do tablic?
Tablica[1] := 1; {zwykłe podstawienie}
for i:= 0 to 30 do {w pętli...}
tablica[i] := 0; {wyzerowanie całej tablicy}
tab2[i][1] := x; {dwuwymiarowa}
tab2[i, 1] := x; {drugi sposób}
{*****************************************}
{wczytanie i wyświetlenie 10 imion w pętli}
for i:= 1 to 10 do {w pętli...}
begin
Write('Podaj ', i, ' imię: ');
ReadLn(tablica_imion[i]);
end;
WriteLn('Wpisane imiona:');
for i:= 1 to 10 do {w pętli...}
begin
Write(tablica_imion[i]);
end;
Aatwo zauważyć, że do tablicy można się odwoływać za pomocą indeksu. I właściwie o to
chodzi w używaniu tablic. Pozwalają znacznie zaoszczędzić czasochłonne wklepywanie kodu.
Przypuśćmy, że w tablicy liczb Integer, o nazwie tablica chcesz znalezć wartość największą.
Jak to zrobić? Trzeba przejść przez całą tablicę i sprawdzić, czy kolejny element jest większy
nich dotychczas największy. Uwaga, na początku elementem dotychczas największym musi
być ten, który jest pierwszym elementem tablicy, nie 0. Dlaczego? Ponieważ gdy tablica
będzie zawierała jedynie liczby ujemne, program uważałby, że największą dotychczasową
wartością jest 0, a tak nie będzie.
var tablica : Array[0..30] of Integer;
i, max : Integer;
begin
{tutaj można wypełnić tablicę jakimiś wartościami, np. losowymi}
Randomize; {Inicjowanie losowania}
for i:= 0 to 30 do {w pętli...}
tablica[i] := Random(100) - Random(100); {losowanie w zakresie -99..+99}
max := tablica[0];
for i:= 1 to 30 do {w pętli...}
begin
{Jeśli największy dotychczas element jest mniejszy niż badany...}
if max < tablica[i] then
max := tablica[i];{zmień dotychczas największy}
end;
{tu możesz wyświetlić max}
WriteLn('Max: ', max);
end.
Własne typy danych
Czasami zachodzi potrzeba utworzenia własnego typu -tzw. rekordu, który będzie
przechowywał wymyślone przez nas dane. Przypuśćmy że chciałbyś zbudować prostą bazę
danych zawierającą imiona i nazwiska swoich klientów. Zamiast przechowywać wszelkie
dane w osobnych tablicach np.
const
MaxDanych = 200;
var
{imiona - tablica o rozmiarze MaxDanych elementów }
imiona : array[0..MaxDanych-1] of string[20];
nazwiska : array[0..MaxDanych-1] of string[30];
telefony : array[0..MaxDanych-1] of string[20];
{...}
{odwoływanie}
imiona[10]:='Moje Imię';
nazwiska[10]:='Moje Nazwisko';
telefony[10]:='0700 00 000';
Można pogrupować je blisko siebie. W taki sposób by znajdowały się obok siebie w pamięci
(jest bardziej fachowo).
Można to zrobić choćby tak:
const
MaxDanych = 200;
type
TDaneOsobowe = record
imie : string[20];
nazwisko : string[30];
telefon : string[20];
rok_ur : integer;
end;
var
Dane : array[0..MaxDanych-1] of TDaneOsobowe;
{& }
{odwoływanie}
Dane[0].imie := 'Moje imie';
Dane[0].nazwisko := 'Moje nazwisko';
Dane[0].telefon := '0 700 00 000';
Dane[0].rok_ur := 1999;
{lub za pomocą with uproszczenie}
with Dane[0] do
begin
imie := 'Moje imie';
rok_ur := 1999;
end;
W przykładzie zademonstrowano korzystanie z polecenia with - które dla każdego elementu
wewnątrz dodaje przedrostek, w typ wypadku Dane[0]. Dzięki temu poleceniu możemy
znacznie skrócić kod.
Do tablicy własnego rekordu można odnosić się jak do każdej innej tablicy. Można
przeglądać tą tablicę za pomocą pętli i zmiennej iterowanej (zwiększanej).
Wskazniki w turbo pascalu (pointer)
Wskazniki przypominają spis treści w grubej książce. Gdybyś podczas rozmowy telefonicznej
chciał wskazać koledze konkretne miejsce w jakiejś publikacji, co zrobisz? Czy powiesz mu,
otwórz swoją książę na zdaniu... I tu zaczniesz cytować, czy raczej podasz numer strony?
Oczywiście numery stron są lepsze, bo ułatwiają szybie odnajdywanie miejsc. Tak samo
wskazniki w programowaniu -pozwalają przeszukiwać spore ilości danych bez wertowania
całej pamięci. Podobnie jak przy rozmowie przez telefon, tak samo przy porozumiewaniu się
między procedurami w programie potrzeba jak najściślejszych, ale jak najszybszych
informacji.
Wskazniki to adresy pamięci, które pokazują komputerowi miejsce gdzie znajdują się jakieś
dane. Możesz przykładowo przechowywać w pamięci wskaznik na obrazek bitmapowy,
podczas gdy przechowywanie obrazu w tablicy byłoby niezbyt praktyczne. Pamięć do której
odnoszą się wskazniki można w każdej chwili zwalniać, deklarować i zmieniać.
Bez wskazników nie byłoby możliwe nieograniczone tworzenie nowych danych, np. w
słowniku. Gdyby nie wskazniki mielibyśmy z góry określoną liczbę słów, które słownik
byłby w stanie zapamiętać. W grach komputerowych, liczba ludzików, zbudowanych
elementów w strategii, zawsze byłaby z góry ograniczona. Nie moglibyśmy w systemie
uruchomić większej liczby programów niż zaplanowano.
Wskazniki mogą wskazywać na dowolny obszar pamięci, a adres ten można zmieniać. Są
pomocne podczas alokacji pamięci. Kiedy chcemy ją zadeklarować w czasie trwania
programu, funkcja GetMem zwraca nam właśnie wskaznik -czyli miejsce gdzie będziemy
mogli wpisywać swoje dane. Gdybyśmy spróbowali wspisać swoje dane bez wcześniejszego
zarezerwowania pamięci, w najlepszym wypadku zakończyłby się nasz program, w gorszym
zawiesilibyśmy komputer.
Budowa wskazników*
Ze względu na ryzoko zawieszenia programu wskazniki są traktowane jako typy, które należy
umiejętnie stosować. Wskazniki na ogół zbudowane są z 4 bajtów. Pierwsze 2 określają
segment danych, kolejne 2 ofset.
Pamięć konwencjonalna (pierwszy 1MB pamięci komputera) podzielony jest na segmenty po
16KB każdy. Tak więc 1 segment ma adres 0, drugi 1, trzeci 2, itd... Ofset to przemieszczenie
względem segmentu. Dzięki ofsetowi możemy dojść do każdego jednego bajtu pamięci.
Adres typu pointer składa się z dwóch bajtów segmentu, dwóch ofsetu i jest najczęściej
zapisywany w kodzie szesnastkowym, dzięki czemu jest bardziej czytelny, np.
$a000:00, $b800:00
Typ pointer
Typ wskazników nazywa się pointer. Gdy jakąś zmienną zadeklarujesz jako poiner, będzie
ona wskaznikiem. Wskazniki mogą adresować różne typy zmiennych. Mogą adresować
liczby, napisy, tablice, itd. Gdy adresują konkretny typ, nie deklaruje się ich jako pointer,
tylko tworzy swój własny typ -o tym przeczytasz za moment.
Podstawianie wskazników
Żeby wskaznik wskazywał adres jakiejś zmiennej, możemy napisać:
var
wskaznik : pointer; {lub podobny typ}
{...}
wskaznik := @nazwa_zmiennej;
znacznik @ oznacza pobranie adresu zmiennej. Gdybyśmy chcieli teraz coś zapisać pod
wskazanym miejscem wystarczy wywołać wskazywane miejsce, za pomocą znaku ^
wskaznik^ := nowa_wartosc;
W podanym przykładzie trzeba by wskaznik był zadeklarowany jako wskaznik na liczbę.
Gdybyśmy bez rzutowania i bez określenia rodzaju wkaznika próbowali mu podstawić
wartość wystąpiłby błąd "illegal assigment".
Jak zadeklarować wskaznik na liczbę?
np.
type p_liczba = ^integer; {utworzenie nowego typu - wskaznika na liczbę}
var liczba : p_liczba;
i : integer;
begin
liczba := @i;
i:=2;
liczba^:=4;
end.
{teraz i = 4 a nie 2!}
Można ewentualnie potraktować typ pointer jako wskaznik na liczbę co nazywa się
rzutowaniem -dzięki temu unikniemy błędu a powiemy kompilatorowi, że wpisujemy w
niego liczbę Integer
var liczba : pointer;
i : integer;
begin
liczba := @i;
i:=2;
integer(liczba^):=4;
end.
Wyszukiwarka
Podobne podstrony:
Typy danych w MySQL05 Normalizacja struktury bazy danych (AC)Typy Danych w Pascalutypy danychobiekty i typy danychWyklad 1 program typy danych05 Zlozone typy danych cwiczenia przygotowujacetablica funkcji i operatorów typy danychLekcja jej struktura i typyProgramowanie i jezyk C Wyklad 01 Typy danychTYPY DANYCHtypy danych rejestruIstota i struktury hurtowni danych Zasady eksploracji danych12 Część IV Zagadnienia praktyczne Typy danychTypy danych rejestruWyklad 1 program typy danychwięcej podobnych podstron