2.8.2 Yksiulotteiset taulukot

Taulukko voidaan muodostaa samaa tyyppiä olevista alkioista. Taulukko on yksinkertaisesti kokoelma muuttujia, jossa tilaa on varattu useille samantyyppisille tietoalkioille peräkkäin. Erona tavallisiin muuttujiin viittaus taulukon yksittäiseen alkioon tapahtuu indeksoidun muuttujan avulla, jolloin kerrotaan halutun alkion sijainti varatun alueen sisällä.

Taulukko esitellään muuten samoin kuin yksittäinen muuttuja, mutta nimen perään liitetään hakasuluissa tieto siitä, monelleko alkiolle siinä varataan tilaa. Määrittelyn yleinen muoto on

tyyppi nimi[koko];

missä tyyppi on taulukon yhden alkion tyyppi, nimi on taulukon nimi ja koko taulukossa olevien alkioiden eli "lokerojen" lukumäärä.

Esimerkiksi taulukko, jossa on kolme liukulukua määriteltäisiin seuraavasti:

double luvut[3];

Edellä esitetty taulukon esittely varaa keskusmuistista muistialueen, jossa on tilaa kolmelle kaksoistarkkuuden luvulle. Varattuun tilaan (varatun tilan ensimmäiseen tavuun) voidaan tästedes viitata taulukolle annetulla symbolilla luvut.

Taulukon yksittäisiin alkioihin viitataan indeksoidun muuttujan avulla. Indeksoitu muuttuja on muotoa

taulukon_nimi[indeksi]

missä taulukon_nimi on taulukolle esittelyn yhteydessä annettu nimi ja indeksi kokonaisluku, joka kertoo, kuinka monta alkiota taulukossa on ohitettava, jotta löydetään haluttu alkio. On huomattava, että kuvatusta ajattelutavasta johtuen C++-kielessä taulukoiden indeksointi alkaa nollasta, toisin kuin useimmissa muissa korkean tason ohjelmointikielissä.

Jos edellä kuvattuun luvut taulukkoon halutaan sijoittaa toiseksi alkioksi luku 4.56, on sijoitus muotoa

luvut[1]=4.56;

Siis toisen alkion indeksinä onkin luku 1 eikä luku 2!

Aiemmin on todettu, että erityyppiset muuttujat vievät muistista erilaisen määrän tavuja. Mistä kääntäjä tietää, montako tavua taulukon alusta kaiken kaikkiaan pitää ohittaa viitattaessa muuttujaan taulu[2], jos taulukko taulu on määritelty
• char taulu[5];
• int taulu[5];
• float taulu[5];
• double taulu[5];
ja mitkä ovat kyseiset siirtymät?

C++-kielen käyttämästä indeksoinnista seuraa suoraan, että:

Taulukoiden avulla voidaan tehostaa huomattavasti kirjoitettavaa koodia. Jos esimerkiksi halutaan tulostaa taulukko, jossa on 50 kokonaislukua, ei tarvita 50 perättäistä tulostuslausetta, vaan voidaan hyödyntää taulukolle ominaista indeksointia ja toistorakenteita. Näin ollen lukujen tulostus voidaan hoitaa seuraavalla silmukalla:

double luvut[50];
...
for(i=0; i<50; i++)
  cout << luvut[i] << "\n";

Edellinen esimerkki oli hieman huono, sillä alkioiden lukumäärä (50) on esitetty lukuna. Selkeämpi ja parempi tapa on käyttää vakiota:

#define ALKIOITA 50
...
double luvut[ALKIOITA];
...
for(i=0; i<ALKIOITA; i++)
  cout << luvut[i] << "\n";

Mitä etu saavutetaan käyttämällä vakiota ALKIOITA sen sijaan että käytettäisiin lukua 50?

Otetaan esimerkkinä taulukon käytöstä ohjelma, joka kysyy käyttäjältä kokonaislukuja ja sijoittaa ne taulukkoon. Lopuksi ohjelma tulostaa ko. taulukon sisällön.

/* *********************************************************
TAULUKKO.CPP
  Yksiulotteisen taulukon käsittelyn harjoittelua.
  Lukee taulukkoon kokonaislukuja ja tulostaa ne näytölle.
********************************************************* */

#include <iostream.h>

#define NMAX 5  // taulukon alkioiden maksimilukumäärä

int main(void)
{
  int taulu[NMAX]; // kokonaislukutaulukko
  int i, n;

  do {
    cout << "Anna alkioiden lukumäärä (1-" << NMAX << ") > ";
    cin >> n;
  } while (n < 1 || n > NMAX);

  cout << "Anna " << n << " kokonaislukua > ";
  for (i=0; i<n; i++) // HUOM: indeksointi alkaa nollasta
    cin >> taulu[i];  // luetaan luku taulukkoon

  cout << "Annoit luvut:";
  for (i=0; i<n; i++)         // tulostetaan taulukon sisältö
    cout << "  " << taulu[i];
  cout << endl;

  return 0;
}

Esimerkkiajo:

Anna alkioiden lukumäärä (1-5) > 5
Anna 5 kokonaislukua > 3 1 -6 3 20
Annoit luvut:  3  1  -6  3  20