Sign in Join
Wiki copytemporary

Dynamic array/fi

English · Español · Français · Suomi · Русский · 日本語

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:

pascal
array of char

Huomaa, miten taulukon kokoa ei ole määritetty.

Moniulotteisen taulukon määrittelemiseksi, perustyypiksi määritetään itse taulukko.

pascal
array of array of longInt

Mitoitus

Kääntäjän aliohjelma setLength muuttaa dynaamisen taulukon pituutta edellyttäen, että muistia on riittävästi.

pascal
program setLengthDemo(input, output, stdErr);
var
    sieve: array of longWord;
begin
    setLength(sieve, 1337);
end.

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.

pascal
program multidimensionalSetLengthDemo(input, output, stdErr);
var
    samples: array of array of smallInt;
begin
    setLength(samples, 12, 64);
end.

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.

pascal
program binomialPotence(input, output, stdErr);
var
    pascalsTriangle: array of array of longWord;
    exponent: longInt;
    factor: longInt;
begin
    setLength(pascalsTriangle, 20);
    
    setLength(pascalsTriangle[0], 1);
    pascalsTriangle[0][0] := 1;
    
    setLength(pascalsTriangle[1], 2);
    pascalsTriangle[1][0] := 1;
    pascalsTriangle[1][1] := 1;
    
    // construct values by simple addition
    for exponent := 2 to high(pascalsTriangle) do
    begin
        setLength(pascalsTriangle[exponent], exponent + 1);
        pascalsTriangle[exponent][0] := 1;
        pascalsTriangle[exponent][exponent] := 1;
        for factor := 1 to exponent - 1 do
        begin
            pascalsTriangle[exponent][factor] :=
                pascalsTriangle[exponent - 1][factor - 1] +
                pascalsTriangle[exponent - 1][factor];
        end;
    end;
    
    // ...

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:

pascal
program dynamicArrayCreateDemo(input, output, stdErr);
type
    truths = array of boolean;
var
    l: truths;
begin
    l := truths.create(false, true, true, false, true, false, false);
end.

Voidaan tietysti käyttä myös sisäkkäisiä taulukoita:

pascal
program nestedDynamicArrayCreateDemo(input, output, stdErr);
type
    truths = array of boolean;
    pattern = array of truths;
var
    p: pattern;
begin
    p := pattern.create(
            truths.create(false, false),
            truths.create(true, false),
            truths.create(true, false, false),
            truths.create(true, true, false)
        );
end.

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.

pascal
program dynamicArrayCopyDemo(input, output, stdErr);

var
    foo, bar: array of char;

procedure printArrays;
begin
    writeLn('foo[0] = ', foo[0], '; bar[0] = ', bar[0]);
end;

begin
    setLength(foo, 1);
    foo[0] := 'X';
    // copies _reference_
    bar := foo;
    write('     initial values: ');
    printArrays;
    
    // change content _via_ _second_ reference
    bar[0] := 'O';
    write('changed via 2nd ref: ');
    printArrays;
    
    // copy content
    bar := copy(foo, 0, length(foo));
    bar[0] := 'X';
    write(' copied and changed: ');
    printArrays;
end.

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.

pascal
program dynamicArrayNilDemo(input, output, stdErr);
var
    foo, bar: array of char;
begin
    setLength(foo, 1);
    foo[0] := 'X';
    // copy _reference_, increase reference count
    bar := foo;
    // foo becomes nil, reference count is decreased
    setLength(foo, 0);
    writeLn('length(foo) = ', length(foo),
        '; length(bar) = ', length(bar));
    
    // decrease reference count another time
    bar := nil;
    writeLn('length(foo) = ', length(foo),
        '; length(bar) = ', length(bar));
end.

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

Katso myös


From the Free Pascal wiki, page "Dynamic array/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 1, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.