Luento 21

Rakenteiset tyypit - kertausta ja yhteenvetoa

C++ -tietotyypit

C++:ssa on useita eri tapoja tallettaa tietoa muistiin (luettelon lisäksi on eräitä erityistyyppejä, joita ei käsitellä tässä):

Näistä perustyyppejä käsitellään monisteen luvussa 2.2, taulukoita luvussa 2.8 ja tietueita (struct) luvussa 2.9. Osoittimista ja olioista on lisätietoa kiinnostuneille esim Ohjelmointi++ -kurssin luentomonisteessa.

Tietueen tai taulukon sijoitus

Tietueiden käsittely on oleellisesti taulukoita turvallisempaa. Erityisesti automaattinen sijoitusoperaattori helpottaa tietueiden kopiointia. Tutkitaan funktiota, jonka pitäisi kopioida taulukon sisältö toiseen taulukkoon:

const int KOKO = 10; // vakiokokoiset taulukot

// tämä ei ole 'toimiva' versio
void f(int t[]) {
    int j[KOKO]= {1,2,3,4,5,6,7,8,9}; // alustetaan taulukko
    t=j; // sijoitetaan j:n osoite t:n osoitteeseen 
         // Huom! Tässä EI kopioida j:n alkioita t:n alkioihin.
         // => pääohjelman taulukolle ei tapahdu mitään.
}

int main() {
    int t[KOKO] = {0}; // alustetaan kaikki alkiot 0:ksi.
    f(t); 
    // i:n alkiot ovat edelleen 0:ia.
}

'Toimiva' versio taulukoilla olisi seuraava:

void f(int t[]) {
    int j[KOKO]= {0,1,2,3,4,5,6,7,8,9}; // alustetaan taulukko
    for (int i=0; i<KOKO; i++)  // kopioidaan alkiot
        t[i]=j[i]; 
}

int main() {
    int t[KOKO] = {0}; // alustetaan kaikki alkiot 0:ksi.
    f(t); 
    // t:n alkiot ovat nyt {0,1,2,3, ... ,9}
}

Huom! Jos taulukko on määritelty tietueen sisälle, kopiointi onnistuu suoraan:

struct taulu {
    int t[KOKO];
};

// Huom. referenssi
void f(taulu& t) {
    taulu j = {{0,1,2,3,4,5,6,7,8,9}}; // alustetaan taulukko tietueen sisällä
    t=j; // kopioidaan tietue ja samalla taulukko
}

int main() {
    taulu t = {{0}}; // alustetaan kaikki alkiot 0:ksi.
    f(t); 
    // t:n t-kenttätaulukon alkiot ovat nyt {0,1,2,3, ... ,9}
}

Kopioinnin onnistuminen selittyy tietueen sijoitusmekanismilla: jokaiseen kenttään (erityisesti myös taulukkokenttään) varatut tavut kopioidaan sellaisenaan uuteen tietueeseen. For-silmukoita ei tarvita.

Luetellut tyypit

Eräs hyvin monissa ohjelmissa käytettävä tietotyyppi on lueteltu tyyppi (enumerated type). Lueteltu tyyppi on muuttuja, jonka kaikki mahdolliset arvot on lueteltu listassa. Luetellun tyypin esittely muistuttaa tietueen esittelyä:

enum maat {
    pata, risti, ruutu, hertta
};

enum sukupuoli {
    M,N 
};

enum arvosanat {
    HYL,TT,HT,ET
};

Sisäisesti luetellun tyypin arvot ovat kokonaislukuja. Ohjelman tehokkuuden kannalta enum-tyyppien sijasta voisi yhtä hyvin käyttää itse määriteltyjä numeroarvoja, mutta lueteltujen tyyppien käyttäminen on suositeltavampaa niiden luettavuuden ja ylläpidettävyyden takia. Ns. 'taikanumerot' eivät kuulu hyvään rakenteiseen ohjelmointityyliin!

enum-tyyppistä muuttujaa voi käyttää muiden tyyppien tapaan. Erityisen hyödyllisiä enum-tyypit ovat switch-case -tyylisissä rakenteissa:

sukupuoli sp;
sp = M;

//...

switch(sp) {
    case M:
        cout << "mies";
        break;
    case N:
        cout << "nainen";
        break;
    default:
        cout << "???";
}

Taulukoiden, tietueiden ja lueteltujen tyyppien hallinta muodostavat tukevan perustan rakenteiselle ohjelmoinnille. (Siirtyminen tästä olio-ohjelmointiin ei ole ylivoimainen askel...) :-)

Lopuksi vielä 'rakenteiseen' tyyliin tehty esimerkkiohjelma henktie2.cpp, joka pohjautuu monisteen esimerkkiin henktied.cpp.

http://appro.mit.jyu.fi/2002/kesa/johdatusohjelmointiin/luennot/luento21/index.html
© Miika Nurminen ()
27.06.2002 02:36:29