| | IKT i praksis - Pascal |
|
Array (tabell)I svært mange samanhengar er det enklare å lagre eller handtere data i form av tabellar enn som enkeltvariabler. I Pascal finst det fleire metodar for å lage slike tabellar, eller array som det heiter i programmeringsspråka. Alt avhengig av kva tabellen skal brukast til, kan ein i Pascal velje ein- eller fleir-dimensjonale tabellar. I tillegg også statiske og dynamiske utgåver av desse. Dette kapitlet vil ta føre seg noen av bruksmåtane. Enkel arrayI dette første eksemplet ønskjer eg å lagra maksimumstemperaturane for kvar dag i ein månad. Sjølvsagt kunne eg ha laga til 31 variablar med namn som dag1, dag2, dag3 osv. Men i staden definerer eg ein tabell:
var temp: array[1..31] of real;
Tala [1..31] definerer tabellen til å innehalde 31 element, eitt element for kvar dag i månaden, nummererte frå 1 til 31. Prikkane er to punktum etter kvarandre. Desse tala blir kalla «indekstal», eller i programverda helst index. Dei må alltid skrivast mellom hakeparentesar.
Den 1. januar les eg av temperaturen til å vere -5,0 grader. Dette blir skrive inn i tabellen slik: For å hente ut data, skriv eg t.d. Fleirdimensjonal arrayDen definerte tabellen, temp[1..31], kan innehalde data for ein månad. Det neste steget er å lage ein tabell
som kan innehalde data for kvar månad i eitt år. Dette kan gjerast på fleire måtar, men ein nokså forståeleg måte er
å definere tabellen som ein tabell med 12 månader der kvar månad igjen er ein tabell med 31 dagar. Definisjonen kan
då vere: Du kan definere så mange dimensjonar du måtte ha bruk for. Blir temperaturen registrert kvar time i døgnet,
kan du definere ein 3. dimensjon som inneheld timane:
var aaret: array[1..12, 1..31,0..23] of Real; Array av RecordEr du svært pirkete, vil du ha funne ut at det i grunnen ikkje er nødvendig å bruke desimaltal (Real) i temperaturlista anna enn for temperaturen. Dei andre verdiane er heiltal. I Pascal er det ikkje råd å blande element av ulike typer som t.d. Integer, String osv. i ein tabell. Difor måtte eg velje Real sidan denne kan brukast for alle variablane i dette tilfellet. Har ein behov for å lage ein tabell med ulike typer, kan ein definere ein datatype som inneheld dei ønskte
verdiane. Akkurat i temperatureksempelet er det kanskje like enkelt å bruke array nettopp slik det er gjort, men
andre gonger kan andre løysingar vere enklare. Sett at du har eit kryssordprogram som mellom anna skal innehalde
ein tabell med løysingsordet, stikkord og nummer for plasseringa i rutemønsteret. I tillegg om ordet er vassrett eller
loddrett. For å kunne plassere ordet korrekt i diagrammet, bør tabellen også innehalde koordinata for første bokstav
i ordet. Eg definerer difor ein Type som inneheld alle dei nødvenige data for kvart løysingsord i kryssordet. Neste steg er å definere ein tabell som kan innehalde alle orda i kryssordet. Dersom ein går ut frå at det ikkje er
nødvendig med meir enn 100 løysingsord, kan tabellen definerast slik: For å fylle inn dei aktuelle verdiane i tabellen, kan dette gjerast slik: For å hente ut igjen data frå tabellen er det som vanleg bare å gå andre vegen: Dynamisk tabellDet er slettes ikkje alltid at ein på førehand veit kor stor ein tabell må vere for å dekke alle behova. I slike tilfelle, som t.d. i eksemplet ovanfor, kan det vere greit å utvide tabellen etter kvart som behova melder seg. Då er dynamiske tabellar løysinga. Alle tabellar som kan definerast som ein- eller fleirdimensjonerte kan også definerast som dynamiske. Først ei lita åtvaring. Når ein programmerer i Pascal kjem det gjerne opp ei melding om kva som er feil dersom ein gjer tabber i kodeinnskrivinga. Dette gjeld også køyretidsfeil (Run Time Error), som t.d. kan fortelje at ein variabel er blitt tileigna verdiar utanom det han er definert for. Når ein prøver ut dynamiske tabellar, finst det ikkje noe slik feilmelding. Du får i staden opp ei melding om at det er køyretidsfeil, utan nærare forklaring. I Lazarus kjem meldinga «Project dynamic.exe raised exception class 'External: SIGSEGV'.» opp. Dette betyr at eit eller anna har gått gale under køyringa av programmet, men seier ikkje noe om kva som er gale. Du må altså sjølv finne feilen. Tilbake til emnet. I kryssordtabellen veit vi eigentleg ikkje kor mange innskrivingar som trengst for kvart
kryssord. Det er altså naturleg å definere lengda på tabellen etter kvart som vi skriv inn nye data. Først må vi
definere tabellen som «dynamic». Dette er nokså enkelt. Vi gjer det på same måten som for dimensjonerte
tabellar, men sløyfer lengda. Altså: Nå gjeld det bare å halde styr på kor lang tabellen må vere. For kvar gong du skriv eit nytt ord inn i tabellen, aukar du variabelen lengde med 1. Enklast med inc(lengde); Deretter må du definere ny lengde for tabellen: SetLength(xord, lengde); I Pascal blir dei dynamiske tabellane definerte med første element som 0. Ein tabell med lengde 10 inneheld elementa tabell[0], tabell[1] osv til tabell[9]. Det siste elementet i tabellen er altså lengde - 1. Fort gjort å gløyme dette. Det er nokså viktig å halde styr på lengda av tabellen. Difor noen eksempel på korleis vi kan kontrollere tabellen: Dersom programmet inneheld fleire stader der variabelen lengde blir forandra, kan det vere lurt å definere ny lengde på tabellen som lengde := length(xord) + 1 og deretter bruke SetLength(xord,lengde); Utskriving frå dynamiske tabellar Greier ein å halde styr på kor lang tabellen er til ei kvar tid, kan ein bruke vanleg for - to løkke Ein sikrare metode for å unngå køyretidsfeil, er å bruke Fjerne element Det finst ingen enkeltkommando for å fjerne element frå ein dynamisk tabell. Eg måtte difor tenke litt sjølv, og kom fram til ein liten programsnutt for denne jobben. Her går eg ut frå at tabellen tabell er globalt definert, altså at han kan nåast frå alle stader i programmet. procedure slettElement(nr: Integer);var sist, x: Integer; begin sist := high(kryssord); if nr in [0,sist] then begin if (nr < sist) then for x := nr to sist-1 do tabell[x] := tabell[x+1]; setLength(tabell,length(tabell)-1); end; end; Litt forklaring. Variabelen sist blir tileigna verdien for indeksen til det siste elementet i tabellen. For å sikre seg at det elementet som skal fjernast har ein gyldig indeksverdi, vil prosedyren bli utført bare dersom verdien er innføre dei verdiane tabellen har. Dette skjer i if nr in [0,sist] som kontollerer at verdien er frå og med 0 til og med indeksen for siste element. Løkka for - to vil då flytte alle elementa som har høgare verdi enn nr eitt hakk nedover på lista. Det elementet som skal fjernast blir såleis overskrive av det elementet som ligg eitt hakk høgare. Det siste elementet får ikkje noen ny verdi, men blir fjerna likevel med kommandoen SetLength som set lengda på tabellen til 1 mindre enn den opphavlege lengda. For spesialistaneEin dynamisk tabell er eigentleg ein peikar. Når du endrar lengda på tabellen, vil det bli frigitt eller okupert minne i datamaskinen alt etter som tabellen blir gjort mindre eller større. Set du verdien til NIL, eller lengda til 0, vil tabellen forsvinne og heile minneplassen tabellen opptar bli frigitt. Ut frå det eg har forstått, vil programmet automatisk frigjere minneplass når det blir avslutta. Håper det stemmer.
|