Siirry sisältöön

C/Ohjausrakenteet

Wikikirjastosta
< C

Tämä luku kertoo C:n ohjausrakenteista.

Koodilohkoa merkitään aaltosulkeilla. Ne voivat sisältää mitä tahansa lauseita.

Lohkon voi halutessaan sijoittaa ilman muunlaista ohjausrakennetta. Tällöin niillä on vaikutus vain muuttujien näkyvyysalueeseen:

/* jotain koodia */
int muuttuja = 1;
{
    int muuttuja = 2;
    int toinen_muuttuja = 3;
}
/* nyt muuttuja = 1, ja toinen_muuttuja on lakannut olemasta. */

Tällainen rakenne on kuitenkin hieman sekava, joten niitä tulee välttää ilman erityisen pätevää syytä. (Esim. ennen C99-standardia muuttujia pystyi määrittelemään vain lohkon alussa, joka saattoi joissain tapauksissa olla pätevä syy.)

If-ehtorakenne

[muokkaa | muokkaa wikitekstiä]

If-ehtolauseessa määritellään ehto, ja koodi suoritetaan vain, jos ehto on tosi (eli sen arvo ei ole 0, tai osoittimilla NULL).

if (pituus > 300)
{
    puts("Liian pitkä - enimmäispituus on kolme metriä");
}

Lisää ehtoja voi määritellä else if:n avulla. Tällöin koodi suoritetaan (ja ehto tarkistetaan) vain, jos edelliset ehdot eivät olleet tosia. Viimeinen lause voi olla vain else, jolloin se suoritetaan vain, jos mikään aiemmista ehdoista ei ollut tosi.

if ((luku % 2) == 0)
{
    puts("Luku on parillinen");
}
else if ((luku % 3) == 0)
{
    puts("Luku on kolmella jaollinen");
}
else
{
    puts("Luku on pariton eikä kolmella jaollinen");
}
luku Tuloste
1 Luku on pariton eikä kolmella jaollinen
2 Luku on parillinen
3 Luku on kolmella jaollinen
4 Luku on parillinen
5 Luku on pariton eikä kolmella jaollinen
6 Luku on parillinen
7 Luku on pariton eikä kolmella jaollinen

Ehtojen yhdistelemisestä ks. C/Operaattorit § Loogiset operaatiot.

Toistolauseet

[muokkaa | muokkaa wikitekstiä]

Toistolauseilla voi toistaa ohjelmasta tiettyjä vaiheita.

While-toistorakenne

[muokkaa | muokkaa wikitekstiä]

While-toistorakenteessa määritellään vain ehto, jolloin toistetaan. Tämä ohjelma tulostaa samalle riville 10 kertaa tekstin "Hello World!".

/* Tarvittava muuttuja toistorakennetta varten */
int x = 0;

/* Toista niin kauan kunnes x ei ole pienempi kuin kymmenen. */
while (x < 10)
{
    puts("Hei maailma!");
    /* Lisää yhdellä muuttujaa x */
    ++x;
}

While-rakenteesta on olemassa myös toinen versio, do...while. Sen ainoa ero tavalliseen while-rakenteeseen on, että silmukka toistuu vähintään kerran. Do...while-rakennetta käytetään usein syötöntarkistuksessa, koska sen avulla voidaan helposti varmistaa että käyttäjä syöttää esimerkiksi jonkin tietyn arvon. Esimerkki rakenteesta:

int x = 1;
do {
    printf("Teksti tulostuu kerran.");
} while (x == 0);

For-toistorakenne

[muokkaa | muokkaa wikitekstiä]

For-silmukka on hieman monimutkaisempi kuin while-rakenne, mutta on toiminnaltaan melkein vastaava.

for (alustus; ehto; päivitys)
{
    /* ... */
}

Silmukka koostuu kolmesta lausekkeesta. Ensimmäinen on alustuslauseke, jossa yleensä alustetaan silmukassa käytettävä laskuri. Toinen lauseke on ehtolauseke, jonka perusteella silmukkaa joko jatketaan tai se pysäytetään. Kolmas lauseke on ns. päivityslauseke, joka suoritetaan aina silmukan jälkeen. Sitä käytetään yleensä laskurin arvon nostamiseen tai laskemiseen. Seuraava esimerkki tulostaa kaikki luvut nollan ja kymmenen välillä.

int i;
for (i = 0; i <= 10; ++i)
{
    printf("numero %d\n", i);
}

for (alustus; ehto; päivitys) vastaa suunnilleen seuraavaa koodia while-rakenteella:

alustus;
while (ehto) {
    /* koodilohko */
    päivitys;
}

Toiston katkaiseminen tai jatkaminen

[muokkaa | muokkaa wikitekstiä]

Toistolause jatkuu tavallisesti koodilohkon loppuun, ja suorittaa sitä niin pitkään kun ehto pitää paikkaansa. Kielessä on kaksi erityistä avainsanaa, joilla voidaan toimia toisin. break katkaisee (sisimmän) toistorakenteen heti:

int i;
for (i = 0; i <= 100; ++i)
{
    if (i > 10)
    {
        /* mentiin liian pitkälle */
        break; /* toisto päättyy */
    }
    printf("numero %d\n", i);
}

continue hyppää suoraan sisimmän toistorakenteen koodilohkon loppuun. Toisto jatkuu, jos ehto pitää yhä paikkaansa.

switch on valintarakenne, joka valitsee arvon perusteella automaattisesti valittavan osan koodia. Sille annetaan kyseinen arvo, ja lohkoon sijoitetaan case-lauseita, joihin suoritus hyppää tietyillä arvoilla.

Samaan kohtaan koodia voi sijoittaa monta case-lausetta. default-ehto suoritetaan, jos mikään case:ista ei täsmännyt arvoon. (Jos se puuttuu, mitään ei silloin tapahdu.)

switch (arvosana) {
    case 0:
        puts("hylätty");
        break; /* huomaa break; ilman breakia koodin suoritus jatkuu seuraavaan caseen. (tästäkin on ajoin hyötyä) */
    case 1:
        puts("välttävä");
        break;
    case 2:
        puts("tyydyttävä");
        break;
    case 3:
        puts("hyvä");
        break;
    case 4:
        puts("kiitettävä");
        break;
    case 5:
        puts("erinomainen");
        break;
    default:
        puts("tuntematon arvosana");
        break;
}

goto-lauseella voi hypätä saman funktion sisällä toiseen nimiöön (engl. label), joita lisätään kirjoittamalla nimi ja sen perään kaksoispiste. Nimiö ei vaikuta koodin normaaliin sarjasuoritukseen.

goto-lauseiden käyttöä tulee yleensä välttää, jos sama voidaan ilmaista muilla ohjausrakenteilla, koska ne tekevät koodista merkittävästi hankalampaa lukea. Jotkin tyylioppaat kieltävät sen käytön kokonaan. Joissain tapauksissa niistä on kuitenkin hyötyä:

  FILE *tiedosto = fopen(tiedoston_nimi, "rb");
  if (!tiedosto)
  {
      /* tulosta virhe */
      perror("tiedostovirhe");
      return; /* tiedostoa ei tarvitse sulkea vielä, eihän sitä ole saatu edes auki */
  }
  if (fread(puskuri, sizeof(int), 8, tiedosto) < 8)
  {
      /* tulosta virhe */
      perror("tiedostovirhe");
      goto sulje_tiedosto; /* ei palata vielä returnilla, tiedosto pitää sulkea */
  }
  /*
  ...
  */
sulje_tiedosto:
  fclose(tiedosto); /* sulje tiedosto */
  /* ... */

Lisäksi goto:a voi käyttää usean toistosilmukan katkaisemiseen kerralla.

Huomaathan, ettei nimiötä voi sellaisenaan laittaa aivan lohkon loppuun, eli ennen oikeaa aaltosuljetta. Ratkaisu tähän on kirjoittaa puolipiste nimiön jälkeen, jotta saadaan tyhjä lause (nimiön on osoitettava aina lauseeseen).

C-ohjelmointikieli

EtusivuHistoriaTyökalut


Yksinkertainen C-kielinen ohjelmaMuuttujatOperaattoritKommentitOhjausrakenteetFunktiotOsoittimetDynaaminen muistinvarausTaulukotMerkkijonotTietueetEsikääntäjäOtsikkotiedostot


C-kielen varatut sanatStandardikirjastoAiheesta muualla