Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Code Block
void KartionTilavuus()
{
    float Sade, Korkeus, Tilavuus;            // esitellään muuttujat

    system("cls");                            // putsataan ruutufunktion paikalliset muuttujat

    printf("Lasken kartion tilavuuden");      // annetaan ohjeita käyttäjälle
    printf("Anna pohjan säde:");
    scanf("%f", &Sade);                       // kysytään tietoa käyttäjältä

    printf("Anna korkeus:");
    scanf("%f", &Korkeus);

    Tilavuus = 3.14159 * Sade*Sade*Korkeus/3; // lasketaan ja sijoitetaan
    printf("Tilavuus on %5.2f", Tilavuus);
}

Edellinen ohjelma laskee kartion tilavuuden ja tulostaa tiedot ruudulle, muttei pysty välittämään tietoa muille funktioille. Muuttujat Sade, Korkeus ja Tilavuus ovat tämän funktion paikallisia muuttujia eli tiedon säilömispaikkoja. (kts. seuraava kohta).

Funktion kutsuminen

Funktiota kutsutaan muodossa funktion_nimi() ja sulkujen sisään tulevat mahdolliset parametrit.

...

Note

Funktiota voidaan kutsua sen mistä tahansa ohjelmasta, myös funktiosta itsestään (vrt. rekursio).

Funktion parametrit

...

Funktioon voidaan sen käynnistyessä viedä tietoa ja se voi päätyttyään palauttaa kutsujalleen tietoa. Tieto viedään parametrien avulla ja palautetaan return-käskyllä. Tietoa voidaan palauttaa myös parametreissa (kts. Esimerkki 6 ja Osoittimet).

...

ja paikalliset muuttujat

Kaikilla funktiolla voi olla omia paikallisia (local) muuttujia. Lisäksi funktiolla voi olla parametreja, joiden avulla funktiolle välitetään tietoa sen ulkopuolelta. Parametrit eroavat paikallisista muuttujista siinä, että niille on annettu alkuarvo funktion kutsussa.

...

Esimerkki 2

Code Block
void TulostaMerkkifunktio(charint Merkkix)
{
    int y;
    ...
}
  • x on funktion parametri ja y funktion paikallinen muuttuja. On huomattava, että parametrit ja paikalliset muuttujat eivät näy funktion ulkopuolelle eivätkä siten ole käytettävissä muualla kuin funktiossa itsessään.
  • On myös tärkeää huomata, että eri funktioissa voi olla samannimisiä muuttujia ja ne ovat toisistaan täysin riippumattomia.
    Anchor
    esim2
    esim2

Esimerkki 2

Code Block

void TulostaMerkki(char Merkki)               // funktion parametrina char tyyppinen muuttuja
{
    printf("Antamasi merkki oli %c", Merkki); // tulostetaan annettu merkki %c:n osoittamaan kohtaan
}

int main()
{
    char JokinMerkki = 'a';      // esitelläänfunktion muuttuja,parametrina nytchar paikallisena, nyt muutuja näkyy vain tässä funktiossa
    TulostaMerkki(JokinMerkki);  // Funktio saa parametrinaan JokinMerkki muuttujan arvon
    getch();
    return 1;
}

...

Esimerkki 3

Code Block

void LaskeYhteen(int Eka, int Tokatyyppinen muuttuja
{
    printf("Antamasi merkki oli %c", Merkki); // tulostetaan annettu merkki %c:n osoittamaan kohtaan
}

int main()
{
    intchar SummaJokinMerkki = 0;

'a';     Summa =// Ekaesitellään + Toka;
    printf("\nsumma on %d", Summa);
}

int muuttuja, nyt paikallisena, nyt muutuja näkyy vain tässä funktiossa
    TulostaMerkki(JokinMerkki);  // Funktio saa parametrinaan JokinMerkki muuttujan arvon
    getch();
    return 1;
}


Anchor
esim3
esim3

Esimerkki 3

Code Block

void LaskeYhteen(int Eka, int Toka)main()                      // pääohjelma
{
    int FirstSumma = 5, Second = 60;

    Summa = Eka + Toka;
    LaskeYhteen(Firstprintf("\nsumma on %d", SecondSumma); // funktion kutsu, kutsussa ja itse funktiossa muuttujien nimet voivat olla erilaisia!
    return 
}

int main()
{
    LaskeYhteen(4, 6);
    return 1;
}

Edellä oleva funktio ottaa parametreikseen kaksi kokonaislukua ja sijoittaa ne funktion paikallisiin muuttujiin Eka ja Toka. Funktion laskema tulos näytetään ruudulla. Tämä funktio ei palauta mitään tietoa kutsujalle.

...

Paluuarvona ei saa palauttaa esimerkiksi osoitteita paikallisiin muuttujiin, koska ne häviävät funktion päättymisen jälkeen.

Funktio ja osoiteparametrit

Kun funktion pitää muuttaa muuttujan arvoa kutsuvassa ohjelmassa, pitää muuttujasta välittää sen osoite eikä muuttujan arvoa.

Esimerkki 6

...

...

Funktion prototyyppi (esittely)

Funktio esitellään ennen sen käyttöä. Funktion esittelyä sanotaan myös funktion prototyypiksi. Esittely tapahtuu seuraavasti:

Code Block

int

...

Code Block

void LaskeYhteen(int Eka, int Toka, int *Summa);
{

tai

Code Block
int LaskeYhteen(int, int);

Funktion esittelyn tarkoituksena on kertoa kääntäjälle (kääntäjä kääntää ohjelmoijan koodin koneen ymmärtämään muotoon) etukäteen millaisia funktioita ohjelmassa on, lisäksi kerrotaan miten funktiota voidaan kutsua, jotta kääntäjä voi tarkastaa, menikö kutsu oikein. Jos kutsu oli virheellinen, antaa kääntäjä siitä virheilmoituksen. Funktioiden esittelyt laitetaan ohjelman alkuun tai erillisiin otsikkotiedostoihin.

Kuten edellä nähdään, funktioiden parametrien nimiä ei välttämättä tarvita esittelyssä.

Note

Funktiot voidaan jättää myös esittelemättä, jos ne on lähdekoodissa ennen pääohjelmaa ja siinä järjestyksessä, että kutsuttava on lähdekoodissa ennen kutsujaa. Tätä tapaa ei kuitenkaan suositella kuin joissain sulautettujen laitteiden ohjelmoinnissa.

...

Funktio ja osoiteparametrit

Kun funktion pitää muuttaa muuttujan arvoa kutsuvassa ohjelmassa, pitää muuttujasta välittää sen osoite eikä muuttujan arvoa.

Anchor
esim6
esim6

Esimerkki 6

Code Block

void LaskeYhteen(int Eka, int Toka, int *Summa)
{
    *Summa = Eka + Toka;   *Summa = Eka + Toka;               // * summan edessä aiheuttaa sen ettei osiotteen arvoa muuteta, vaan osoittimen osoittaman muistipaikan sisältö
}

void main()                            // pääohjelma
{
    int First=5, Second=8, Sum=0;

    LaskeYhteen(First, Second, &Sum);  // välitetään yhteenlaskettavat arvoparametreina ja summa osoiteparametrina,
                                       // * summan jottaedessä summaaiheuttaa saadansen muutettuaettei nollastaosiotteen haluttuunarvoa arvoonmuuteta, kutsuttavassavaan funktiossa
osoittimen osoittaman muistipaikan  printf("\nsumma on %d", Sum);
    getch();
}

Edellä kuvattu menetelmä vaatii jo hieman huolellisuutta. Koska funktion parametrit esitellään nyt muuttujina. Aina kun tyypin ja muuttujan nimen välissä on * merkki, tämä tarkoittaa, että muuttuja on osoite. Taas * pelkän muuttujan nimen edessä merkitsee siirtymistä muuttujan osoitteesta muuttujan sisältöön. * voi tietysti myös tarkoittaa pelkkää kertomista, onneksi kääntäjä osaa päätellä tämän.

Funktion esittely

Funktio esitellään ennen sen käyttöä. Funktion esittelyä sanotaan myös funktion prototyypiksi. Esittely tapahtuu seuraavasti:

Code Block

int LaskeYhteen(int Eka, int Toka);

tai

Code Block

int LaskeYhteen(int, int);

ja

Code Block

void LaskeYhteen(int *Eka, int *Toka, int *Summa);

tai

Code Block

void LaskeYhteen(int*, int*, int*);

...

sisältö
}

void main()                            // pääohjelma
{
    int First=5, Second=8, Sum=0;

    LaskeYhteen(First, Second, &Sum);  // välitetään yhteenlaskettavat arvoparametreina ja summa osoiteparametrina,
                                       // jotta summa saadan muutettua nollasta haluttuun arvoon kutsuttavassa funktiossa
    printf("\nsumma on %d", Sum);
    getch();
}

Edellä kuvattu menetelmä vaatii jo hieman huolellisuutta. Koska funktion parametrit esitellään nyt muuttujina. Aina kun tyypin ja muuttujan nimen välissä on * merkki, tämä tarkoittaa, että muuttuja on osoite. Taas * pelkän muuttujan nimen edessä merkitsee siirtymistä muuttujan osoitteesta muuttujan sisältöön. * voi tietysti myös tarkoittaa pelkkää kertomista, onneksi kääntäjä osaa päätellä tämän.

Prototyyppi
Code Block

void LaskeYhteen(int *Eka, int *Toka, int *Summa);

tai

Code Block

void LaskeYhteen(int*, int*, int*);

...

Merkkijono funktion parametrina

Funktio ei voi palauttaa merkkijonoja eikä taulukoita, vaan näissä tapuksissa palautetaan aina osoite. Lisäksi osoitteen täyttyy olla kutsuvan funktion varaama, koska kutsuttavan funktion muuttujavaraukset häviävät funktoista palataessa.eikä taulukoita, vaan näissä tapuksissa palautetaan aina osoite. Täytyy myös ottaa huomioon, se missä merkkijonolle on varattu muisti. Jos se varataan dynaamisesti, se voidaan tehdä funktiossa, mutta jos se varataa staattisesti (ns. normaalisti), se täytyy varata funktion ulkopuolella, koska funktion paikalliset muuttujat tuhoutuvat funktiosta palattaessa.

Prototyyppi:

Code Block
void AnnaNimesi(char OmaNimi[]);

...

Code Block
void AnnaNimesi(char*);         // tästä voisi päätellä että kyseessä onkin osoite

Ja itse funktio:

Code Block
void AnnaNimesi(char OmaNimi[]) // itse asiassa tässä välitetään osoite merkkijonoon
{
    printf("Anna nimesi: ");
    gets(OmaNimi);              // tässäkin välitetään merkkijonon osoite
}

void main()//pääohjelma
{
    char Nimi[100];
    AnnaNimesi(Nimi);             // ei tarvita &-merkkiä, koska Nimi on osoite merkkitaulukkoon Nimi[100]

    printf("\nnimi on %s", Nimi);
    getch();
}

Huomaa, että kutsuttava funktio EI määrää merkkijonon pituutta, ainoastaan kutsuja muuttujan esittelyssä!!!

Vektori funktion parametrina

Vektori on yksiuloitteinen taulukko. Vektori voi sisältää alkioinaan kaikkia C:n tyyppejä.   Funktio ei voi palauttaa, vaan ainoastaan osoitteen vektorin. Lisäksi osoitteen täyttyy olla kutsuvan funktion varaama, koska kutsuttavan funktion muuttujavaraukset häviävät funktoista palataessa.

Code Block
void Tayta(int* taulu);                // esitellään funktio, joka ottaa parametrikseen osoitteen kokonaislukuun

int main()
{
    int Taulu[50];
    Tayta(Taulu);
    getch();

    return 1;
}

void Tayta(int* Vektori)
{
    int koko = sizeof(Vektori);         // selvitetään vektorin koko tavuina
    int IntinKoko = sizeof(int);        // selvitetään int muuttujankoko tavuina
    int JasentenMaara = koko/IntinKoko; // lasketaan vektorin alkioiden määrä
    for(int i=0;i // ?
}

Taulukko funktion parametrina

Taulukko on useampi- kuin yksiulotteinen taulukko. Taulukko voi sisältää alkioinaan kaikkia C:n tyyppejä. Funktio ei voi palauttaa koko taulukkoa, vaan ainoastaan osoitteen. Lisäksi osoitteen täyttyy olla kutsuvan funktion varaama, koska kutsuttavan funktion muuttujavaraukset häviävät funktiosta palattaessa. Ensimmäisen kokoparametrin voi halutessaan jättää kutsusta pois kts. alla

...