Programski jezik C

Krmilni stavki

S pomočjo krmilnih stavkov oblikujemo potek programa. Krmilni stavki nam omogočajo, da se bloki izvedejo ali ne oziroma da se ponavljajo.

Za odločitev, ali blok izvesti ali ne oziroma kolikrat ga ponoviti, potrebujemo pogoje.

Pogoji

Pogoj je izraz, ki je bodisi resničen bodisi neresničen. Ker je jezik C enostaven jezik, je izraz prav vsaka konstanta in prav vsaka spremenljivka, a nam jezik tudi omogoča, da iz izrazov s pomočjo veznikov sestavimo nove izraze. Na kratko, izraz je neresničen, če ima vrednost 0, sicer je resničen. Torej, če imamo spremenljivko a tipa int, je njej pripadajoč izraz (a) neresničen, če ima a vrednost 0, in resničen, če a nima vrednosti 0.

Največkrat za izraze uporabljamo spremenljivke tipa int.

Primerjalni vezniki

Poglejmo si nekaj primerov sestavljenih pogojev, kjer sta a in b izraza.

(a == b)	/* pogoj velja, ko je a (po vrednosti oziroma vsebini) enak b */
(a != b)	/* pogoj velja, ko a ni enak b */

Če sta a in b takšnega tipa, da obstaja operacija primerjanja <, potem lahko tvorimo tudi naslednje izraze.

(a < b) 	/* pogoj velja, ko je a (strogo) manjši od b  */
(a <= b)	/* pogoj velja, ko je a manjši ali enak b */
(a > b) 	/* pogoj velja, ko je a (strogo) večji od b */
(a >= b)	/* pogoj velja, ko je a večji ali enak b */

Če en izraz predstavlja predznačeno, drug izraz pa nepredznačeno spremenljivko, lahko pride do težav!

Veznik NE

Veznik ni najbolj posrečena beseda, saj veznik ne (not) z znakom ! ničesar ne povezuje, temveč le spremninja (zamenja) pravilnost pogoja. Če je pogoj a resničen, je pogoj !a neresničen in velja tudi obratno.

Veznika IN in ALI

Več pogojev lahko združimo s pomočjo veznika in z znakom && in veznika ali z znakom ||.

((a > 4) && (a < 8))	/* Izraz je resničen, če je a večji od 4 in manjši od 8. */
((b < 2) || (b > 6))	/* Izraz je resničen, če je b manjši od 2 ali večji id 6 */

Krmilni stavek: if

Krmilni stavek if s pogojem odloča, ali se bo naslednji stavek oziroma naslednji blok izvedel ali ne. Oglejmo si to na primeru.

if (jabolka > 4)
  cena = 5;

Ta primer pove: „Če je vrednost spremenljivke jabolka strogo večja od 4, potem priredi spremenljivki cena vrednost 5. Blok uporabimo, kadar želimo imeti nadzor nad več kot enim stavkom, kot kaže naslednji primer.

if (jabolka > 4) {
  cena = 5;
  valuta = 'E';
}

Stavek if nastopa lahko tudi v podaljšani izvedbi, kjer dodamo else. Ta se zgodi, kadar pogoj pri if ni resničen.

if (jabolka > 4)
  cena = 5;
else
  cena = 2;

Če spremenljivka jabolka ne bo strogo večja od 4, potem nastavi vrednost spremenljivke cena na 2.

Več if-stavkov lahko uporabimo drug za drugim.

if (a) {
  ...
}
else if (b) {
  ...
}
else {
  ...
}

Krmilni stavek: switch

Ker se kdaj odločamo glede na vrednost spremenljivke in je toliko možnosti, da je nesmiselno uporabiti if-stavek, nam pomaga krmilni stavek switch, ki za enak učinek zahteva manj pisanja.

switch (jabolka) {

  case 1: cena += 5;
          break;

  case 2: cena -= 5;
          break;

  case 3: cena = 5;
          break;

  case 4: cena = 9;
          break;

  default: cena = 0;

}

Poleg stavka switch, se v zgornji kodi pojavijo tri nove besede: Z besedo case podamo možnosti oziroma vrednosti, katere lahko zavzame spremenljivka. Ob ujemanju se sprožijo stavki, ki ji sledijo, dokler ti ne dosežejo stavka break, ki prekine izvajanje stavkov in celoten stavek switch se zaključi. Poseben primer možnosti predstavlja beseda default, ki predstavlja vse ostale izide vrednosti spremenljivke, torej če ne obstaja primeren case.

Zgornji primer nam zato pove sledeče. Če je spremenljivka jabolka enaka 1, potem povečaj spremenljivko cena za 5. Če je spremenljivka jabolka enaka 2, potem zmanjšaj spremenljivko cena za 5 in tako naprej. Če spremenljivka ni enaka 1 ne 2 ne 3 in ne 4, potem postavi spremenljivko cena na 0.

Stavkom, ki se začno za besedo case, ni potrebno dodati zavitih oklepajev, četudi jih je več, da bi označili blok.

Naslednji primer prikazuje primer odsotnosti stavka break v primeru case 3:. Če bo vrednost spremenljivke enaka 3, potem se bodo izvedli stavki, ki sledijo case 4:, saj izvajanja nismo prekinili.

switch (jabolka) {
  case 1: cena += 5;
          break;
  case 3:
  case 4: cena = 9;
          break;
  default: cena = 0;
}

V nadaljevanju si poglejmo še zanke, ki so uporabne, ko je potrebno enako ali podobno kodo večkrat izvršiti.

Zanka: while

Stavek while se uporablja, ko želimo, da se del programa ponavlja dokler je izpolnjen pogoj. Oglejmo si primer, v kateremu se bo blok ponavljal, dokler bo spremenljivka i strogo manjša od vrednosti 10. Blok v naslednjem primeru sestavlja stavek i++;.

int i = 0;
while (i < 10) {
  i++;
}

Če hočemo zanko (blok) zapustiti predčasno lahko uporabimo stavek break. Če želimo ponovno preveriti pogoj in znova začeti vsebino zanko, uporabimo stavek continue.

int i = 10;
while (i > 0) {
  i--;	/* Štejemo navzdol. */
  if (i % 5 == 1)
    break;
}
/* Sedaj je vrednost i enaka 6. */

Če pred zanko nekaj naredimo (na primer nastavimo števec), je pogoj enostaven, in ob ponovitvi zanke zopet nekaj naredimo (na primer spremenimo števec), potem je smiselno razmisliti o zanki naslednjega tipa.

Števec je številska spremenljivka, ki nekaj šteje. V zgornjem primeru ima vlogo števca spremenljivka i.

Zanka: for

Poglejmo si primer, kjer se koda znotraj zavitih oklepajev izvede desetkrat.

int i;
for (i = 0; i < 10; i++) {
  ...
}

Stavek for sprejme tri parametre, ločene s podpičjem ;. Stavki v prvem parametru se izvedejo pred začetkom zanke. Drugi parameter predstavlja pogoj, če se bo zanka izvedla, in stavki v tretjem parametru se izvedejo po vsakem koraku zanke.

V zgornjem primeru se bo najprej i nastavil na 0 in nato preveril pogoj i < 10. Ker je ta resničen, se bo izvedel blok, ki sledi for-stavku. Ko se ta blok izvede, se izvede še i++, kar poveča i na 1, in tako znova in znova. Po zadnjem izvajanju bloka, se i poveča na 10, ker bo tedaj pogoj neresničen, se zanka konča.

Ker je pogoj neresničen, ko ima vrednost 0, je bolje šteti navzdol.

Splošna oblika for-zanke je enaka for(pred_prvim_korakom; pogoj_za_ponovitev; po_koraku).

Zanka: do-while

Ta vrsta zanke je zelo podobna while-zanki, pri čemer se zanka ponovi vsaj enkrat, saj se pogoj preverja na koncu, medtem ko se while-zanka lahko ne izvrši niti enkrat.

int i = 0;
do {
  i--;
} while (i > 0);

/* Spremenljivka i ima vrednost -1. */

i = 0;
while (i > 0) {
  i--;
}
/* Spr. i ima vrednost 0. */