Esittely latautuu. Ole hyvä ja odota

Esittely latautuu. Ole hyvä ja odota

Tiedon vieminen funktiolle tMyn1 Tiedon vieminen funktiolle, parametrit Argumentin vieminen funktiolle voidaan toteuttaa kahdella menetelmällä: –Pass-by-Value.

Samankaltaiset esitykset


Esitys aiheesta: "Tiedon vieminen funktiolle tMyn1 Tiedon vieminen funktiolle, parametrit Argumentin vieminen funktiolle voidaan toteuttaa kahdella menetelmällä: –Pass-by-Value."— Esityksen transkriptio:

1 Tiedon vieminen funktiolle tMyn1 Tiedon vieminen funktiolle, parametrit Argumentin vieminen funktiolle voidaan toteuttaa kahdella menetelmällä: –Pass-by-Value -mekanismi. –Pass-by-Reference -mekanismi.

2 Tiedon vieminen funktiolle tMyn2 Arvoparametri, Pass-by-Value Tässä menetelmässä funktion kutsun yhteydessä funktion argumenttina oleva muuttuja tai vakio ei itse asiassa siirry funktioon. Muuttujasta tai vakiosta tehdään kopio, ja tämä kopio viedään funktioon. Kun funktion suoritus päättyy, kopiot häviävät pois. Käytetään ensimmäisenä esimerkkinä aiemmin esiteltyä potenssiinKorotus-funktiota:

3 Tiedon vieminen funktiolle tMyn3... double kantaluku=20.0; int potenssi=3; double vastaus=potenssiinKorotus(kantaluku, potenssi); double potenssiinKorotus(double x, int n) { Täällä oleva koodi ei voi operoida alkuperäisiä muuttujia kantaluku ja potenssi. } potenssi kantaluku kopio 20.0 3 3 main-funktiossa:

4 Tiedon vieminen funktiolle tMyn4 Otetaan seuraava esimerkki – se edustaa samalla HUONOA tunnusten nimeämistapaa!!

5 Tiedon vieminen funktiolle tMyn5 using namespace System; using namespace std; double muutaArvo(double); int main(array ^args) { double arvo=5.0; double muutos=muutaArvo(arvo); cout<<"Funktion suorittamisen j\204lkeen " <<"\"arvo\"= "<<arvo<<"."<<endl; cout<<"Funktion palauttama arvo on " <<muutos<<"."<<endl; return 0; }

6 Tiedon vieminen funktiolle tMyn6 double muutaArvo(double arvo) { arvo+=10.0; cout<<"Funktion sis\204lt\204 \"arvo\"=" <<arvo<<"."<<endl; return arvo; }

7 Tiedon vieminen funktiolle tMyn7 muuttuja arvo funktiossa main() muuttujasta arvo tehdään kopio, kun funktiota muutaArvo() kutsutaan main()-funktiossa. kopio muuttujasta arvo: double muutos=muutaArvo(arvo); double muutaArvo(double arvo) { arvo+=10.0; cout<<"Funktion sis\204lt\204 \"arvo\"=" <<arvo<<"."<<endl; return arvo; } Tehdään paikallisesta muuttujasta arvo kopio, ja tämä palautetaan kutsuvaan ohjelmanosaan! Paluuarvosta tehtyä kopiota käytetään tässä, koska alkuperäinen paikallinen muuttuja arvo funktion muutaArvo() sisällä on lakannut olemasta! Tämä on lause main() -funktiosta: 55 15

8 Tiedon vieminen funktiolle tMyn8 Entä jos kutsuvan ohjelmanosan muuttujan arvoa halutaan muuttaa kutsutun funktion kautta? Pysytään edelleenkin pass-by-value -kategoriassa. Tällöin käytetään funktion argumenttina osoitinmuuttujaa. Koska osoitinmuuttujan kopio sisältää saman osoitteen kuin alkuperäinen osoitinmuuttuja, niin nyt kopio osoittaa samaan keskusmuistiosoitteeseen! Kirjoitetaan aiempi esimerkki tähän tilanteeseen sopivaksi:

9 Tiedon vieminen funktiolle tMyn9 using namespace System; using namespace std; double muutaArvo(double*); int main(array ^args) { double arvo=5.0; double muutos=muutaArvo(&arvo); cout<<"Funktion suorittamisen j\204lkeen " <<"\"arvo\"="<<arvo<<"."<<endl; cout<<"Funktion palauttama arvo on " <<muutos<<"."<<endl; return 0; }

10 Tiedon vieminen funktiolle tMyn10 double muutaArvo(double* osArvo) { *osArvo+=10.0; cout<<"Funktion sis\204lt\204 \"arvo\"=" <<*osArvo<<"."<<endl; return *osArvo; }

11 Tiedon vieminen funktiolle tMyn11 Olkoot muuttujan arvo osoite funktiossa main(): muuttujan arvo osoitteesta tehdään kopio, kun funktiota muutaArvo() kutsutaan main()-funktiossa. double muutos = muutaArvo(&arvo); double muutaArvo(double* osArvo) { *osArvo+=10.0; cout<<"Funktion sis\204lt\204 \"arvo\"=" <<*osArvo<<"."<<endl; return *osArvo; } Tehdään palautettavasta arvosta kopio, ja tämä kopio palautetaan kutsuvaan ohjelmanosaan! Tämä on lause main() -funktiosta: 64FDEC 15 64FDEC 5 Tämä kasvattaa main()-osassa olevan muuttujan arvoa 10.0:lla

12 Tiedon vieminen funktiolle tMyn12 Yksiulotteinen taulukko funktion argumenttina Taulukon nimi on osoitin taulukon ensimmäiseen alkioon. Kun taulukko välitetään argumenttina funktiolle, niin käytännössä taulukon alkuosoite kopioidaan, ja tämä osoitteen kopio välitetään funktiolle. Taulukkoa ei voi välittää funktiolle muulla tapaa. Seuraavassa esimerkissä lasketaan taulukon alkioiden arvojen keskiarvo. Aluksi ei käytetä osoitinnotaatioita:

13 Tiedon vieminen funktiolle tMyn13 using namespace System; using namespace std; double keskiarvo(double [], int); int main(array ^args) { double mitattu[]={2.1, 4.7, 6.8, 3.1, 8.5, 9.4, 7.7, 5.3, 3.9}; cout<<"Keskiarvo = " <<keskiarvo(mitattu, (sizeof mitattu)/(sizeof mitattu[0])) <<"."<<endl; return 0; }

14 Tiedon vieminen funktiolle tMyn14 double keskiarvo(double numerot[], int maara) { double summa=0.0; for(int i=0; i<maara; i++) summa+=numerot[i]; return summa/maara; }

15 Tiedon vieminen funktiolle tMyn15 Funktion esittelyssä ensimmäisenä parametrinä oli double []. Hakasulkeiden sisään ei tule laittaa alkioiden lukumäärää. Jos sinne laittaisi jonkin kokonaisluvun, niin sillä ei olisi toivottua vaikutusta. Muutetaan ratkaisua siten, että käytetään avuksi osoitinnotaatiota:

16 Tiedon vieminen funktiolle tMyn16 using namespace System; using namespace std; double keskiarvo(double*, int); int main(array ^args) { double mitattu[]={2.1, 4.7, 6.8, 3.1, 8.5, 9.4, 7.7, 5.3, 3.9}; cout<<"Keskiarvo = " <<keskiarvo(mitattu, (sizeof mitattu)/(sizeof mitattu[0])) <<"."<<endl; return 0; }

17 Tiedon vieminen funktiolle tMyn17 double keskiarvo(double* viite, int maara) { double summa=0.0; for (int i=0; i<maara; i++) summa+=*viite++; return summa/maara; }

18 Tiedon vieminen funktiolle tMyn18 Funktion rungossa on rivi summa+=*viite++; Tässä ei ole ristiriitaa. Aikaisemmin on todettu, että ei ole mahdollista muuttaa taulukon nimeen liittyvää osoitetta. Funktiolle välitettiin kopio taulukon alkuosoitteesta, ja tämän kopion sisältämää osoitetta inkrementoidaan!!!

19 Tiedon vieminen funktiolle tMyn19 Kaksiulotteinen taulukko funktion argumenttina Kaksiulotteinen taulukko voisi olla vaikkapa double mitatut[3][4]; Tämä taulukko voitaisiin sijoittaa parametriksi funktion esittelyssä seuraavasti: double yhteenLaskettuna(double mitatut[3][4]); Ongelma on siinä, että yllä olevassa esittelyssä parametrina olevan taulukon ensimmäistä dimensiota ei voida tarkistaa… siispä yhtä hyvin olisi voitu kirjoittaa double yhteenLaskettuna(double mitatut[][4]);

20 Tiedon vieminen funktiolle tMyn20 Taulukon rivilukumäärä on siis vietävä funktiolle jotenkin käyttäen hyväksi toista parametriä, esim: double yhteenLaskettuna(double mitatut[][4], int rivi); Tehdään toimiva esimerkki:

21 Tiedon vieminen funktiolle tMyn21 using namespace System; using namespace std; double yhteenLaskettuna(double [][4], int); int main(array ^args) { double korkeudet[3][4] = { {1.8, 1.6, 1.4, 1.9}, {1.3, 1.2, 1.7, 1.2}, {2.0, 2.6, 1.4, 1.0} }; cout<<"Yhteenlasketuksi arvoksi saadaan " <<yhteenLaskettuna(korkeudet, sizeof korkeudet/ sizeof korkeudet[0]) <<"."<<endl; return 0; }

22 Tiedon vieminen funktiolle tMyn22 double yhteenLaskettuna(double mitatut[][4], int rivi) { double summa=0.0; for (int i=0; i<rivi; i++) for (int j=0; j<4; j++) summa+=mitatut[i][j]; return summa; }

23 Tiedon vieminen funktiolle tMyn23 Kun funktiolle välitetään argumenttina useampiulotteinen taulukko, niin silloin ei enää kannata käyttää osoitinnotaatiota. Tehdään se kuitenkin kerta kiellon päälle jotta nähdään, että se ei ole niin havainnollista:

24 Tiedon vieminen funktiolle tMyn24 using namespace System; using namespace std; double yhteenLaskettuna(double (*)[4], int); int main(array ^args) { double korkeudet[3][4] = { {1.8, 1.6, 1.4, 1.9}, {1.3, 1.2, 1.7, 1.2}, {2.0, 2.6, 1.4, 1.0} }; cout<<"Yhteenlasketuksi arvoksi saadaan " <<yhteenLaskettuna(korkeudet, sizeof korkeudet/ sizeof korkeudet[0])<<"."<<endl; return 0; }

25 Tiedon vieminen funktiolle tMyn25 double yhteenLaskettuna(double (*mitatut)[4], int rivi) { double summa=0.0; for (int i=0; i<rivi; i++) for (int j=0; j<4; j++) summa+=*(*(mitatut+i)+j); return summa; }

26 Tiedon vieminen funktiolle tMyn26 Viittausparametri, Pass-by-Reference Jos funktion esittelyssä on käytetty funktion parametrinä viittausparametriä, niin silloin funktiota kutsuttaessa käytetään funktion argumenttina tiedon välittämiseen funktiolle pass-by-reference - mekanismia. Viittausmuuttuja voidaan ymmärtää viitattavan muuttujan alias-nimenä. Viittausparametrin määrittely: void funktionNimi(tyyppi& viittausparametri)

27 Tiedon vieminen funktiolle tMyn27 int main() { int numero=20; … cout<<muutaArvoa(numero); …. return 0: } int muutaArvoa(int& arvo) { arvo+=10; return arvo; } Funktion kutsu main()-osasta: Toteutetaan funktio, jossa parametrina käytetään viittausparametria: Viittausmuuttuja arvo alustetaan muuttujalla numero, eli muuttujasta arvo tulee muuttujan numero alias. Muodostetaan paluuarvosta arvo kopio - siis tässä tapauksessa muuttujan numero sisällöstä kopio, ja tämä kopio palautetaan kutsuvaan osaan

28 Tiedon vieminen funktiolle tMyn28 Kun funktiossa käytetään (funktion suorituksen aikana) funktion esittelyssä viittausparametriksi määriteltyä argumenttia, kohdistuu käsittely suoraan argumenttina välitettyyn muuttujaan. Sitä ei siis kopioida funktiolle funktion kutsun yhteydessä. Tästä kopioimisen puuttumisesta aiheutuu myös se, että funktion suoritus on nopeampaa. Viittausparametrin käyttö funktion parametrinä saattaa olla hiukan hämäävää - ulkopuolinen koodin tarkkailija ei ehkä heti huomaa, että kutsuvan osan muuttujan arvoa tulee muutetuksi:

29 Tiedon vieminen funktiolle tMyn29 Funktion parametrina osoitinmuuttuja: int muutaArvoa(int* arvo) { *arvo+=10; return *arvo; } Funktiota kutsuttaessa argumenttina annetaan muuttujan osoite, jolloin on selvää, että kutsutun osan muuttujan arvoa saatetaan muuttaa!!... int luku=20; cout<< muutaArvoa(&luku);... Funktion parametrina viittausparametri: int muutaArvoa(int& arvo) { arvo+=10; return arvo; } Funktiota kutsuttaessa muodostuu kutsuvan osan muuttujan luku aliasnimeksi arvo. Kun siis funktiossa operoidaan aliasnimellä arvo, niin ei ole yhtä lailla ilmeistä, että samalla tullaan muuuttaneeksi kutsuvan ohjelmanosan muuttujan luku sisältöä!! … int luku=20; cout<<muutaArvo(luku)

30 Tiedon vieminen funktiolle tMyn30 Tehdään esimerkkiohjelma, jossa funktion parametreina on viiteparametreja. Tässä ei muuteta kutsuvan osan muuttujien arvoja:

31 Tiedon vieminen funktiolle tMyn31 using namespace System; using namespace std; int suurempiKahdesta(int&, int&); int main(array ^args) { int luku1, luku2; cout<<"Anna kaksi kokonaislukua: "; cin>>luku1>>luku2; cin.get(); cout<<"Suurempi annetuista on: " <<suurempiKahdesta(luku1, luku2)<<"."<<endl; return 0; }

32 Tiedon vieminen funktiolle tMyn32 int suurempiKahdesta(int& eka, int& toka) { if(eka>toka) return eka; else return toka; }


Lataa ppt "Tiedon vieminen funktiolle tMyn1 Tiedon vieminen funktiolle, parametrit Argumentin vieminen funktiolle voidaan toteuttaa kahdella menetelmällä: –Pass-by-Value."

Samankaltaiset esitykset


Iklan oleh Google