Siirry sisältöön

C/Tietueet

Wikikirjastosta
< C

Tämä luku kertoo C:n tietueista.

Tietue on C-kielessä tapa koota useampia tietoalkioita yhdeksi loogiseksi kokonaisuudeksi. Tietue määritellään varatulla sanalla struct, jota seuraa tietueen nimi, sekä lueteltuna tietueen kentät.

Tietueen määritteleminen

[muokkaa | muokkaa wikitekstiä]

Määritellään uusi tietotyyppi 2D-avaruudessa sijaitsevaa pistettä varten:

struct point 
{
    double x;
    double y;
};

Pistettä voidaan käyttää seuraavasti:

double distance;
struct point p1;
struct point p2;

p1.x = 1.1;
p1.y = 2.2;

p2.x = 3.3;
p2.y = 4.4;

distance = sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));

Tietueen kenttiin viitataan siis . - operaattoria käyttäen. Jos muuttuja olisikin osoitin tietueeseen, voitaisiin käyttää operaattoria ->.

/* struct point *p1 */
p1->x       /* sama kuin (*p1).x */

Tietueet ja abstraktit tietotyypit

[muokkaa | muokkaa wikitekstiä]

Tietueiden avulla voidaan C-kielessä muodostaa abstrakteja tietotyyppejä (ADT = abstract data type). On hyödyllistä määritellä edellä esitetyn pisteen käyttöä varten omat funktionsa:

struct point pointConstruct(double x, double y)
{
    struct point p;
    p.x = x;
    p.y = y;
    return p;
}

double pointDistance(struct point p1, struct point p2)
{
    return sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}

Huomaa, että funktioissa on käytetty etuliitteenä (prefix) tietotyypin nimeä. Tämä on hyvä käytäntö, sillä tällöin jo funktion nimestä käy ilmi mitä abstraktia tietotyyppiä varten se on tehty.

Funktioita voidaan käyttää yksinkertaisesti seuraavasti:

double distance;
struct point p1;
struct point p2;

p1 = pointConstruct(1.1, 2.2);
p2 = pointConstruct(3.3, 4.4);

distance = pointDistance(p1, p2);

Etenkään suurempia tietueita ei kannata antaa funktioille suoraan arvoina (koska ne pitää kopioida joka kerta), vaan osoittimina, jolloin esim. funktion pointDistance esittely näyttäisi seuraavalta:

double pointDistance(struct point *p1, struct point *p2);

tai, koska kyseisen funktion ei tarvitse muuttaa tietueita, niin paremmin:

double pointDistance(const struct point *p1, const struct point *p2);

Kun tietuetta käytetään tietotyyppinä, etuliite struct pitää mainita (C:ssä, ei C++:ssa). Tämä voidaan välttää määrittelemällä tyypille alias typedef-lauseella:

typedef struct point point;

niin point riittää pelkän struct point:n sijasta. Voitaisiin myös esim. kirjoittaa typedef struct point Point;, niin Point vastaisi struct point:ia. typedef:llä voi yleensäkin määritellä omia nimiä jo määritellyille tyypeille, myös kieleen kuuluville.

Voidaan myös kirjoittaa

typedef struct point 
{
    double x;
    double y;
} point;

Sama sääntö struct-määreestä ja typedef:n käytöstä pätee myös alla käsitellyille yhdiste- ja luetelmatyypeille.

Yhdistetyypit

[muokkaa | muokkaa wikitekstiä]

Tietueiden lisäksi on yhdisteitä (engl. union). Siinä missä tietueet säilyttävät kaikkia kenttiä sarjassa, yhdisteet säilyttävät vain yhtä kenttää kerrallaan rinnakkain.

Esimerkiksi seuraava yhdiste sisältää joko kokonaisluvun tyyppiä int tai liukuluvun tyyppiä float:

union luku {
    int koko;
    float liuku;
};

Yhdisteessä voi säilöä kerrallaan vain yhtä kenttää kerrallaan. Siitä on luettava sitä tyyppiä oleva arvo, joka siihen on viimeksi kirjoitettu, tai luettava arvo on kelvoton. Yhdiste ei itse sisällä tätä tietoa, joten sen selvittäminen jää ohjelmoijan vastuulle.

union luku luku;
luku.koko = 2;
printf("Kokonaisluku on %d\n", luku.koko);
luku.liuku = 2;
printf("Liukuluku on %f\n", luku.liuku);

Yhdisteiden päätarkoitus on säästää muistia tapauksissa, joissa arvo voi olla useaa tyyppiä, mutta vain yhtä kerrallaan.

Luetelmat eli luetellut tyypit (engl. enumeration, enum) ovat tietotyyppejä, joiden sallitut arvot on lueteltu erikseen. Sisäisesti muuttujan, jonka tietotyyppi on luetelmatyyppiä, arvo on jonkinlainen kokonaisluku.

Esimerkki luetelmasta:

 enum maa { MAA_PATA, MAA_HERTTA, MAA_RUUTU, MAA_RISTI };

Tällöin muuttujalla tyyppiä enum maa voi olla arvo MAA_PATA (= 0), MAA_HERTTA (= 1), MAA_RUUTU (= 2), MAA_RISTI (= 3). Arvot voi myös määritellä itse:

 enum maa { MAA_PATA = 0, MAA_HERTTA = 1, MAA_RUUTU = 2, MAA_RISTI /* saa automaattisesti arvon, joka on edellinen + 1 */ };

Joissain tapauksissa luetelmatyyppiä voi käyttää bittimaskina, jolloin myös yhdistelmät (MAA_PATA | MAA_HERTTA) voivat olla kelvollisia.

Huomaa, että luetelmatyyppien arvot ovat vakioita, jotka näkyvät kaikkialla ja ovat kuin vakioita, jotka olisi määritelty luetelmatyypin ulkopuolella. Siksi luetelma-arvojen nimien eteen kannattaa lisätä jokin etuliite.

C-ohjelmointikieli

EtusivuHistoriaTyökalut


Yksinkertainen C-kielinen ohjelmaMuuttujatOperaattoritKommentitOhjausrakenteetFunktiotOsoittimetDynaaminen muistinvarausTaulukotMerkkijonotTietueetEsikääntäjäOtsikkotiedostot


C-kielen varatut sanatStandardikirjastoAiheesta muualla