Kirjautuminen

Haku

Tehtävät

Opasarkisto: Pascal-ohjelmointi: Osa 3 - Silmukat ja ehtolauseet

  1. Osa 1 - Mistä Pascal alkaa?
  2. Osa 2 - Vakiot, muuttujat ja tietueet
  3. Osa 3 - Silmukat ja ehtolauseet
  4. Osa 4 - Tiedostot
  5. Osa 5 - Funktiot, aliohjelmat ja omat moduulit

Kirjoittaja: Metabolix (2004).

⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠


Pascal sisältää neljä eri ehtolausetta, joista kaksi on silmukoita. Minkä tahansa näitä neljää käyttävän koodin saa muutettua muotoon, joka käyttää vain kahta, mutta tämä pidentää koodia. Lisäksi kieleen kuuluu For-silmukka.

Erilaisia ehtoja

Ehtoja ei ole kuin muutama:

Merkki / sanaMerkitys
>Suurempi kuin
<Pienempi kuin
=Yhtä suuri kuin
>=Suurempi tai yhtä suuri kuin
<=Pienempi tai yhtä suuri kuin
<>Erisuuri kuin
inKuuluu tiettyyn ryhmään. (if (A in [10, 20, 30, 45, 60]))

if .. then

Yksinkertaisin ehtolause on muotoa if (ehto) then (koodi). Se toimii yksinkertaisesti niin, että mikäli ehto on tosi, suoritetaan koodi. Mikäli halutaan suorittaa jokin muu koodi mikäli ehto ei ole tosi, lause muuttuu muotoon if (ehto) then (koodi) else (koodi jos ehto on epätosi). Huomaa, että ennen sanaa else ei laiteta puolipistettä.

Jos lauseessa on vain yksi ehto, se voidaan jättää ilman sulkuja. Muuten kukin ehto tulee laittaa sulkuihin. Useita ehtoja voi ja täytyy sitoa sanoilla and, or ja xor. Sanan and molempien, sanan or toisen tai molempien ja sanan xor vain yhden puolen tulee olla tosi. not tarkoittaa että ehto ei saa olla tosi. Muutama esimerkki:

function OutoEhto(X, Y: Integer): Boolean;
begin
  if (((X = 2) and (Y = 10)) xor (X + Y < 5)) or ((X = 0) xor not (Y = X)) then
    OutoEhto := True
  else
    OutoEhto := False;
end;

function AinaEpatosi(X, Y: Integer): Boolean;
begin
  if (X < Y) and (X > Y) then
    AinaEpatosi := True { X on isompi ja pienempi kuin y ?!?}
  else
    AinaEpatosi := False; { AinaEpatosi on siis aina epätosi. }
end;

case .. of

Case ei ole suoranaisesti ehtolause; se vain katsoo onko X jokin annetuista vaihtoehdoista. String-tyyppisiä muuttujia tällä ei voi tarkastella. Muuttujia ei voi käyttää vaihtoehtoina; jokaisen vaihtoehdon on oltava vakio, koska muuten vaihtoehdoissa voisi olla kaksi samaa. Vaikka tämä alkaa kuulostaa siltä, että case .. of on aika turha lause, se on silti hyvin hyödyllinen.

Jos vaihtoehtoja on useita, vaikkapa jos X voi olla mikä tahansa luku väliltä 1 - 100 ja jokaisessa tilanteessa täytyy toimia eri lailla, on hyvin epäkäytännöllistä käyttää sataa peräkkäistä if .. then .. else -lausetta.

Myös case .. of -lauseeseen voidaan lisätä vaihtoehto else, johon siirrytään, mikäli mikään muu vaihtoehto ei ollut oikea. case .. of -lause päättyy sanaanend.
case .. of
-lause voisi näyttää vaikkapa tältä:

procedure CaseEsimerkki(X: Integer);
begin
  case X of
    0: Writeln('Antamasi luku on nolla.');
    1: Writeln('Antamasi luku on yksi.');
    1 + 1: Writeln('Antamasi luku on 2.');
    3 .. 5:
    begin
      Writeln('Antamasi luku on väliltä 3 - 5.');
      if X = 4 then Writeln('Tarkemmin sanoen se on 4.');
    end;
    6, 8, 10 .. 12: Writeln('Antamasi luku on 6, 8 tai jokin väliltä 10 - 12.');
    100 .. 2147483647: WriteLn('Häh!?! Eihän tuollaista lukua olekaan!');
    else
    begin
      Writeln('Se on jotakin muuta.');
    end;
  end; { end of case }
end;

while .. do

Tavallinen silmukka on muotoa while (ehto) do (koodi). Tällöin koodia toistetaan niin kauan, kuin ehto on tosi. Mikä tahansa ehto, joka käy if .. then -lauseeseen, käy myös tähän.

Jos koodi jätetään tyhjäksi eli sanan do jälkeen laitetaan puolipiste, ehtoa tarkistetaan jatkuvasti. Tätä hyödynnetään usein esimerkiksi silloin, kun ehtona on funktio, joka palauttaa Boolean-arvon: silmukka loppuu ensimmäiseen False-palautusarvoon.

program WhileEsimerkki_TikTak;
uses
  SysUtils, Windows;

var
  Maara: Integer;
  Seuraava, Loppu: LongWord;

const
  Naks_Per_Sekunti = 2;

begin
  { GetTickCount palauttaa Windowsin käynnistymisestä kuluneen ajan millisekunteina. }
  { Seuraava naksahdus tulkoon heti paikalla }
  Seuraava := GetTickCount - 1;

  { Loppu minuutin kuluttua }
  Loppu := GetTickCount + 1000 * 60;

  Maara := 0;

  while (GetTickCount < Loppu) do
  begin
    { Jos GetTickCount palauttaa arvon, joka on suurempi kuin Seuraava }
    if (GetTickCount > Seuraava) then
    begin
      { Lasketaan seuraavan naksahduksen ajankohta }
      Seuraava := GetTickCount + (1000 div Naks_Per_Sekunti);

      { Korotetaan määrää }
      Inc(Maara);

      { Vuorotellen Tik ja Tak, eli hyödynnetään jakojäännöstä }
      if (Maara mod 2 = 0) then
        WriteLn(' ... Tak')
      else
        WriteLn(' ... Tik');
    end;
  end;
end.

repeat .. until

repeat (koodi) until (ehto) eroaa vähän mutta merkittävästi while .. do -lauseesta: Koodi suoritetaan joka tapauksessa kerran, koska tarkistus suoritetaan vasta lopuksi. Lisäksi koodia toistetaan kunnes ehto on tosi. Ennen sanaa until ei tule puolipistettä. Mikä tahansa ehto, joka käy if .. then -lauseeseen, käy myös tähän. Jos ehto jätetään tyhjäksi eli sanan until jälkeen laitetaan puolipiste, koodia toistetaan loputtomasti.

program RepeatEsimerkki;
{ Paljon muuta tavaraa ja määritelmiä }
begin
  repeat begin
    PoimiKranaatti;
    VedaSokka;
    HeitaKranaatti;
  end until (Kranaattilaatikko.Kranaatteja = 0)
      or (Vihollinen.HeitettyKranaatti.Lentosuunta = Mina.Sijainti);
end.

for .. to / downto .. do

for (JokuInteger := MinArvo) to (MaxArvo) do (koodi) suorittaa koodin JokuIntegerin kaikilla arvoilla MinArvosta MaxArvoon korottaen sitä joka kerta yhdellä. Vastaavasti for (JokuInteger := MaxArvo) downto (MinArvo) do (koodi) suorittaa koodin JokuIntegerin kaikilla arvoilla MaxArvosta MinArvoon pienentäen sitä joka kerta yhdellä.

program ForEsimerkki;
var
  A: Integer;
begin
  for A := 1 to 10 do
  begin
    WriteLn(A, '   Paina "Enter" kun olet valmis jatkamaan.');
    ReadLn;
  end;
  WriteLn('Hienoa! ja sitten alaspäin!');
  for A := 10 downto 1 do
  begin
    WriteLn(A, '   Paina "Enter" kun olet valmis jatkamaan.');
    ReadLn;
  end;
  Writeln('Hienoa! Huomenna siirrymme aakkosiin!');
  ReadLn;
end.

Break ja Continue

Break murtaa silmukan eli lopettaa sen suorittamisen ja hyppää ulos siitä. Continue taas palaa silmukan alkuun suorittamatta loppua.

Lauri Kenttä, 26.8.2004


Kommentit

Lazu [19.04.2005 08:55:22]

#

Onkos tuossa if esimerkissä virhe?

function OutoEhto(X, Y: Integer): Boolean;
begin
  if (((X = 2) and (Y = 10)) xor (X + Y < 5)) or ((X = 0) xor not (Y = X)) then
    OutoEhto := True;
  else
    OutoEhto := False;
end;

function AinaEpatosi(X, Y: Integer): Boolean;
begin
  if (X < Y) and (X > Y) then
    OutoEhto := True; { X on isompi ja pienempi kuin y ?!?}
  else
    OutoEhto := False;
end;

Metabolix [19.04.2005 17:21:05]

#

No niinpä onkin. Oikein neljä kappaletta. Korjasin. Kumma, ettei kukaan ole aiemmin huomannut huomauttaa.

NanoSoft [21.04.2006 15:33:54]

#

mikset kertonut nested if:stä?

  If true then
    If false then
      ShowMessage('Inner then satisfied')
    else
      ShowMessage('Inner else satisfied')
  else
    ShowMessage('Outer else satisfied');

Metabolix [22.04.2006 11:05:30]

#

No eikö se ole aika ilmeistä? Tietenkin niitä voi laittaa sisäkkäin, tyhmäähän se olisi, jos voisi olla vain yksi if-lause. Ei sisäkkäisyyksissä ole mitään ihmeellistä, suoritusjärjestys menee aivan normaalien sääntöjen mukaan. Olen käsittääkseni neuvonut if-lauseen ja begin-end-parin, niin miksei koodiblokin sisällä voisi olla toista vastaavaa? Näyttäisi niitä sitä paitsi tuolla while-esimerkissä ja muissakin olevan esimerkkiä tästä.

Suosittelisin kuitenkin laittamaan noissa aina thenin jälkeen beginin, ettei tule epäselvyyksiä siitä, mikä on kenenkin else:

if A then
  if B then
    if C then
      {...}
  else {...} { Ja kenelle nämä kuuluvat? }
else {...} { A&B, B&C vai peräti A&C? Ei kannata arvailla. }
if A then begin
  if B then begin
    if C then begin
      {...}
    end
    else begin
      { C:n else }
    end
  end
  { Ei elseä B:lle }
end
else begin
  { A:n else }
end

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta