290 likes | 434 Views
Sisältö Ohjausrakenteet ja ohjelmalohkot Funktiot. Rakenteinen ohjelmointi. 1. Ohjausrakenteet ja ohjelmalohkot. Ohjelman kulkua ohjataan ohjausrakenteilla, joita on kaksi eri tyyppiä. Valinta kahdesta tai useammasta vaihtoehdosta Toisto.
E N D
Sisältö Ohjausrakenteet ja ohjelmalohkot Funktiot Rakenteinen ohjelmointi
1. Ohjausrakenteet ja ohjelmalohkot Ohjelman kulkua ohjataan ohjausrakenteilla, joita on kaksi eri tyyppiä • Valinta kahdesta tai useammasta vaihtoehdosta • Toisto Ohjelman etenemistä voidaan ohjata myös ns. hyppylauseilla. Hyppylauseita ei kuitenkaan tule suosia tarpeettomasti, sillä ne tekevät ohjelmakoodista vaikeaselkoista.
1. Ohjausrakenteet ja ohjelmalohkot Kielen säännöt ja niiden tulkitseminen • Syntaksi on kielioppi, tarkkaan määritetty säännöstö, jonka mukaan kielen ilmaisut on koottava kielen tunnistamista rakenneosista • Semantiikka on syntaktisten rakenteiden määrittelemä merkitys
1. Ohjausrakenteet ja ohjelmalohkot Valinta/ehtolause (if, if/else) Syntaksi Semantiikka if (lauseke) lause; if (lauseke) lause1; else lause2; Jos ehtolauseke on tosi (lauseke≠ 0), niin suoritetaan lause Jos ehtolausekeon tosi (lauseke ≠ 0), niin suoritetaan lause1, muussa tapauksessa (lauseke = 0) suoritetaan lause2. Huom! Tässä ja myöhemmin kielen syntaksin mukaiset merkistöt ja sanat kuvataan punaisella ja ohjelmoijan määrittelemät osat valkoisella kursiivilla.
1. Ohjausrakenteet ja ohjelmalohkot Valinta, vertailuoperaattorit If –valintalauseessa ehtolauseke muodostetaan yleensä ns. vertailuoperaattoreilla.
1. Ohjausrakenteet ja ohjelmalohkot Valinta/ehtolause (if, if/else) Esimerkki 1 Semantiikka int main() { int Kallen_ika=15, Villen_ika=16; printf(”Anna Kallen ikä\n”); scanf(”%d”,&Kallen_ika); printf(”Anna Villen ikä\n”); scanf(”%d”,&Villen_ika); if (Kallen_ika>=Villen_ika) printf(”Kalle on vähintään yhtä vanha kuin Ville\n”); else printf(”Ville on vanhempi kuin Kalle\n”); return 0; } Kysellään käyttäjältä muuttujien arvot Ohjataan käyttäjän syöttämien tietojen perusteella oikea tulostus.
1. Ohjausrakenteet ja ohjelmalohkot Valinta/ehtolause (if, if/else) Esimerkki 2 Semantiikka int main() { int Kallen_ika, Villen_ika; printf(”\nAnna Kallen ikä\n”); scanf(”%d”,&Kallen_ika); printf(”\nAnna Villen ikä\n”); scanf(”%d”,&Villen_ika); if (Kallen_ika>Villen_ika) printf(”\nKalle on vanhempi kuin Ville\n”); else if (Kallen_ika==Villen_ika) printf(”\nKalle ja Ville ovat yhtä vanhoja\n”); else printf(”\nVille on vanhempi kuin Kalle\n”); return 0; } Ensimmäinen if -lause Toinen if –lause, joka on ensimmäisen if –lauseen else -lohko.
1. Ohjausrakenteet ja ohjelmalohkot Valinta, loogiset operaattorit If –valintalauseessa ehtolauseke voidaan muodostaa myös loogisten operaattoreiden avulla (&&, || sekä !). Esimerkiksi Huom! Yhdistetyissä lausekkeissa on turvallisinta käyttää aina sulkeita varmistamaan sen, mitkä operandit (tässä a, b ja c) halutaan kuuluvan millekin operaattorille
1. Ohjausrakenteet ja ohjelmalohkot Valinta, loogiset operaattorit && (ja), || (tai) sekä ! (negaatio) ja niiden totuusarvotaulukot Tulos tosi && tosi tosi epätosi && tosi epätosi (tulos määräytyy pelkästään 1. operandin perusteella) tosi && epätosi eptosi epätosi && epätosi epätosi tosi || tosi tosi epätosi || tosi tosi tosi || epätosi tosi (tulos määräytyy pelkästään 1. operandin perusteella) epätosi || epätosi epätosi !tosi epätosi !epätosi tosi
1. Ohjausrakenteet ja ohjelmalohkot Valinta/ehtolause (if, if/else) Syntaksi Semantiikka if (lauseke) { lause1; lause2; } else { lause3; lause4; } Usein joudutaan ohjausrakenteessa käyttämään ns. koottua lausetta, jossa peräkkäiset lauseet yhdistetään lohkoksi aaltosulkeilla. Huom! Pelkät rivinvaihdot ja sarkainten käyttö eivät muodosta oikeaoppista rakennetta. Mikäli lohkoa ei merkitä aaltosulkeilla, jälkimmäiset lauseet lause2 ja lause4 eivät kuulu if –rakenteeseen oikein
1. Ohjausrakenteet ja ohjelmalohkot Valinta/ehtolause (if, if/else) Esimerkki 3 Semantiikka printf(”Anna kokonaisluku väliltä 1 … 10\n"); scanf("%d",&luku); if ( (luku >= 1) && (luku <= 10) ) { testi = luku%2; if ( testi==0) printf(”Syötit parillisen luvun”); else printf(”Syötit parittoman luvun”); } else printf(”Luku ei ole väliltä 1 … 10\n"); Testataan onko luku oikean kokoinen Aaltosuluilla rajattu koottu lause, jossa testataan ja tulostetaan onko luku parillinen vai pariton. Harj. Kirjoita oheinen ohjelma ja testaa toimiiko se oikein kaikissa tilanteissa.
1. Ohjausrakenteet ja ohjelmalohkot Valinta/tapauslause (switch) Syntaksi Semantiikka Jos lausekkeen arvo on vakio1, niin suoritetaan lause1, jos lausekeen arvo on vakio2, niin suoritetaan lause2, … jne. Mikäli lausekkeen arvo ei ole mikään arvoista arvo1 … arvon, ei suoriteta mitään. Vakioina käytetään yleisesti kokonaislukuja tai merkkejä. switch(lauseke) { casevakio1:lause1; break; casevakio2:lause2; break; ¨¨ casevakion:lausen; break; } Huom! Koko switch -lauseen lohko on merkittävä aaltosulkeilla. Kullakin valinnalla voi sen sijaan olla useita lauseita yhdistettynä peräkkäin ilman erillisiä lohkomerkkejä, sillä break keskeyttää koko switch -lauseen suorituksen
1. Ohjausrakenteet ja ohjelmalohkot Valinta/tapauslause (switch) Syntaksi Semantiikka switch(lauseke) { casevakio1:lause1; break; casevakio2:lause2; break; ¨¨ casevakion:lausen; break; default: lause0; break; } switch –lauseeseen voidaan liittää default –osa, joka suoritetaan aina, kun lausekkeen arvo ei ole mikään arvoista vakio1 … vakion.
1. Ohjausrakenteet ja ohjelmalohkot Valinta/tapauslause (switch) Harjoitus: Laadi ohjelma, joka lukee käyttäjältä henkilön painon ja pituuden, laskee henkilön painoindeksin kaavalla sekä tulostaa painoindeksin ja ohjeet ruokavalion säilyttämiseksi tai muuttamiseksi oheisen taulukon mukaan: Normaalia alhaisempi paino 18,4 tai alle Normaali paino 18,5 - 24,9 Lievä lihavuus 25,0 - 29,9 Merkittävä lihavuus 30,0 - 34,9 Vaikea lihavuus 35,0 - 39,9 Sairaalloinen lihavuus 40,0 tai yli Testaa ohjelman toimivuus kaikissa luokissa.
1. Ohjausrakenteet ja ohjelmalohkot Toisto/ Alkuehtoinen toisto (while) Syntaksi Semantiikka Niin kauan, kun ehtolausekkeen lauseke arvo on tosi(0), niin toistetaan lauseet lause1, lause2, … lausen. Alkuehtoinen toisto on hyvä silloin, kun lauseita ei välttämättä haluta suorittaa kertaakaan. while(lauseke) { lause1; lause2; ¨¨ lausen; } Huom! Jälkimmäisen lohkomerkin jälkeen ei tule puolipistettä
1. Ohjausrakenteet ja ohjelmalohkot Toisto/ Loppuehtoinen toisto (do … while) Syntaksi Semantiikka Niin kauan, kun ehtolausekkeen lauseke arvo on tosi(0), niin toistetaan lauseet lause1, lause2, … lausen. Loppuehtoinen toisto on hyvä silloin, kun lauseet halutaan välttämättä suorittaa ainakin kerran. do { lause1; lause2; ¨¨ lausen; } while(lauseke);
1. Ohjausrakenteet ja ohjelmalohkot Toisto/ lukumääräinen toisto (for) Syntaksi Semantiikka Alustetaan laskuri. Niin kauan, kun ehtolausekkeen lauseke arvo on tosi(0), toistetaan lauseet lause1, lause2, … lausen sekä kasvatetaan laskuria tässä järjestyksessä. Lukumääräinen toisto on hyvä silloin, kun tiedetään kuinka monta kertaa lauseet halutaan suorittaa esimerkiksi käytäessä taulukkorakennetta läpi. for(laskurinalustus;lauseke;laskurinkasvatus) { lause1; lause2; ¨¨ lausen; }
1. Ohjausrakenteet ja ohjelmalohkot Toisto Esimerkki Semantiikka Kaikkia toistolauseita voidaan käyttää saman tehtävän ratkaisuna. Käytäntö kuitenkin opettaa mikä kolmesta ohjausrakenteesta milloinkin on luontevin. int i; printf(”Kokonaislukujen 1 … 10 neliöt:\n"); i = 1; while ( i <= 10) { printf(”Luvun %d neliö = %d\n”, i, i*i); i = i + 1; } i = 1; do { printf(”Luvun %d neliö = %d\n”, i, i*i); i = i + 1; } while (i <= 10); for ( i=1 ; i <= 10 ; i = i + 1 ) printf(”Luvun %d neliö = %d\n”, i, i*i); • Kun käytetään silmukkalaskuria, on huolehdittava, että seuraavat kolme asiaa ovat kunnossa; • Laskurin alustus i=1 • Toistoehto i<=10 • Laskurin kasvatus i=i+1
1. Ohjausrakenteet ja ohjelmalohkot Toisto Esimerkki Käyttöliittymä Semantiikka Tulostetaan ohjeet char valinta; do { printf("Valitse toiminto\n"); printf("a) syöttö b) tulostus x) lopetus\n") fflush(stdin); scanf("%c",&valinta); switch(valinta) { case ’a’: syotto(); break; case ’b’: tulostus(); break; case ’x’: break; default: printf(”Kirjoita a, b tai x\n”); } while (valinta != 'x’ ); Tyhjennetään syöttöpuskuri ja luetaan käyttäjän valinta Käyttäjän valinnan mukaan suoritetaan syöttö, tulostus tai lopetus default-osassa tulostetaan ohjeet tapauksessa, jossa käyttäjä ei ole ymmärtänyt kirjoittaa oikeaa kirjainta
1. Ohjausrakenteet ja ohjelmalohkot Toisto Harjoitus 1: Laadi ohjelma, joka laskee yhteen ja tulostaa 100 ensimmäisen kokonaisluvun summan. Harjoitus 2: Laadi ohjelma, joka tulostaa sanan pieni kirjain, suuri kirjain tai muu merkki riippuen siitä minkä merkin käyttäjä on syöttänyt. Käyttäjä voi jatkaa kirjainten syöttämistä ja ohjelma lopetetaan vasta, kun käyttäjä syöttää numeron. Ohje: merkkimuuttuja (char) on myös kokonaislukumuuttuja, ja kullakin merkillä on numeerinen ASCII-arvo. Esimerkiksi kirjainten A … Y ASCII-arvot ovat kokonaislukujen 65 ja 89 välissä, kirjaimet a … y ovat lukujen 97 ja 121 välissä sekä numeroiden 0 … 9 ASCII-arvot ovat lukujen 48 ja 57 välissä (skandit voidaan tulkita muiksi merkeiksi).
1. Ohjausrakenteet ja ohjelmalohkot Harjoituksen 2 pseudokoodi Toisto toistetaan tulosta käyttäjälle syöttöohje nollataan syöttöpuskuri (fflush(stdin);) luetaan käyttäjältä merkki josmerkki on kokonaislukujen 65 ja 89 välissä tulostetaan iso kirjain muutoin, josmerkki on kokonaislukujen 97 ja 121 välissä tulostetaan pieni kirjain muutoin tulostetaan muu merkki niin kauan, kunmerkki ei ole koko kokonaislukujen 48 ja 57 välissä
2. Funktiot Otsikko ja määrittely Syntaksi Semantiikka Paluuarvon tyyppi Funktion nimi tyyppitunniste( parametritopt) { määrittelyt lauseet } Parametrien lista (voi olla tyhjä) Paikallisten muuttujien määrittely Funktion toiminnan määrittelevät lauseet Funktion ensimmäistä riviä kutsutaan funktion otsikoksi
2. Funktiot Paluuarvo ja return -lause Syntaksi Semantiikka Kaikille paluuarvon tietotyypeille funktion pitää palauttaa return-lauseella vastaava tietotyyppi. Jos funktio ei palauta mitään arvoa (esimerkiksi monet tulostusfunktiot), kirjoitetaan paluuarvoksi void, jolloin return –lausetta ei tarvita Ehdollisissa kontrollirakenteissa voi olla useitakinreturn-lauseita intomafunktio(parametritopt) { intluku; … luku= … … returnluku; }
2. Funktiot Parametrien ja paikallisten muuttujien määrittely Semantiikka Syntaksi Funktion muodolliset parametrit välittävät tietoa funktiolle kutsuvasta ohjelman osasta. Muodolliset parametrit esitellään sulkeiden sisällä samalla periaatteella kuin paikalliset muuttujatkin tyyppitunniste Parametreja käytetään runko-osassa kuten muitakin muuttujia. Niiden sisältämä arvo määräytyy kutsuvan ohjelman osan mukaan. floatlaskeka(floatluku1, floatluku2) { floatkeskiarvo; keskiarvo= (luku1+luku2)/2; returnkeskiarvo; }
2. Funktiot Funktion esittely ja kutsuminen Semantiikka Syntaksi C-kielessä kaikki kutsuttavat funktiot on esiteltävä koodissa ennen sitä ohjelmalohkoa, jossa kutsu esiintyy. Funktioiden esittelyt tehdään yleensä ennen main() funktiota ja niiden määrittelyt sen jälkeen. Esittelyyn riittää kirjoittaa funktion otsikko. Funktion kutsuparametrien nimen ei tarvitse olla sama kuin funktion otsikossa olevien muodollisten parametrien. Funktion paluuarvo sijoitetaan sitä vastaavan tietotyypin muuttujan arvoksi. floatlaskeka(floatluku1,floatluku2); int main( ) { float eka=5.1;toka=4.2; float ka; ka = laskeka(eka, toka); … }
2. Funktiot C-ohjelman käännösyksikön yleinen rakenne, paikalliset ja globaalit muuttujat Semantiikka Syntaksi esikääntäjäkutsut globaalienMuuttujienMäärittely funktioidenEsittely intmain( ) { paikallistenMuuttujienMäärittely ohjelmanLauseet } funktioidenMäärittelyt Esikääntäjäkutsut kirjoitetaan kaikki eri riveille, mutta puolipistettä ei käytetä. esimerkiksi #include <stdio.h> Globaalit muuttujat näkyvät kaikissa alla määritellyissä funktioissa. Paikalliset muuttujat näkyvät vain siinä ohjelmalohkossa, missä ne ovat määritelty.
2. Funktiot Funktioiden määrittelyt ja toisen funktion kutsuminen Semantiikka Syntaksi tyyppi funktio1(parametritOpt ) { paikallistenMuuttujienMäärittely funktionToiminta } tyyppi funktio2(parametritOpt ) { paikallistenMuuttujienMäärittely funktionToiminta …funktio1(kutsuparametrit)… } … C-kielessä jokainen funktion määrittely muodostaa oman itsenäisen ohjelmalohkonsa, sisäkkäisiä määrittelyjä ei sallita. Funktiot voivat kutsua toisia funktioita, jos kutsuttava funktio on vähintään esitelty (tai myös määritelty) koodissa ennen sitä ohjelmalohkoa, jossa kutsu esiintyy.
2. Funktiot Rekursiivinen funktio Semantiikka Syntaksi tyyppi rek_funktio(parametritOpt ) { paikallistenMuuttujienMäärittely funktionToiminta …rek_funktio(kutsuparametrit)… } Funktiot voivat kutsua myös itseään, jolloin kyseessä on rekursiivinen funktio. Rekursiivinen funktion käyttö on tärkeä ohjelmallinen ratkaisu moniin ohjelmointiongelmiin. Rekursion käyttöön liittyy aina myös ongelmia, koska se kuluttaa paljon ohjelman vaatimaa muistitilaa. Lisäksi, jos käytetään useita rekursiivisia kutsuja, voi myös ohjelman suoritukseen kuluva aika kasvaa kohtuuttomasti.
2. Funktiot Rekursion määrittely Semantiikka Esimerkki Funktio kertoma() palauttaa syötetyn luvun kertoman (!) eli kertoma(0)=0!=1 kertoma(1)=1!=1 kertoma(2)=2!=2*1!=2 kertoma(3)=3!=3*2!=6 jne… int kertoma(int luku) { if( luku == 0 || luku == 1) return 1; else returnluku*kertoma(luku-1); } Kuten toistolauseissakin tulee myös rekursiossa olla jokin ehto, jonka toteutuminen päättää rekursiiviset kutsut. Huom! Rekursio voidaan aina (jos osataan) korvata toistolauseilla (esim. for).