Rakenteinen ohjelmointi
Sisältö
1.Ohjausrakenteet ja ohjelmalohkot
2.Funktiot
1. Ohjausrakenteet ja ohjelmalohkot
Valinta kahdesta tai useammasta vaihtoehdosta
Toisto
Ohjelman kulkua ohjataan ohjausrakenteilla, joita on kaksieri tyyppiä
Ohjelman etenemistä voidaan ohjata myös ns. hyppylauseilla.Hyppylauseita ei kuitenkaan tule suosia tarpeettomasti, sillä netekevät ohjelmakoodista vaikeaselkoista.
1. Ohjausrakenteet ja ohjelmalohkot
Syntaksi on kielioppi, tarkkaan määritetty säännöstö,jonka mukaan kielen ilmaisut on koottava kielentunnistamista rakenneosista
Semantiikka on syntaktisten rakenteidenmäärittelemä merkitys
Kielen säännöt ja niiden tulkitseminen
1. Ohjausrakenteet ja ohjelmalohkot
if (lauseke)
      lause;
if (lauseke)
      lause1;
else
      lause2;
Valinta/ehtolause (if, if/else)
Jos ehtolauseke on tosi (lauseke  0), niinsuoritetaan lause
Syntaksi
Semantiikka
Jos ehtolauseke on tosi (lauseke ≠ 0), niinsuoritetaan lause1, muussa tapauksessa(lauseke = 0) suoritetaan lause2.
Huom! Tässä ja myöhemmin kielen syntaksin mukaiset merkistöt ja sanatkuvataan punaisella ja ohjelmoijan määrittelemät osat valkoisella kursiivilla.
1. Ohjausrakenteet ja ohjelmalohkot
Valinta, vertailuoperaattorit
If –valintalauseessa ehtolauseke muodostetaan yleensä ns.vertailuoperaattoreilla.
Matem. esitys
C-operaattori
Semantiikka
a < b
< b
a pienempi kuin b
a > b
> b
a suurempi kuin b
 b
>= b
a suurempi tai yhtä suuri kuin b
 b
<= b
a pienempi tai yhtä suuri kuin b
a = b
== b
a sama kuin b
a ≠ b
!= b
a eri kuin b
1. Ohjausrakenteet ja ohjelmalohkot
Valinta/ehtolause (if, if/else)
Kysellään käyttäjältä muuttujienarvot
Esimerkki 1
Semantiikka
Ohjataan käyttäjän syöttämientietojen perusteella oikea tulostus.
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;
}
1. Ohjausrakenteet ja ohjelmalohkot
Valinta/ehtolause (if, if/else)
Ensimmäinen if -lause
Esimerkki 2
Semantiikka
Toinen if –lause, joka onensimmäisen if –lauseen else -lohko.
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;
}
1. Ohjausrakenteet ja ohjelmalohkot
Valinta, loogiset operaattorit
If –valintalauseessa ehtolauseke voidaan muodostaa myös loogistenoperaattoreiden avulla (&&|| sekä !). Esimerkiksi
Matem. esitys
C-operaattorit
Semantiikka
a < b < c
(< b) && (< c)
a pienempi kuin b ja b pienempikuin c
a < b  a > c
(< b) || (> c)
a pienempi kuin b tai asuurempi kuin c
(a>b)
!(a>b)
ei - a suurempi kuin b, eli onepätosi (=0), jos a > b, ja tosi(0) kun a  b.
Huom! Yhdistetyissä lausekkeissa on turvallisinta käyttää aina sulkeitavarmistamaan sen, mitkä operandit (tässä a, b ja c) halutaan kuuluvanmillekin  operaattorille
1. Ohjausrakenteet ja ohjelmalohkot
Valinta, loogiset operaattorit
&& (ja), || (tai) sekä ! (negaatio) ja niiden totuusarvotaulukot
Tulos
tosi && tositosi
epätosi && tosiepätosi (tulos määräytyy pelkästään 1. operandin
perusteella)
tosi && epätosieptosi
epätosi && epätosiepätosi
tosi || tositosi
epätosi || tositosi
tosi || epätositosi (tulos määräytyy pelkästään 1. operandin
perusteella)
epätosi || epätosiepätosi
!tosiepätosi
!epätositosi
1. Ohjausrakenteet ja ohjelmalohkot
if (lauseke)
{
      lause1;
lause2;
}
else
{
      lause3;
lause4;
}
Valinta/ehtolause (if, if/else)
Syntaksi
Semantiikka
Usein joudutaan ohjausrakenteessakäyttämään ns. koottua lausetta, jossaperäkkäiset lauseet yhdistetään lohkoksiaaltosulkeilla.
Huom! Pelkät rivinvaihdot ja sarkaintenkäyttö eivät muodosta oikeaoppistarakennetta. Mikäli lohkoa ei merkitäaaltosulkeilla, jälkimmäiset lauseet lause2ja lause4 eivät kuulu if –rakenteeseenoikein
1. Ohjausrakenteet ja ohjelmalohkot
Valinta/ehtolause (if, if/else)
Testataan onko luku oikeankokoinen
Esimerkki 3
Semantiikka
Aaltosuluilla rajattu koottu lause,jossa testataan ja tulostetaanonko luku parillinen vai pariton.
   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 ");
Harj. Kirjoita oheinenohjelma ja testaa toimiiko seoikein kaikissa tilanteissa.
1. Ohjausrakenteet ja ohjelmalohkot
switch (lauseke)
{
case vakio1: lause1;
         break;
case vakio2: lause2;
         break;
¨¨
case vakion: lausen;
         break;
}
Valinta/tapauslause (switch)
Jos lausekkeen arvo on vakio1, niinsuoritetaan lause1, jos lausekeen arvo onvakio2, niin suoritetaan lause2, … jne.
Mikäli lausekkeen arvo ei ole mikään arvoistaarvo1 … arvon, ei suoriteta mitään.
Vakioina käytetään yleisesti kokonaislukuja taimerkkejä.
Syntaksi
Semantiikka
Huom! Koko switch -lauseen lohko onmerkittävä aaltosulkeilla. Kullakin valinnalla voisen sijaan olla useita lauseita yhdistettynäperäkkäin ilman erillisiä lohkomerkkejä, silläbreak keskeyttää koko switch -lauseensuorituksen
1. Ohjausrakenteet ja ohjelmalohkot
switch (lauseke)
{
case vakio1: lause1;
          break;
case vakio2: lause2;
          break;
¨¨
case vakion: lausen;
          break;
default  lause0;
  break;
}
Valinta/tapauslause (switch)
switch –lauseeseen voidaan liittää default –osa, joka suoritetaan aina, kun lausekkeenarvo ei ole mikään arvoista vakio1 … vakion.
Syntaksi
Semantiikka
1. Ohjausrakenteet ja ohjelmalohkot
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 taimuuttamiseksi oheisen taulukon mukaan:
Normaalia alhaisempi paino  18,4 tai alle
Normaali paino 18,5 - 24,9
Lievä lihavuus25,0 - 29,9
Merkittävä lihavuus30,0 - 34,9
Vaikea lihavuus35,0 - 39,9
Sairaalloinen lihavuus40,0 tai yli
Testaa ohjelman toimivuus kaikissa luokissa.
Valinta/tapauslause (switch)
1. Ohjausrakenteet ja ohjelmalohkot
while (lauseke)
{
lause1;
     lause2;
¨¨
lausen;
}
Toisto/ Alkuehtoinen toisto (while)
Niin kauan, kun ehtolausekkeen lauseke arvoon tosi (0), niin toistetaan lauseet lause1,lause2, … lausen.
Alkuehtoinen toisto on hyvä silloin, kunlauseita ei välttämättä haluta suorittaakertaakaan.
Syntaksi
Semantiikka
Huom! Jälkimmäisenlohkomerkin jälkeen ei tulepuolipistettä
1. Ohjausrakenteet ja ohjelmalohkot
do
{
lause1;
     lause2;
¨¨
lausen;
while (lauseke);
Toisto/ Loppuehtoinen toisto (do … while)
Niin kauan, kun ehtolausekkeen lauseke arvoon tosi (0), niin toistetaan lauseet lause1,lause2, … lausen.
Loppuehtoinen toisto on hyvä silloin, kunlauseet halutaan välttämättä suorittaa ainakinkerran.
Syntaksi
Semantiikka
1. Ohjausrakenteet ja ohjelmalohkot
for(laskurinalustus;lauseke;laskurinkasvatus)
{
lause1;
lause2;
¨¨
lausen;
}
Toisto/ lukumääräinen toisto (for)
Alustetaan laskuri. Niin kauan,kun ehtolausekkeen lausekearvo on tosi (0), toistetaanlauseet lause1lause2, …lausen sekä kasvatetaanlaskuria tässä järjestyksessä.
Lukumääräinen toisto on hyväsilloin, kun tiedetään kuinkamonta kertaa lauseet halutaansuorittaa esimerkiksi käytäessätaulukkorakennetta läpi.
Syntaksi
Semantiikka
1. Ohjausrakenteet ja ohjelmalohkot
Toisto
Kaikkia toistolauseita voidaankäyttää saman tehtävänratkaisuna. Käytäntö kuitenkinopettaa mikä kolmestaohjausrakenteesta milloinkin onluontevin.
Esimerkki
Semantiikka
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ä seuraavatkolme asiaa ovat kunnossa;
1)Laskurin alustus    i=1
2)Toistoehto         i<=10
3)Laskurin kasvatus    i=i+1
1. Ohjausrakenteet ja ohjelmalohkot
Toisto
Tulostetaan ohjeet
Esimerkki Käyttöliittymä
Semantiikka
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 jaluetaan käyttäjän valinta
Käyttäjän valinnan mukaansuoritetaan syöttö, tulostus tailopetus
default-osassa tulostetaanohjeet tapauksessa, jossakäyttäjä ei ole ymmärtänytkirjoittaa oikeaa kirjainta
1. Ohjausrakenteet ja ohjelmalohkot
Harjoitus 1: Laadi ohjelma, joka laskee yhteen ja tulostaa 100ensimmäisen kokonaisluvun summan.
Harjoitus 2: Laadi ohjelma, joka tulostaa sanan pieni kirjain, suurikirjain tai muu merkki riippuen siitä minkä merkin käyttäjä onsyöttänyt. Käyttäjä voi jatkaa kirjainten syöttämistä ja ohjelmalopetetaan vasta, kun käyttäjä syöttää numeron.
Ohje: merkkimuuttuja (char) on myös kokonaislukumuuttuja, jakullakin merkillä on numeerinen ASCII-arvo. Esimerkiksi kirjaintenA … Y ASCII-arvot ovat kokonaislukujen 65 ja 89 välissä, kirjaimeta … y  ovat lukujen 97 ja 121 välissä sekä numeroiden 0 … 9ASCII-arvot ovat lukujen 48 ja 57 välissä (skandit voidaan tulkitamuiksi merkeiksi).
Toisto
1. Ohjausrakenteet ja ohjelmalohkot
Toisto
Harjoituksen 2pseudokoodi
toistetaan
     tulosta käyttäjälle syöttöohje
     nollataan syöttöpuskuri (fflush(stdin);)
     luetaan käyttäjältä merkki
     jos merkki on kokonaislukujen 65 ja 89 välissä
tulostetaan iso kirjain
     muutoin, jos merkki on kokonaislukujen 97 ja 121 välissä
tulostetaan pieni kirjain
     muutoin
tulostetaan muu merkki
niin kauan, kun merkki ei ole koko kokonaislukujen 48 ja 57 välissä
2. Funktiot
tyyppi tunniste parametritopt)
{
    määrittelyt
    lauseet
}
Paluuarvon tyyppi
Syntaksi
Semantiikka
Funktion nimi
Parametrien lista (voi olla tyhjä)
Paikallisten muuttujien määrittely
Funktion toiminnan määrittelevätlauseet
Otsikko ja määrittely
Funktion ensimmäistä riviä kutsutaan funktion otsikoksi
2. Funktiot
int omafunktio (parametritopt)
{
    int luku;
    …
    luku = …
    …
    return luku;
}
Kaikille paluuarvon tietotyypeillefunktion pitää palauttaa return-lauseella vastaava tietotyyppi.
Jos funktio ei palauta mitäänarvoa (esimerkiksi monettulostusfunktiot), kirjoitetaanpaluuarvoksi void, jolloin return–lausetta ei tarvita
Ehdollisissa kontrollirakenteissavoi olla useitakin return-lauseita
Syntaksi
Semantiikka
Paluuarvo ja return -lause
2. Funktiot
float laskeka (float luku1float luku2)
{
    float keskiarvo;
    keskiarvo(luku1+luku2)/2;
 
    return keskiarvo;
}
Funktion muodolliset parametritvälittävät tietoa funktiollekutsuvasta ohjelman osasta.
Muodolliset parametrit esitelläänsulkeiden sisällä samallaperiaatteella kuin paikallisetmuuttujatkin
          tyyppi tunniste
Parametreja käytetään runko-osassa kuten muitakin muuttujia.Niiden sisältämä arvo määräytyykutsuvan ohjelman osan mukaan.
Syntaksi
Semantiikka
Parametrien ja paikallisten muuttujien  määrittely
2. Funktiot
float laskeka (float luku1, float luku2);
int main( )
{
    float eka=5.1;toka=4.2;
    float ka;
    ka laskeka(eka, toka);
    
}
C-kielessä kaikki kutsuttavat funktiot onesiteltävä koodissa ennen sitäohjelmalohkoa, jossa kutsu esiintyy.Funktioiden esittelyt tehdään yleensäennen main() funktiota ja niidenmäärittelyt sen jälkeen. Esittelyyn riittääkirjoittaa funktion otsikko.
Funktion kutsuparametrien nimen eitarvitse olla sama kuin funktionotsikossa olevien muodollistenparametrien.
Funktion paluuarvo sijoitetaan sitävastaavan tietotyypin muuttujan arvoksi.
Syntaksi
Semantiikka
Funktion esittely ja kutsuminen
2. Funktiot
esikääntäjäkutsut
globaalienMuuttujienMäärittely
funktioidenEsittely
int main( )
{
    paikallistenMuuttujienMäärittely
    ohjelmanLauseet
}
funktioidenMäärittelyt
Esikääntäjäkutsut kirjoitetaan kaikki eririveille, mutta puolipistettä ei käytetä.esimerkiksi   #include <stdio.h>
Globaalit muuttujat näkyvät kaikissa allamääritellyissä funktioissa. Paikallisetmuuttujat näkyvät vain siinäohjelmalohkossa, missä ne ovatmääritelty.
Syntaksi
Semantiikka
C-ohjelman käännösyksikön yleinen rakenne,paikalliset ja globaalit muuttujat
2. Funktiot
tyyppi funktio1(parametritOpt )
{
    paikallistenMuuttujienMäärittely
    funktionToiminta
}
tyyppi funktio2(parametritOpt )
{
    paikallistenMuuttujienMäärittely
    funktionToiminta
    …funktio1(kutsuparametrit)
}
C-kielessä jokainen funktion määrittelymuodostaa oman itsenäisenohjelmalohkonsa, sisäkkäisiämäärittelyjä ei sallita.
Funktiot voivat kutsua toisia funktioita,jos kutsuttava funktio on vähintäänesitelty (tai myös määritelty) koodissaennen sitä ohjelmalohkoa, jossa kutsuesiintyy.
Syntaksi
Semantiikka
Funktioiden määrittelyt ja toisen funktion kutsuminen
2. Funktiot
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 moniinohjelmointiongelmiin.
Rekursion käyttöön liittyy  aina myösongelmia, koska se kuluttaa paljonohjelman vaatimaa muistitilaa. Lisäksi,jos käytetään useita rekursiivisiakutsuja, voi myös ohjelmansuoritukseen kuluva aika kasvaakohtuuttomasti.
Syntaksi
Semantiikka
Rekursiivinen funktio
2. Funktiot
Funktio kertoma() palauttaa syötetynluvun kertoman (!) eli
kertoma(0)=0!=1
kertoma(1)=1!=1
kertoma(2)=2!=2*1!=2
kertoma(3)=3!=3*2!=6 jne…
Esimerkki
Semantiikka
Rekursion määrittely
int kertoma(int luku)
{
  if ( luku == 0 || luku == 1)
      return 1;
  else
     return luku*kertoma(luku-1);
 }
Kuten toistolauseissakin tulee myösrekursiossa olla jokin ehto, jonkatoteutuminen päättää rekursiivisetkutsut.
Huom! Rekursio voidaan aina (jos osataan) korvata toistolauseilla (esim. for).