TIETORAKENTEET

Tietorakenne on joukko tietoa, joka on järjestelty tietyllä tavalla. Perustietotyypit (int, char, long, float, double) sisältävät vain yksittäisen tiedonpalasen. Taulukot yhdistävät samantyypisen tiedon ryhmiä. Tietorakenteet ovat rakenteita, joiden avulla yhdistetään useita eri tyyppisiä muuttujia "tietokannaksi".

Esimerkiksi henkilötiedot-tietue koostuu nimestä, iästä, osoitteesta ja puhelinnumerosta, eli tiedoista jotka ovat eri tyyppisiä (numeroita ja/tai kirjaimia).

Example pic


TIETUEET

Taulukkoon voi tallentaa tietoa, mutta taulukon jokaisen alkion täytyy olla samaa tietotyyppiä, eli kirjaimia ja numeroita ei voi samaan sekoittaa samaan taulukkoon. C-ohjelmointikielissä on tietorakenne jolla eri tyyppistä tietoa voi yhdistää, rakennetta kutsutaan tietueeksi (struct).

Tietueiden määrittely

struct nimi { tietotyyppi alkio 1; tietotyyppi alkio 2; .... tietotyyppi alkio n; };

Tietue on sellaista tietotyyppiä, jonka muodon ohjelmoija itse määrittelee. Kun tietue on määritelty, on luotava muuttujien määrittelyt, jotka yhdistävät symbolisen nimen tietueeseen.

struct nimi erikoisnimi;

Avainsanaa struct seuraa tietueen nimi. Muuttujan nimi (erikoisnimi) sisältää muuttujalle annetun todellisen tyypin. Kutakin tietueen alkiota käsitellään käyttämällä muuttujan perusnimeä, jonka jälkeen tulee piste ja alkion nimi.

Esim.

nimi.alkio1 nimi.alkio2


Esimerkki tietueen käyttämisestä.

/* Tietueiden käyttäminen */ #include <stdio.h> struct henkilo_tiedot /* tietueen henkilo_tiedot määrittely */ { int ika; char osoite[40]; char nimi[35]; char puh[14]; }; int main() { struct henkilo_tiedot henkilo1; /* muuttujan henkilo1 määrittely */ printf("Anna ika: "); scanf("%i",&henkilo1.ika); fflush(stdin); /* näppäimistö-puskurin tyhjennys */ strcpy(henkilo1.osoite,"Mustakiven-puisto"); printf("Anna henkilon nimi: \n"); gets(henkilo1.nimi); fflush(stdin); printf("Anna henkilon puhelinnumero: "); gets(henkilo1.puh); fflush(stdin); if (henkilo1.ika < 18) { printf("\n\n%s on alaikainen.", henkilo1.nimi); } else printf("\n\n%s on taysi-ikainen.", henkilo1.nimi); printf("\n%s", henkilo1.osoite); printf("\n%s", henkilo1.puh); getch(); return 0; }



Esimerkissä (yllä), luodaan ennen pääohjelmaa henkilo_tiedot-niminen tietue. henkilo_tiedot-tietueeseen liitetään ika-, osoite-, nimi- ja puhelinnumero-muuttujat. Muuttujat ovat tyypeiltään ika kokonaisluku, osoite, nimi ja puh merkkityyppiset taulukot. Ohjelman osien erittely:

Tietueen määrittely eli esittely, ennen pääohjelmaa annetaan tietueelle nimi sekä kerrotaan tietueessa käytettävien muuttujien tyypit sekä nimet. Tietueessa aiotaan siten käsitellä ikää, osoitetta, nimeä ja puhelinnumeroa.

struct henkilo_tiedot { int ika; char osoite[40]; char nimi[35]; };

henkilo_tiedot-tietueessa, on neljä alkiota:

Ensimmäinen alkio on kokonaisluku ja on nimeltään ika.
Toinen alkio on sisältää merkkejä ja on nimeltään osoite.
Kolmas alkio on sisältää merkkejä ja on nimeltään nimi.
Neljäs alkio on sisältää merkkejä ja on nimeltään puh.

Example pic
Kuva, yllä. Tässä kohtaa on esitelty eli luotu tietue-rakenne sekä tietueessa käytettävät alkiot, muuttujat. Muistia tietueelle ei varata vielä tässä vaiheessa. Muistin varaaminen tapahtuu muuttajan määrittelyn yhteydessä.

struct etunimi leena;

Avainsanaa struct seuraa tietueen nimi (etunimi) ja muuttujan nimi (leena).

Example pic

Kieli sallii tietueen määrittelyn myös lyhyessä muodossa, jolloin edellinen esimerkki näyttäisi seuraavalta:

struct etunimi { int numero_1; float numero_2; char kirjain; } leena;

Tällainen koodijakso mahdollistaa sekä tietueen että muuttujan määrittelyn tekemisen yhdessä vaiheessa.

Tietueen alkioiden käsittelyyn käytetään pisteoperaattoria.

leena.numero_1 = 99; leena.numero_2 = 29.95; leena.kirjain = 'p';

Komennot ovat sijoitusoperaatioita. Kutakin tietueen alkiota voidaan käsitellä käyttämällä pistemerkintää. Kun alkioiden sisältö halutaan näyttää ruudulla käytetään samaa pisteoperaatoria uudelleen.


TIETUETAULUKOT

Tietuetaulukoita voi olla käytössä aivan kuten kokonaislukutaulukoita, merkkitaulukoita tai liukulukutaulukoita. Ennen taulukon käyttöä on määriteltävä tietue.


Tietuetaulukon määrittely

struct astruct { int first; char second; float third; };

Tietueen esittelyn jälkeen määritellään taulukko:

struct astruct mystructarr[5];

Tietuetaulukkomäärittely on samanlainen kuin tavallisen taulukon määrittely. Tietuetaulukkoalkioihin viittaaminen on kuitenkin hieman monimutakaisempaa. Muuttujan nimen jälkeen tulee taulukon alkion tunniste, jota seuraa piste. Lopuksi lisätään kentän nimi.

mystructarr[1].first = 2; mystructarr[2].second = 2.68; mystructarr[3].third = 'p';

Esimerkki.

/*Tietuetaulukon käyttäminen*/ #include <stdio.h> #include <stdlib.h> #define DIM 3 struct tietue { int numero; float lukumaara; char nimi[25]; }; int main() { struct tietue myynti[DIM]; int luku; for (luku = 0; luku < DIM; luku++) { printf("\nAlkion %d tiedot on\n", luku+1); printf("Anna numero: "); scanf("%d", &myynti[luku].numero); printf("Anna maara: "); scanf("%f", &myynti[luku].lukumaara); printf("Anna nimi: "); scanf("%s", &myynti[luku].nimi); } for (luku = 0; luku < DIM; luku++) { printf("\n**Tietorakennealkio %d\n", luku+1); printf("Numero: %d\n", myynti[luku].numero); printf("Maara: %f\n", myynti[luku].lukumaara); printf("Nimi: %s\n\n", myynti[luku].nimi); } getch(); return 0; }




TIETUEIDEN KÄYTTÄMINEN FUNKTIOIDEN YHTEYDESSÄ

Funktiolle voidaan välittää tietuemuuttuja parametrina samoin kuin sille välitetään tavallista tietoa. Mikäli tietue sisältää paljon tietoa, on suositeltavampaa välittää osoitin ko. tietueeseen.

Esim. (esimerkki-ohjelma ei toimi Dev C++ kääntäjällä)

/* Tietueen välittäminen funktiolle */ #include <stdio.h> /* Tietueen määrittely */ struct persoona { char nimi[25]; int ika; }; /* Funktioiden prototyypit */ struct persoona ota_data(void); void printdata(struct persoona); int main() { struct persoona ystava, sisko; printf("Anna tietoja ystavasta\n"); ystava = ota_data(); printf("Anna tietoja sisarestasi\n"); sisko = ota_data(); printf("Ystava on\n"); printdata(ystava); printf("Sisar on\n"); printdata(sisko); getch(); return 0; } /* FUNKTIOIDEN MÄÄRITTELYT */ /***************************/ /*henkilötiedot*/ struct persoona ota_data() { struct persoona apu; // tilapäinen paikallinen muuttuja printf("Anna etunimi\n"); scanf("%s", &apu.nimi); printf("Anna ika\n"); scanf("%d", &apu.ika); return apu; } /* tulostusfunktio */ void printdata(struct persoona apu) { printf("Nimi on %s\n", apu.nimi); printf("Ika on %d \n\n", apu.ika); }




UNIONIT

Unionit ovat samanlaisia kuin tietueet siinä, että ne sisältävät alkioita, jotka tietotyyppinsä suhteen voivat erota toisistaan. Poiketen tietueista unionin jäsenet kuitenkin jakavat saman muistialueen. Tietueessa kullekin jäsenelle annetaan oma muistialueensa mutta unionissa vain yhtä tietojäsentä käytetään kerrallaan. Unionille allokoidaan tarpeeksi muistia tallentamaan määrittelyn suurin jäsen. Mikäli pienempi jäsen on aktiivinen, jäljellejäävää muistia ei käytetä.

Unionin määrittely

union nimi { tietotyyppi alkio 1; tietotyyppi alkio 2; ..... tietotyyppi alkio n; };

Union on varattu avainsana. Muilla termeillä on sama merkitys kuin tietuemäärittelyssä.

Esim.

union id { char name[15]; int controlnumber; }; union id salesitem;



KÄYTTÄJÄN MÄÄRITTELEMÄT TYYPIT

Ohjelmointikieli mahdollistaa uuden nimen luomisen olemassa olevalle tietotyypille. Tämän mahdollisuuden avulla voidaan ohjelmakoodin luettavuutta parantaa. Nimeämiseen käytetään typedef-rakennetta.

Typedef-rakenne

typedef tyyppi uusinimi;

Tyyppi on mikä tahansa tavallinen tietotyyppi ja uusinimi on tämän tyypin uusi nimi l. lisäys olemassa olevan tyypin nimeen.

Esim.

#define TOSI 1 #define EPATOSI 0 typedef int BOOL; ………… BOOL status; int number; char ch; …………

Esimerkissä on luotu Boolean-tietotyyppi, joka saa arvon tosi tai epätosi. typedef-komennolla luodaan Boolean tietotyyppi, joka on sama kuin int. Tunnistetta BOOL voidaan käyttää tästä eteenpäin muuttujien määrittelyssä. Isojen kirjaimien käyttö uusien tyyppien kohdalla muistuttaa siitä, että tyypin nimi on yhtäläinen toisen tyypin kanssa.