C++-kieli‎ > ‎

Pino

Pino

Lifo-pino on tietorakenne, johon voidaan tallentaa tietoa siten, että viimeksi talletettu tieto tulee ensimmäisenä pois.

Esimerkki 1. Pinon luokkamalli ja toteutus, sekä käyttöesimerkki main():sta.

#include <iostream>

using namespace std;

// Pino, johon voi tallettaa kokonaislukuja
class CPino // Stack, LIFO=Last In First Out
{
private:
    int m_PinonJasenet[100];
    int m_PinonHuippu;

public:
    CPino(const int Huippu=0)
    {
        m_PinonHuippu = Huippu;
    }

    void LisaaUusiPinoon(const int Uusi)
    {
        m_PinonJasenet[m_PinonHuippu] = Uusi;
        m_PinonHuippu++;                     // näyttää ensimmäiseen tyhjään paikkaan.
        assert(m_PinonHuippu < 100);         // Testaa että pinon huippu varmasti alle sata.
    }

    int OtaPinosta()
    {
        m_PinonHuippu--;
        assert(m_PinonHuippu >= 0);          // Testaa että pinon huippu varmasti yli nollan.
        return m_PinonJasenet[m_PinonHuippu];
    }

    int NaytaMaaraPinossa() const
    {
        return m_PinonHuippu;
    }

    void NaytaKokoPino() const
    {
        for (int i=0; i<m_PinonHuippu; i++) {
            cout << "#" << i << ": " << m_PinonJasenet[i] << endl;
        }
        cout << "Pinon huippu on #" << m_PinonHuippu << endl;
    }
};

int main()
{
        CPino pino;
        pino.LisaaUusiPinoon(-4);
        pino.LisaaUusiPinoon(1234);
        pino.NaytaKokoPino();
        cout << "Pinosta otettu luku: " << pino.OtaPinosta() << endl;
        pino.NaytaKokoPino();
}


Mallit (Template)

Malleja pidetään vaikeana C++-kielen ominaisuutena. Tämä pitää vain osin paikkansa. Mallit ovat oikein käytettynä erittäin tehokas ohjelmoijan apukeino.

Mallit ovat luokan abstraktio, eli malleilla kuvataan millaisia luokkia malleista voidaan luoda. Näistä luokista sitten luodaan olioita, normaaliin tapaan. Mallit voivat parametrisoida kokonaislukuja sekä tietotyyppejä (sisäänrakennettuja sekä itse tehtyjä luokkia).

Malleja voi olla sekä luokka-, että funktiomalleja.

Esimerkki 1. Funktiomalli, jossa tietotyyppi on parametrisoitu.

template <typename T>
T Kerro( T a, T b)
{
    return a*b; // Palauttaa annettujen lukujen tulon.
}

Käyttö:

int tulos1 = Kerro <int>(1, 3);           // int kertominen
float tulos2 = Kerro <float>(1.34, 3.14); // float kertominen

Esimerkissä luotiin funktiomalli, joka kertoo kaksi lukua yhteen ja palauttaa tuloksen. Käyttö tapahtuu määrittämällä minkä tietotyypin Kerro-funktio halutaan luoda.
HUOM <tietotyyppi> ei välttämätön, jos kääntäjä osaa itse päätellä tietotyypin. Tässä esimerkissä <int> määritettä ei tarvita, sillä parametreiksi annetaan vain int-tyyppisiä arvoja.

Esimerkki 2. Luokkamalli, jossa tietotyyppi on parametrisoitu.

template <typename T>
class CLuokka
{
private:
    T m_Muuttuja;

public:
    void AsetaMuuttuja(const T);
    T PalautaMuuttuja() const;
};

Käyttö:

int main()
{
    CLuokka <int> int_luokka;
    int_luokka.AsetaMuuttuja(34);

    CLuokka <float> float_luokka;
    float_luokka.AsetaMuuttuja(3.14576);
}

Tässä esimerkissä esitellään luokkamalli, jonka tietotyyppi on parametrisoitu. Käyttö tapahtuu antamalla tietotyyppi hakasulkujen sisällä heti luokan nimen jälkeen. Käyttö-kohdassa luodaan CLuokka<int> ja CLuokka<float> luokat. Tämä tarkoittaa että, CLuokka-luokan jäsenmuuttuja  m_Muuttuja on ensimmäisessä tapauksessa  int ja toisessa  float.

Mallien ongelmia

Se miksi malleja pidetään vaikeana on niiden hieman omituinen syntaksi ja se, että ne tuottavat käsittämättömiä virheilmoituksia.

Mallien etuja

Etuna mallien käytössä on se, että ne voivat säästää saman asian useaan otteeseen kirjoittamiselta. Jos sinulla on esimerkiksi TulostaBinaari()-funktio, joka tulostaa minkä tahansa muuttujan binäärimuodossa ruudulle. Ilman malleja joutuisit ylikuormittamaan funktion jokaiselle sisäiselle tietotyypille (int, char, float, jne.) ja sen lisäksi jokaiselle itse tekemällesi luokalle/tietorakenteelle.
Mallien avulla kirjoitat koodin yhteen kertaan ja tämä koodi toimii kaikille tietotyypeille ja lisäksi omille luokille.

Esimerkki 3. TulostaBinaari()-funktion toteutus mallien avulla.

template <typename T>
void TulostaBinaari(T arvo)
{
    for (int i=sizeof(T)-1; i>=0; i--) {
        for (int j=8-1; j>=0; j--) {
            cout << ((arvo >> (i+j)) & 1);
        }
    }
}

Käyttö:

int main()
{
    TulostaBinaari<char>(34);      cout << endl;
    TulostaBinaari<int>(342623);   cout << endl;
    TulostaBinaari<float>(3.1475); cout << endl;
}





Comments