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

...

Funktio

...

on

...

itsenäinen

...

ohjelman

...

osa,

...

joka

...

tekee

...

jonkin

...

halutun

...

tehtävän,

...

se

...

voi

...

esimerkiksi

...

laskea

...

jonkin

...

laskutoimituksen.

...

Funktioiden

...

avulla

...

toteutetaan

...

ohjelmien

...

modulaarisuutta.

...


Funktioista

...

puhuttaessa

...

voidaan

...

erottaa

...

kaksi

...

tasoa:

...

  • Toisaalta

...

  • on

...

  • olemassa

...

  • valmiita

...

  • kirjastofunktioita,

...

  • jotka

...

  • ovat

...

  • kaikkien

...

  • ohjelmoijien

...

  • käytössä.

...

  • Toisaalta

...

  • jokainen

...

  • ohjelmoija

...

  • voi

...

  • kirjoittaa

...

  • funktioita

...

  • omaan

...

  • käyttöönsä.

Funktion syntaksi

Funktion täydellinen nimi koostuu kolmesta asiasta:

  1. paluuarvon tyyppistä (pakollinen!)
  2. funktion nimestä (pakollinen!)
  3. parametreista (ei pakollisia, riippuu funktiosta)
Code Block


h2. Funktion syntaksi

Funktion täydellinen nimi koostuu kolmesta asiasta:
# paluuarvon *tyyppistä* (pakollinen\!)
# funktion *nimestä* (pakollinen\!)
# _parametreista_ (ei pakollisia, riippuu funktiosta)

{code}
funktion_paluuarvon_tyyppi funktion_nimi(
	param_1_tyyppi parametri_1,
	param_2_tyyppi parametri_2,
	/* loput parametrit, jos on */)

Funktiotyypit

Funktioita voidaan tehdä erilaisia:

Anchor
esim1
esim1

Esimerkki 1

Seuraavassa esimerkissä funktio laskee kartion tilavuuden, funktion alussa esitellään ne muuttujat (tietovarastot), joita ohjelma tarvitsee.

Code Block
{code}

h2. Funktiotyypit

Funktioita voidaan tehdä erilaisia:

* [Ei parametreja - ei paluuarvoa|#esim1]
* [Parametri - ei paluuarvoa|#esim2]
* [Parametri ja paluuarvo|#esim4]

{anchor:esim1}

h3. Esimerkki 1

Seuraavassa esimerkissä funktio laskee kartion tilavuuden, funktion alussa esitellään ne muuttujat (tietovarastot), joita ohjelma tarvitsee.

{code}
void KartionTilavuus()
{
    float Sade, Korkeus, Tilavuus;            // esitellään funktion 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);
}
{code}

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

...

(kts.

...

seuraava

...

kohta).

...

Funktion

...

kutsuminen

...

Funktiota

...

kutsutaan

...

muodossa

...

funktion_nimi()

...

ja

...

sulkujen

...

sisään

...

tulevat

...

mahdolliset

...

parametrit.

...

Esim

...

funktion

...

kutsuminen

...

pääohjelmasta:

{
Code Block
}
int main()              // pääohjelma
{
    KartionTilavuus();  // funktion kutsu
    getch();            // jäädään odottamaan, että käyttäjä painaa jotain nappulaa
}
{code}
{note}Funktiota voidaan kutsua sen mistä tahansa ohjelmasta, myös funktiosta itsestään (vrt. [rekursio|http://fi.wikipedia.org/wiki/Rekursio]).
Note

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

Funktion parametrit 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.

Code Block
{note}

h2. Funktion parametrit 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.

{code}
void funktio(int x)
{
    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
{code}
* {{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}

h3. Esimerkki 2

{code}
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ään muuttuja, nyt paikallisena, nyt muutuja näkyy vain tässä funktiossa
    TulostaMerkki(JokinMerkki);  // Funktio saa parametrinaan JokinMerkki muuttujan arvon
    getch();
    return 1;
}
{code}
\\
{anchor:esim3}

h3. Esimerkki 3

{code}


Anchor
esim3
esim3

Esimerkki 3

Code Block
void LaskeYhteen(int Eka, int Toka)
{
    int Summa = 0;

    Summa = Eka + Toka;
    printf("\nsumma on %d", Summa);
}

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

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.

...

Funktion

...

paluuarvo

...

Funktio

...

voi

...

päätyttyään

...

palauttaa

...

kutsujalleen

...

tietoa.

...

Tieto

...

palautetaan

...

return

...

-käskyllä.

...

Funktiossa

...

voi

...

olla

...

useita

...

return

...

-lauseita

...

sopivissa

...

kohdissa.

...

Funktion

...

nimen

...

edessä

...

oleva

...

tyyppi

...

määrää

...

paluuarvon

...

tyypin

...

ja

...

siksi

...

return

...

-lauseen

...

perässä

...

olevan

...

arvon

...

pitää

...

olla

...

samaa

...

tyyppiä

...

(joko

...

vakio

...

tai

...

muuttuja).

Anchor
esim4
esim4

Esimerkki 4

Code Block


{anchor:esim4}

h3. Esimerkki 4

{code}
#include <stdio.h>
#include <conio.h>

char KysyMerkki()                    // funktion tyyppi on nyt char ja funktio paluttaa nyt kutsujalle näppäimistöltä annetun merkin
{
    printf("anna jokin merkki: ");
    return getch();                  // kysytään merkki näppäimistöltä ja palutetaan se funktiosta return lauseella
}

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;                // Esitellään muuttuja, nyt paikallisena, nyt muutuja näkyy vain tässä funktiossa
    JokinMerkki = KysyMerkki();      // Funktio palauttaa arvonsa muuttujaan JokinMerkki
    TulostaMerkki(JokinMerkki);      // Funktio saa parametrinaan JokinMerkki muuttujan arvon

    return 1;
}

Anchor
esim5
esim5

Esimerkki 5

Code Block
{code}
{anchor:esim5}

h3. Esimerkki 5

{code}
int LaskeYhteen(int Eka, int Toka)
{
    int Summa = 0;
    Summa = Eka + Toka;
    return Summa;
}

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

    Sum = LaskeYhteen(First, Second);  // Sum nappaa paluuarvon = merkillä
    printf("\nsumma on %d", Sum);

    getch();                           // jäädään odottamaan, että käyttäjä painaa jotain nappulaa
}
{code}

Paluuarvona

...

ei

...

saa

...

palauttaa

...

esimerkiksi

...

osoitteita

...

paikallisiin

...

muuttujiin,

...

koska

...

ne

...

häviävät

...

funktion

...

päättymisen

...

jälkeen.

...

...

Funktion prototyyppi (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);
{code}
tai
{

tai

Code Block
code}
int LaskeYhteen(int, int);
{code}

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
{note}
----
h2. Funktio ja osoiteparametrit

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

{anchor:esim6}

h4. Esimerkki 6

{code}
void LaskeYhteen(int Eka, int Toka, int *Summa)
{
    *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,
                                       // jotta summa saadan muutettua nollasta haluttuun arvoon kutsuttavassa funktiossa
    printf("\nsumma on %d", Sum);
    getch();
}
{code}

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


h5. Prototyyppi

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

tai

Code Block
{code}
void LaskeYhteen(int*, int*, int*);
{code}
----
h2. 

...

Merkkijono funktion parametrina

Funktio ei voi palauttaa merkkijonoja 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
Merkkijono funktion parametrina

Funktio ei voi palauttaa merkkijonoja eikä taulukoita, vaan näissä tapuksissa palautetaan aina [osoite|Osoittimet]. Täytyy myös ottaa huomioon, se missä merkkijonolle on varattu muisti. Jos se varataan [dynaamisesti|Muistin varaukset#dynaaminen], 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}
void AnnaNimesi(char OmaNimi[]);

tai

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

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()
{
    char Nimi[100];
    AnnaNimesi(Nimi);             // ei tarvita &-merkkiä, koska Nimi on osoite merkkitaulukkoon Nimi[100]

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

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
\!\!

h2. Vektori funktion parametrina

Vektori on yksiuloitteinen [taulukko|Taulukot]. 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}
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

Code Block
{code}

h2. 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

{code}
void Tayta(int taulu[][10], int);

int main()
{
    int rivit=5;
    int Taulu[5][10];
    Tayta(Taulu,rivit);
    return 1;
}

void Tayta(int Taulu[][10], int rivit)
{
    int i,j;
    int sarakkeenkoko = sizeof(*Taulu);            // selvitetään vektorin koko tavuina
    int IntinKoko = sizeof(int);                   // selvitetään int muuttujankoko tavuina
    int JasenetRivilla = sarakkeenkoko/IntinKoko;  // lasketaan vektorin alkioiden määrä
    for(j=0;j

{code}