Difference between revisions of "Dynamic array/fi"
(Created page with "{{Dynamic array}} =Dynaaminen taulukko= Dynaaminen taulukko on taulukko, jonka mittoja ei tunneta käännösaikana. Dynaaminen taulukko-tyyppi ei ole ainoa sell...") |
|||
Line 11: | Line 11: | ||
Dynaamisen taulukon indeksit ovat aina ei-negatiivisia kokonaislukuja, jotka alkavat nollasta joka vastaa ensimmäistä elementtiä. | Dynaamisen taulukon indeksit ovat aina ei-negatiivisia kokonaislukuja, jotka alkavat nollasta joka vastaa ensimmäistä elementtiä. | ||
− | Lueteltua tyyppiä, muuta ordinaalityyppiä ei voida käyttää indeksinä tai muuttaa ensimmäistä elementtiä, joka on määritetty indeksillä <syntaxhighlight lang="pascal" | + | Lueteltua tyyppiä, muuta ordinaalityyppiä ei voida käyttää indeksinä tai muuttaa ensimmäistä elementtiä, joka on määritetty indeksillä <syntaxhighlight lang="pascal" inline>1</syntaxhighlight>. |
== määritelmä == | == määritelmä == | ||
Line 29: | Line 29: | ||
=== Mitoitus === | === Mitoitus === | ||
− | Kääntäjän [[Procedure/fi|aliohjelma]] {{Doc|package=RTL|unit=system|identifier=setlength|text=<syntaxhighlight lang="pascal" | + | Kääntäjän [[Procedure/fi|aliohjelma]] {{Doc|package=RTL|unit=system|identifier=setlength|text=<syntaxhighlight lang="pascal" inline>setLength</syntaxhighlight>}} muuttaa dynaamisen taulukon pituutta edellyttäen, että muistia on riittävästi. |
<syntaxhighlight lang="pascal" line highlight="5"> | <syntaxhighlight lang="pascal" line highlight="5"> | ||
Line 43: | Line 43: | ||
Sitten se {{Doc|package=RTL|unit=system|identifier=copyarray|text=''kopioi''}} kaikki vanhan inkarnaation elementit uuteen. | Sitten se {{Doc|package=RTL|unit=system|identifier=copyarray|text=''kopioi''}} kaikki vanhan inkarnaation elementit uuteen. | ||
− | Myös moniulotteiset taulukot voidaan muuttaa <syntaxhighlight lang="pascal" | + | Myös moniulotteiset taulukot voidaan muuttaa <syntaxhighlight lang="pascal" inline>setLength</syntaxhighlight> aliohjelmalla. |
<syntaxhighlight lang="pascal" line highlight="5"> | <syntaxhighlight lang="pascal" line highlight="5"> | ||
Line 53: | Line 53: | ||
end. | end. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Taulukon <syntaxhighlight lang="pascal" | + | Taulukon <syntaxhighlight lang="pascal" inline>samples</syntaxhighlight> ensimmäisen ulottuvuuden todelliset indeksit ovat <syntaxhighlight lang="pascal" inline>0..11</syntaxhighlight> kun taas toisen ulottuvuuden kelvolliset indeksit ovat alueella <syntaxhighlight lang="pascal" inline>0..63</syntaxhighlight>. |
Yksi varsin hyödyllinen tosiasia on, että rajoituksen, jonka mukaan kaikkien ulottuvuuksien on oltava samankokoisia, ei sovelleta dynaamisiin taulukoihin. | Yksi varsin hyödyllinen tosiasia on, että rajoituksen, jonka mukaan kaikkien ulottuvuuksien on oltava samankokoisia, ei sovelleta dynaamisiin taulukoihin. | ||
Line 92: | Line 92: | ||
=== Alustus === | === Alustus === | ||
− | FPC:n versiosta 3.0.0 lähtien dynaaminen taulukko, jotka eivät ole anonymous, varustetaan automaattisesti “constructor” (rakentajalla), koska se on tuttua olio-ohjelmoinnista. Tämän avulla voit yhdistää <syntaxhighlight lang="pascal" | + | FPC:n versiosta 3.0.0 lähtien dynaaminen taulukko, jotka eivät ole anonymous, varustetaan automaattisesti “constructor” (rakentajalla), koska se on tuttua olio-ohjelmoinnista. Tämän avulla voit yhdistää <syntaxhighlight lang="pascal" inline>setLength</syntaxhighlight>-kutsu ja joukon toimeksiantoja yhteen lausekkeeseen: |
<syntaxhighlight lang="pascal" line highlight="7"> | <syntaxhighlight lang="pascal" line highlight="7"> | ||
Line 128: | Line 128: | ||
Pitää pitää mielessä että dynaamiset taulukot ovat viitteitä. Dynaamisten taulukkomuuttujien "suora kopiointi" toisilleen ei kopioi mitään hyötykuormaa, vaan vain osoiteen. Tämä eroaa staattisten taulukkojen käyttäytymisestä. | Pitää pitää mielessä että dynaamiset taulukot ovat viitteitä. Dynaamisten taulukkomuuttujien "suora kopiointi" toisilleen ei kopioi mitään hyötykuormaa, vaan vain osoiteen. Tämä eroaa staattisten taulukkojen käyttäytymisestä. | ||
− | Jos halutaan kopioida tietoja, niin on käytettävä {{Doc|package=RTL|unit=system|identifier=copy|text=<syntaxhighlight lang="pascal" | + | Jos halutaan kopioida tietoja, niin on käytettävä {{Doc|package=RTL|unit=system|identifier=copy|text=<syntaxhighlight lang="pascal" inline>system.copy</syntaxhighlight>}}.-tiedostoa. |
<syntaxhighlight lang="pascal" line highlight="25"> | <syntaxhighlight lang="pascal" line highlight="25"> | ||
program dynamicArrayCopyDemo(input, output, stdErr); | program dynamicArrayCopyDemo(input, output, stdErr); | ||
Line 161: | Line 161: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Vain käyttämällä <syntaxhighlight lang="pascal" | + | Vain käyttämällä <syntaxhighlight lang="pascal" inline>copy</syntaxhighlight> kopiointia molempia taulukoita voidaan muokata itsenäisesti. |
− | Kuten edellä todettiin niin tässä <syntaxhighlight lang="pascal" | + | Kuten edellä todettiin niin tässä <syntaxhighlight lang="pascal" inline>setLength</syntaxhighlight> kopioi tiedot. Yllä olevan esimerkin korostettu rivi vastaa (semanttisesti) <syntaxhighlight lang="pascal" inline>setLength(bar, length(bar))</syntaxhighlight>. |
− | Dynaamisella taulukolla on "viitelaskuri". Kutsuminen <syntaxhighlight lang="pascal" | + | Dynaamisella taulukolla on "viitelaskuri". Kutsuminen <syntaxhighlight lang="pascal" inline>setLength(myDynamicArrayVariable, 0)</syntaxhighlight> on käytännössä [[Nil/fi|<syntaxhighlight lang="pascal" inline>myDynamicArrayVariable := nil</syntaxhighlight>]] ja pienentää viitemäärää. Ainoastaan kun viitteiden määrä laskee nollaan, muistilohko vapautetaan. |
<syntaxhighlight lang="pascal" line highlight="9,10,15"> | <syntaxhighlight lang="pascal" line highlight="9,10,15"> | ||
Line 188: | Line 188: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Dynaamiset taulukot kuitenkin loppukäsitellään automaattisesti. Ei tarvitse asettaa manuaalisesti kaikkiin viitteisiin <syntaxhighlight lang="pascal" | + | Dynaamiset taulukot kuitenkin loppukäsitellään automaattisesti. Ei tarvitse asettaa manuaalisesti kaikkiin viitteisiin <syntaxhighlight lang="pascal" inline>setLength(…, 0)</syntaxhighlight>, kun ohjelma päättyy tai kun siirrytään osiosta pois. |
− | Ilman <syntaxhighlight lang="pascal" | + | Ilman <syntaxhighlight lang="pascal" inline>{$rangeChecks on}</syntaxhighlight> on mahdollista saavuttaa taulukon rajat. Tämä tarkoittaa, että kun iteroidaan dynaamisia taulukkoja, on mahdotonta työskennellä ilman {{Doc|package=RTL|unit=system|identifier=low|text=<syntaxhighlight lang="pascal" inline>low</syntaxhighlight>}} ja {{Doc|package=RTL|unit=system|identifier=high|text=<syntaxhighlight lang="pascal" inline>high</syntaxhighlight>}} määrittämään kelvollisia indeksejä (ensimmäinen on valinnainen, koska dynaamiset taulukot alkavat aina nollasta). |
− | Vaihtoehtoisesti voidaan käyttää [[for-in loop|<syntaxhighlight lang="pascal" | + | Vaihtoehtoisesti voidaan käyttää [[for-in loop|<syntaxhighlight lang="pascal" inline>for … in</syntaxhighlight> looppia silmukoissa]], jos indeksiä ei tarvita. |
− | Muista, että [[SizeOf#dynamic arrays and alike|<syntaxhighlight lang="pascal" | + | Muista, että [[SizeOf#dynamic arrays and alike|<syntaxhighlight lang="pascal" inline>sizeOf</syntaxhighlight>]] arvioi dynaamisen taulukon osoittimen koon. |
== Sovellukset== | == Sovellukset== | ||
− | * Käytössä on {{Doc|package=RTL|unit=system|identifier=tboundarray|text=<syntaxhighlight lang="pascal" | + | * Käytössä on {{Doc|package=RTL|unit=system|identifier=tboundarray|text=<syntaxhighlight lang="pascal" inline>system.tBoundArray</syntaxhighlight>}} ja {{Doc|package=RTL|unit=objpas|identifier=tboundarray|text=<syntaxhighlight lang="pascal" inline>objPas.tBoundArray</syntaxhighlight>}} |
== Katso myös == | == Katso myös == | ||
− | * [[String|<syntaxhighlight lang="pascal" | + | * [[String|<syntaxhighlight lang="pascal" inline>string</syntaxhighlight>]] |
* esimerkki: [[Example: Multidimensional dynamic array|multidimensional dynamic array]] | * esimerkki: [[Example: Multidimensional dynamic array|multidimensional dynamic array]] | ||
* [https://www.freepascal.org/docs-html/ref/refsu14.html#x38-510003.3.1 Free Pascal Reference guide: “Dynamic arrays”] | * [https://www.freepascal.org/docs-html/ref/refsu14.html#x38-510003.3.1 Free Pascal Reference guide: “Dynamic arrays”] |
Latest revision as of 17:19, 6 August 2022
│
English (en) │
español (es) │
suomi (fi) │
français (fr) │
日本語 (ja) │
русский (ru) │
Dynaaminen taulukko
Dynaaminen taulukko on taulukko, jonka mittoja ei tunneta käännösaikana. Dynaaminen taulukko-tyyppi ei ole ainoa sellainen tyyppi, joka tarjoaa vaihtelevan pituisen taulukon, mutta (vuonna 2018) se on ainoa mitä Free Pascal-tukee.
Käyttö
Käsite
Dynaaminen taulukon määritys varaa tilaa vain osoittimelle. Ajon aikana eri rutiinit varmistavat sen kätevän käytön, mutta tärkeintä on, että kääntäjä tukee matriisin elementtien pääsyä sijoittamalla indeksit hakasulkeisiin (toteutetaan osoittimen automaattisena viittauksena).
Dynaamisen taulukon indeksit ovat aina ei-negatiivisia kokonaislukuja, jotka alkavat nollasta joka vastaa ensimmäistä elementtiä.
Lueteltua tyyppiä, muuta ordinaalityyppiä ei voida käyttää indeksinä tai muuttaa ensimmäistä elementtiä, joka on määritetty indeksillä 1
.
määritelmä
Yksiulotteinen dynaaminen taulukko on määritellään seuraavasti:
array of char
Huomaa, miten taulukon kokoa ei ole määritetty.
Moniulotteisen taulukon määrittelemiseksi, perustyypiksi määritetään itse taulukko.
array of array of longInt
Mitoitus
Kääntäjän aliohjelma setLength
muuttaa dynaamisen taulukon pituutta edellyttäen, että muistia on riittävästi.
1program setLengthDemo(input, output, stdErr);
2var
3 sieve: array of longWord;
4begin
5 setLength(sieve, 1337);
6end.
Aliohjelma varaa muistia annetun määrän mukaisesti kyseisen tyypin tietueelle ja myös joillekin hallintatiedoille. Sitten se kopioi kaikki vanhan inkarnaation elementit uuteen.
Myös moniulotteiset taulukot voidaan muuttaa setLength
aliohjelmalla.
1program multidimensionalSetLengthDemo(input, output, stdErr);
2var
3 samples: array of array of smallInt;
4begin
5 setLength(samples, 12, 64);
6end.
Taulukon samples
ensimmäisen ulottuvuuden todelliset indeksit ovat 0..11
kun taas toisen ulottuvuuden kelvolliset indeksit ovat alueella 0..63
.
Yksi varsin hyödyllinen tosiasia on, että rajoituksen, jonka mukaan kaikkien ulottuvuuksien on oltava samankokoisia, ei sovelleta dynaamisiin taulukoihin.
1program binomialPotence(input, output, stdErr);
2var
3 pascalsTriangle: array of array of longWord;
4 exponent: longInt;
5 factor: longInt;
6begin
7 setLength(pascalsTriangle, 20);
8
9 setLength(pascalsTriangle[0], 1);
10 pascalsTriangle[0][0] := 1;
11
12 setLength(pascalsTriangle[1], 2);
13 pascalsTriangle[1][0] := 1;
14 pascalsTriangle[1][1] := 1;
15
16 // construct values by simple addition
17 for exponent := 2 to high(pascalsTriangle) do
18 begin
19 setLength(pascalsTriangle[exponent], exponent + 1);
20 pascalsTriangle[exponent][0] := 1;
21 pascalsTriangle[exponent][exponent] := 1;
22 for factor := 1 to exponent - 1 do
23 begin
24 pascalsTriangle[exponent][factor] :=
25 pascalsTriangle[exponent - 1][factor - 1] +
26 pascalsTriangle[exponent - 1][factor];
27 end;
28 end;
29
30 // ...
Alustus
FPC:n versiosta 3.0.0 lähtien dynaaminen taulukko, jotka eivät ole anonymous, varustetaan automaattisesti “constructor” (rakentajalla), koska se on tuttua olio-ohjelmoinnista. Tämän avulla voit yhdistää setLength
-kutsu ja joukon toimeksiantoja yhteen lausekkeeseen:
1program dynamicArrayCreateDemo(input, output, stdErr);
2type
3 truths = array of boolean;
4var
5 l: truths;
6begin
7 l := truths.create(false, true, true, false, true, false, false);
8end.
Voidaan tietysti käyttä myös sisäkkäisiä taulukoita:
1program nestedDynamicArrayCreateDemo(input, output, stdErr);
2type
3 truths = array of boolean;
4 pattern = array of truths;
5var
6 p: pattern;
7begin
8 p := pattern.create(
9 truths.create(false, false),
10 truths.create(true, false),
11 truths.create(true, false, false),
12 truths.create(true, true, false)
13 );
14end.
Käsittely
Pitää pitää mielessä että dynaamiset taulukot ovat viitteitä. Dynaamisten taulukkomuuttujien "suora kopiointi" toisilleen ei kopioi mitään hyötykuormaa, vaan vain osoiteen. Tämä eroaa staattisten taulukkojen käyttäytymisestä.
Jos halutaan kopioida tietoja, niin on käytettävä system.copy
.-tiedostoa.
1program dynamicArrayCopyDemo(input, output, stdErr);
2
3var
4 foo, bar: array of char;
5
6procedure printArrays;
7begin
8 writeLn('foo[0] = ', foo[0], '; bar[0] = ', bar[0]);
9end;
10
11begin
12 setLength(foo, 1);
13 foo[0] := 'X';
14 // copies _reference_
15 bar := foo;
16 write(' initial values: ');
17 printArrays;
18
19 // change content _via_ _second_ reference
20 bar[0] := 'O';
21 write('changed via 2nd ref: ');
22 printArrays;
23
24 // copy content
25 bar := copy(foo, 0, length(foo));
26 bar[0] := 'X';
27 write(' copied and changed: ');
28 printArrays;
29end.
Vain käyttämällä copy
kopiointia molempia taulukoita voidaan muokata itsenäisesti.
Kuten edellä todettiin niin tässä setLength
kopioi tiedot. Yllä olevan esimerkin korostettu rivi vastaa (semanttisesti) setLength(bar, length(bar))
.
Dynaamisella taulukolla on "viitelaskuri". Kutsuminen setLength(myDynamicArrayVariable, 0)
on käytännössä myDynamicArrayVariable := nil
ja pienentää viitemäärää. Ainoastaan kun viitteiden määrä laskee nollaan, muistilohko vapautetaan.
1program dynamicArrayNilDemo(input, output, stdErr);
2var
3 foo, bar: array of char;
4begin
5 setLength(foo, 1);
6 foo[0] := 'X';
7 // copy _reference_, increase reference count
8 bar := foo;
9 // foo becomes nil, reference count is decreased
10 setLength(foo, 0);
11 writeLn('length(foo) = ', length(foo),
12 '; length(bar) = ', length(bar));
13
14 // decrease reference count another time
15 bar := nil;
16 writeLn('length(foo) = ', length(foo),
17 '; length(bar) = ', length(bar));
18end.
Dynaamiset taulukot kuitenkin loppukäsitellään automaattisesti. Ei tarvitse asettaa manuaalisesti kaikkiin viitteisiin setLength(…, 0)
, kun ohjelma päättyy tai kun siirrytään osiosta pois.
Ilman {$rangeChecks on}
on mahdollista saavuttaa taulukon rajat. Tämä tarkoittaa, että kun iteroidaan dynaamisia taulukkoja, on mahdotonta työskennellä ilman low
ja high
määrittämään kelvollisia indeksejä (ensimmäinen on valinnainen, koska dynaamiset taulukot alkavat aina nollasta).
Vaihtoehtoisesti voidaan käyttää for … in
looppia silmukoissa, jos indeksiä ei tarvita.
Muista, että sizeOf
arvioi dynaamisen taulukon osoittimen koon.
Sovellukset
- Käytössä on
system.tBoundArray
jaobjPas.tBoundArray