Luento 19

Lisätietoa C++ -taulukoista

Taulukon esitys muistissa

Taulukko on kokoelma samaa tyyppiä olevia olioita (tietueita, perustyyppejä, osoittimia tai taulukoita edellisistä), jotka on sijoitettu muistiin peräkkäin.

Esimerkkejä taulukoiden esittelystä:

int taulu[10]; // taulukko, jonka koko 10 kokonaislukua.
string nimet[5]; // 5 C++:n merkkijono-oliota.
double matriisi[3][2]; 
/* 2-ulotteinen lukutaulukko (matriisi), koko 2 'x-suunnassa' ja 3 'y-suunnassa'. 
   Voidaan myös ajatella 3-kokoisena taulukkona 2-kokoisista double-taulukoista. */
   
char *argv[2]; 
/* 2-kokoinen taulukko C-tyylisiä merkkijonoja (oikeastaan taulukko merkkiosoittimia).
    Huom. C++ -ohjelman pääohjelmaan välitetään parametrit tässä muodossa. */

Ohjelmoijan vastuulla on aina pitää huolta siitä, että taulukon rajoja ei ylitetä! Esim. edellisen esimerkin tilanteessa käsky

int a = taulu[20]; // ei näin! Taulukon koko on 10 (suurin indeksi 9!)
menee kääntäjästä läpi, mutta tuottaa ohjelman ajon aikana todennäköisesti virhetilanteen.

2-ulotteisen taulukon T muistiesitystä voidaan tulkita esim. seuraavasti:

Ylempi kuva on taulukon 'looginen' esitys (matriisi, jossa 2 riviä ja 3 saraketta), alempi näyttää, miten taulukon alkiot on tallennettu muistiin. Taulukon nimimuuttuja T on osoitin ('muistipaikan osoite') taulukon alkuun (osoittimia ei käsitellä tarkemmin tällä kurssilla).

3-ulotteista taulukkoa voidaan tarkastella vastaavasti:

Huomaa, että '3-ulotteinen' taulukko T voidaan myös tulkita 'tavalliseksi' 3-paikkaiseksi taulukoksi, jonka alkioita ovat 2*3-kokoiset taulukot (tämä on moniulotteisen taulukon tulkinta funktioita kutsuttaessa).

Taulukot ja sizeof

sizeof-operaattorilla saadaan selville tietyn tyypin (tai muuttujan) viemä muistitila tavuina. Tämä mahdollistaa taulukon koon ohjelmallisen selvittämisen määrittelyn jälkeen seuraavasti:

int taulu[10];
// ...
sizeof(taulu) / sizeof(int); // palauttaa 10

Huomaa, että vastaava tekniikka ei toimi, jos taulukko on annettu funktion argumenttina! (ks seuraava kappale)

Esimerkki: sizeof.cpp

Taulukot funktion argumenttina

Kun taulukko on funktion parametrina, sen alkioita ei kopioida (toisin kuin perustyyppien yhteydessä). Taulukkoargumentti on vain osoitin muualla alustetun taulukon alkuun, jolloin sen koosta ei voi tehdä lisäpäätelmiä. Siksi taulukon koko on aina annettava erillisenä argumenttina funktiolle!

Jos taulukon alkioiden arvoja muutetaan funktiossa, muutokset näkyvät suoraan kutsuvassa funktiossa (sisäisesti tämä muistuttaa referenssiparametrin välittämistä). Taulukon arvojen muuttaminen voidaan kieltää const-määreellä:

void f(const int taulu[]); // vakiotaulukko

Käytettäessä moniulotteisia taulukoita argumenttilistassa on annettava taulukon ulottuvuuksien koot (esimmäistä lukuunottamatta).

void f(double T[][2][3],int koko); // moniulotteinen argumentti

// ...

// kutsuva funktio
{
    double T[3][2][3]; // käytetään ylemmän kuvan rakennetta
    // ...
    
    f(T,3); // taulukon koko on välitettävä erikseen!
}

Tämä kuvastaa ajattelua, että T on taulukko 2-ulotteisista taulukoista.

Viitteet

http://appro.mit.jyu.fi/2002/kesa/johdatusohjelmointiin/luennot/luento19/index.html
© Miika Nurminen ()
25.06.2002 15:13:59