2.10.4 Sisäkkäiset tietueet

Tietueen eri kenttien tyyppinä voi olla mikä tahansa tyyppi: Se voi olla yksinkertainen tyyppi (int, double, char), mutta myös rakenteinen tyyppi eli esim. taulukko tai tietue. Mikään ei siis estä käyttämästä tietueen kenttänä jotain toista tietuetta!

Esimerkiksi, jos ensin määritellään tietuetyyppi

struct paivamaara {
  int pp, kk, vvvv;
};

niin sitten voidaan määritellä vaikkapa

struct henkilotiedot {
  string nimi;
  paivamaara synt_aika;
  int sukupuoli;
};

Tällöin henkilotiedot on tietuetyyppi, jossa on kolme kenttää. Näistä ensimmäinen on merkkijono, toinen paivamaara-tietue ja kolmas kokonaisluku. Edelleen kenttä synt_aika sisältää kolme kokonaislukukenttää. Esittelyn

henkilotiedot asiakas;

jälkeen tilanne on siten seuraava:

Miten sitten viitataan tällaisten sisäkkäisten tietueiden eri kenttiin? Ihan normaalisti! Siis tietuemuuttuja asiakas koostuu kolmesta kenttämuuttujasta, asiakas.nimi, asiakas.synt_aika ja asiakas.sukupuoli. Näistä keskimmäinen on tietuemuuttuja, joka puolestaan koostuu kenttämuuttujista asiakas.synt_aika.pp, asiakas.synt_aika.kk ja asiakas.synt_aika.vvvv.

Parhaiten sisäkkäisten tietueiden käyttö selvinnee esimerkin avulla:

/* *********************************************************
HENKTIED.CPP
  Harjoitellaan sisäkkäisten tietueiden käyttöä.
  Lukee näppäimistöltä henkilötiedot ja tulostaa ne sitten
  näytölle.
********************************************************* */

#include <iostream.h>
#include <string>

using namespace std;

struct paivamaara {
  int pp, kk, vvvv;
};

struct nimet {
  string etunimi, sukunimi;
};

struct henkilotiedot {
  nimet nimi;
  paivamaara synt_aika;
  int sukupuoli; // parillinen=nainen, pariton=mies
};

void lue_tiedot(henkilotiedot &henkilo)
{
  cout << "\n\n";
  cout << "Anna etunimesi  > ";
  getline(cin, henkilo.nimi.etunimi);
  cout << "Anna sukunimesi > ";
  getline(cin, henkilo.nimi.sukunimi);
  cout << "Anna syntymäpäiväsi muodossa pp kk vvvv > ";
  cin >> henkilo.synt_aika.pp >> henkilo.synt_aika.kk
      >> henkilo.synt_aika.vvvv;
  cout << "Anna sukupuolesi (0=nainen, 1=mies)     > ";
  cin >> henkilo.sukupuoli;
  henkilo.sukupuoli = henkilo.sukupuoli%2; // on varmasti joko 0 tai 1
}

void tulosta_tiedot(henkilotiedot henkilo)
{
  cout << "\n\n";
  cout << "Henkilötietosi:\n";
  cout << "  Nimi:         " << henkilo.nimi.etunimi << " ";
  cout << henkilo.nimi.sukunimi << endl;
  cout << "  Syntymäpäivä: " << henkilo.synt_aika.pp << ".";
  cout << henkilo.synt_aika.kk << "." << henkilo.synt_aika.vvvv << endl;
  cout << "  Sukupuoli:    ";
  if (henkilo.sukupuoli)
     cout << "mies" << endl;
  else
     cout << "nainen" << endl;
}

int main(void)
{
  henkilotiedot mina;

  lue_tiedot(mina);
  tulosta_tiedot(mina);

  return 0;
}