Instrukcje sterujące

Adam Boduch

Dzisiaj będzie mowa (częściowo) o instrukcjach sterujących w C++.

Instrukcje są bardzo przydatnymi poleceniami służącymi do sterowania przebiegiem programu (stąd ich nazwa: instrukcje sterujące). Za pomocą instrukcji sterujących podejmowane są decyzje o wykonaniu tych czy innych instrukcji programu. Decyzje te podejmowane są na podstawie pewnych warunków - prawdziwości lub fałszywości pewnego wyrażenia:

Wartość zero – fałsz

Wartość inna niż zero – prawda

Po tym wstępie zajmiemy się pierwszą instrukcją sterującą – instrukcją warunkową if, która może mieć następujące formy:

if(wyrażenie) instrukcja1;

lub

if(wyrażenie) instrukcja1;

else

instrukcja2;

Wyrażenie jest to coś, co ma jakąś wartość. Może to być wyrażenie, które najpierw trzeba obliczyć, by poznać jego wartość i na przykład użyć w dalszej części programu; może to być również obiekt do przechowywania określonej zmiennej logicznej.

W pierwszej wersji instrukcji if obliczana może być wartość wyrażenia, jeśli jest ona niezerowa (prawda), to instrukcja jest wykonywana. W przeciwnym razie (wartość wyrażenia jest równa 0 – fałsz), instrukcja nie zostanie wykonana.

W drugim przypadku przypadku widzimy dodatkowe słowo else, które można przetłumaczyć jako: „w przeciwnym razie”. A zatem jeśli w tym drugim przypadku wartość wyrażenia jest niezerowa, to zostanie wykonana instrukcja pierwsza w przeciwnym razie (nasze słowo else), gdy wartość wyrażenia jest zerowa, to zostanie wykonana instrukcja druga.

*Wynik wyrażenie może być wynikiem różnego typu (np. całkowity). Sprawdza się tylko czy jest równy 0 czy nie.

Zanim przejdziemy do przykładu należy wspomnieć jeszcze o tzw. bloku instrukcji.

Z blokiem instrukcji mamy do czynienia w przypadku, kiedy chcemy wykonać kilka instrukcji. Należy wówczas stosować instrukcję składaną zwaną inaczej blokiem. Jest to zbiór instrukcji ograniczonych nawiasami „{}”.

{

 instrukcja1; 

 instrukcja2; 

 instrukcja3; 

 instrukcja4; 

}

*Po klamrach nie trzeba stawiać średników.

A oto przykładowy program:

#include &ltiostream.h&gt

main()

{

int wiek;

  cout<<&#8221;Podaj swój wiek:&#8221;; 

  cin>>wiek; 

  if(wiek<18) 

  { 

     cout<<&#8221;\\n&#8221;<<&#8221;Pamiętaj, że nie wolno ci kupować papierosów!&#8221;; 

  } 

  else 

  { 

     cout<<&#8221;\\n&#8221;<<&#8221;Jesteś już dorosły&#8221;; 

  } 

} 

*Różna wielkość odstępów od lewego marginesu nie ma dla kompilatora żadnego znaczenia. Pomagają one programiście – chodzi o tzw. estetykę programu.

Omówienie:

Program pyta o wiek. Jeżeli wiek (wartość wyrażenia) jest mniejsza od 18, to wyświetlany jest następujący tekst: „Pamiętaj, że nie wolno ci kupować piwa!”, w przeciwnym razie (else-wiek jest większy lub równy 18) wyświetlany jest tekst: „Jesteś już dorosły”.

*W pole tekstowe (zawarte pomiędzy znakami „”) możesz wpisać dowolny tekst, ne będzie miało to wpływu na końcowy wynik wykonania programu.

Przy omawianiu instrukcji warunkowej if, należy wspomnieć o tzw. wyborze wielowariantowym. W powyższym przykładzie mieliśmy możliwość dwuwariantowego wyboru (przy użyciu else).

Wybór wielowariantowy polega na tym, że koło słowa else można postawić następne instrukcje:

if(warunek1) instrukcja1;

else if (warunek2) instrukcja2;

else if (warunek3) instrukcja3;

*Inną możliwością wykonywania wybory wielowariantowego jest instrukcja switch, o której innym razem.

I. Instrukcja while

Forma tej instrukcji wygląda następująco:

while(wyrażenie) instrukcja1;

Najpierw obliczana jest wartość wyrażenia. Jeśli wynik jest zerowy, instrukcja nie jest wykonywana. Jeśli jednak wartość wyrażenia jest niezerowa (prawda), wówczas instrukcja jest wykonywana, po czym wartość wyrażenia jest ponownie obliczana. Jeśli wartość danego wyrażenia jest nadal niezerowa, wtedy instrukcja jest ponownie wykonywana, i tak dalej, dopóki (dopóki – ang. while) wyrażenie ma wartość niezerową. Jeżeli w którymś momencie wykonywania instrukcji, wyrażenie będzie miało wartość zerową, pętla wykonywania instrukcji while zostanie przerwana.

Oto przykładowy program:

#include &ltiostream.h&gt

main()

{

int ilość;

  cout<<&#8221;Ile zer ma milion?:&#8221;; 

  cin>>ilość; 

  cout<<&#8221;Skoro tak sądzisz, oto te zera:&#8221;; 

  while(ilość) 

  { 

     cout<<&#8221;0&#8221;; 

     ilość=ilość-1; 

  } 

} 

Omówienie:

Program pyta o liczbę zer, po wpisaniu odpowiedzi przez użytkownika , program za pomocą instrukcji while rysuje odpowiednią liczbę zer.

Wyrażenie ilość, określa liczbę podaną przez użytkownika.

ilość=ilość-1; - przed pierwszym wykonaniem instrukcj while, wyrażenie ilość jest równe np.6, więc program rysuje jedno zero. Przed następnym wykonaniem instrukcji, wyrażenie jest równe 5 (ilość=ilość-1;), więc program znowu rysuje zero i przechodzi do kolejnego wykonanie instrukcji, ponieważ wyrażenie ma ciągle wartość niezerową; przed kolejnym wykonaniem instrukcji nasze wyrażenie jest równe 4 (następnie 3, 2, 1). W momencie, kiedy wartość wyrażenia będzie równa zero, program przerwie instrukcje a na ekranie pojawi się odpowiednia ilośc zer.

*Jak zwykle zachęcam do eksperymentów. Spróbujcie na przykład tak zmodyfikować kod programu, żeby w przypadku niewłaściwej liczby zer podanej przez użytkownika, program informował o błędzie i kończył swoje działanie komunikatem „Spróbuj jeszcze raz”. Wskazówka: możecie użyć instrukcji if.

II. Pętla do...while...

Oto forma tej instrukcji:

do instrukcja1 while(wyrażenie);

Najpierw wykonywana jest instrukcja1. Następnie obliczana jest wartość wyrażenia. Jeśli jest ono niezerowe, to wykonanie instrukcji1 zostanie powtórzone, po czym wyrażenie zostanie ponownie obliczone...i tak w kółko, dopóki (while) wyrażenie jest różne od zera.

*Tak jak wspomniałem na początku, obie instrukcje są do siebie podobne. Różnica między nimi polega tylko na tym, że wartość wyrażenia obliczana jest nie przed, a po wykonaniu instrukcji1. Łatwo się więc domyśleć, że w przypadku pętli do..while... instrukcja1 zostanie wykonana co najmniej raz. Czyli nawet wtedy, gdy wyrażenie nie bedzie nigdy prawdziwe.

*W tym momencie pojawia się zadanie dla was. Spróbujcie tak przekształcić program przedstawiony powyżej, aby zastosować w nim pętlę do...while... i otrzymać taki sam wynik działania programu. Odpowiedzi na zadanie przysyłajcie na mój e-mail.

III. Pętla for

Pętla for ma następującą formę:

for (instrukcja1;warunek;instrukcja2) treść pętli; 

Omówienie:

for - (ang.dla) oznacza: dla takich warunków wykonuj....

instrukcja1 - instrukcja wykonywana zanim petla zostanie pierwszy raz uruchomiona.

warunek - wyrażenie obliczane przed każdym obiegiem pętli. Jeśli jest ono różne od zera, to

          zostaną wykonane instrukcje będące treścią pętli. Wyrażenie to można określić jako

                            warunek zatrzymania pętli.

instrukcja2 - instrukcja wykonywana na zakończenie każdej pętli (przed obliczeniem wyrażenia

          warunek)

Chcąc przetłumaczyć petlę for na język polski, można powiedzieć tak:

Począwczy od instrukcji 1 aż do warunku, wykonuj instrukcję2.

*Oczywiście należy również uwzględnić treść instrukcji, którą mogą być inne pętle for lub jakiekolwiek inne instrukcje.

*instrukcja1 jaki i instrukcja2 nie muszą być pojedyńczymi instrukcjami. Może ich być kilka, wtedy należy je oddzielić przecinkami. Np:

  for (instrukcja1,insrukcja2,instrukcja3;warunek;instrukcja4,instrukcja5)  treść pętli; 

Analogicznie do wzoru pierwszego; instrukcja 1, instrukcja2, instrukcja3 , są instrukcjami wykonywanymi zanim petla zostanie uruchomiona pierwszy raz . Natomiast instrukcja4 i instrukcja5 są instrukcjami wykonywanymi po zakończeniu każdej pętli.

Przyszedł czas na przykład:

#include &ltiostream.h&gt

main()

{

 int licznik; 

 for(licznik=0;licznik<6;licznik++) 

       cout<<&#8221;WITAM!&#8221;; 

}

Omówienie:

licznik=0 - instrukcja początkowa

licznik<6 - warunek zatrzymania petli

licznik++ - instrukcja wykonywana po zakończeniu każdej pętli

Znaczek ++ po słowie licznik oznacza każdorazowe zwiększanie jego wartości o 1 - inaczej inkrementacja. Przeciwieństwem inkrementacji jest dekrementacja, czyli zmniejszanie wartości o 1 (np.licznik-- ).

I.Instrukcja switch.

Instrukcja switch służy do podejmowania wielowariantowych decyzji.

Budowa tej instrukcji przedstawia się następująco:

switch(wyrażenie) 

{

  case wartość1: 

  instrukcja1; 

  break; 

  case wartość2: 

  instrukcja2; 

  break; 

default:

  instrukcja3; 

  break; 

}

Jeżeli wartość danego wyrażenia odpowiada którejś wartości podanej w etykiecie case, wówczas wykonywane są instrukcje należące do tej etykiety. Ich wykonywanie kończy się po napotkaniu instrukcji break. Jeżeli jednak wartość wyrażenia nie zgadza się z żadną z wartości podanych przy etykietach, wówczas wykonywane są instrukcje należące do etykiety default.

*Etykieta default nie musi być na końcu instrukcji switch – może jaj nawet wcale nie być. W takim przypadku, jeśli wartość wyrażenia nie zgadza się z żadną wartością etykiet case, instrukcja switch jest opószczana, bez wykonywania jakich kolwiek operacji.

*Instrukcja switch nie musi kończyć się instrukcją break. W przypadku jej braku, wykonywane będą instrukcje umieszczone pod następną etykietą.

Po tych wyjasnieniach nadszedł czas na przyklad:

#include &ltiostream.h&gt

main()

{

int wiek; 

cout<<&#8221;Jaki jest twój przedział wiekowy?:\\n&#8221; 

    <<&#8221;1&#8211;przedział 0-15\\n2&#8211;przedział 16-18\\n3&#8211;przedział 19-...\\n&#8221;; 

cin>>wiek; 

switch(data) 

{ 

 case 1: 

        cout<<&#8221;Twój przedział wiekwy to 0-15\\n&#8221;; 

        break; 

 case 2: 

        cout<<&#8221;Twój przedział wiekowy to 16-18\\n&#8221;; 

        break; 

 case 3: 

        cout<<&#8221;Twój przedział wiekowy to 19-...\\n&#8221;; 

        break; 

 default: 

        cout<<&#8221;Brak danych!!&#8221;\\n; 

        break; 

 } 

 } 

II.Instrukcja break

Oprócz przerywania działania instrukcji switch, instrukcja break działa podobnie w stosunku do instrukcji: for, while, do...while – powoduje ona natychmiastowe przerwanie wykonywania tych pętli.

Przy omawianiu tej instrukcji nie będzie przykładu. Dlaczego? Bo to zadanie dla was – znacie już wymienione wcześniej instrukcje, więc do dzieła. Pamiętajcie o zasadzie – „Do odważnych świat należy, czyli eksperymentowania czar” – mam na myśli programowanie:):):).

III.Instrukcja goto

goto etykieta;

Po napotkaniu tej instrukcji wykonywanie programu przenosi się do miejsca, gdzie znajduje się dana etykieta.

Po etykiecie musi pojawić się dwukropek.

Oto przykład:

   cout<<&#8221;Pada deszcz\\n&#8221;; 

goto decyzja:

cout<<”Idziemy na spacer\n”;

decyzja:

cout<<&#8221;Zostajemy w domu\\n&#8221;; 

*Zapewne zauważyliście, że powyższy przykład nie jest kompletny. BRAWO!! Macie rację. Otóż specjalnie zammieściłem jedynie jego fragment, żebyście sami go uzupełnili.

*Nie można skoczyć z dowolnego punktu programu w dowolne inne. Etykieta musi znajdować się w obowiązującym w danej chwili zakresie ważności. Żeby zrozumieć, czym jest zakres ważności trzeba wyjaśnić dwa pojęcia:

czas życie obiektu – okres począwszy od momentu zdefiniowania go (przydzielenia mu miejsca w pamięci) do

                             momentu, gdy przestaje istnieć (zajmowane przez niego miejsce w pamięci zostaje

                             zwolnione).

zakres ważności nazwy obiektu –część programu, w której nazwa jest znana kompilatorowi.

IV.Instrukcja continue

Stosowana jest w pętlach for, while oraz do...while. Powoduje zaniechanie instrukcji będących treścią pętli, jednak w przeciwieństwie do instrukcji break, sama petla nie zostaje przerwana – zostaje przerwany tylko ten obieg petli i rozpoczęty następny.

Czas na przykład:

int a;

for(a=0;a<7;a=a+1)

{

cout<<&#8221;A&#8221;; 

if(a>1) continue; 

cout<<&#8221;B&#8221;<<endl; 

}

Żeby lepiej zrozumieć działanie instrukcji continue, należy spojrzeć na to, co pojawi się na ekranie po wykonaniu programu.

*Przy omawianiu pętli for, muszę wspomnieć o niebezpieczeństwie, jakie niesie ze sobą niewłaściwe jej użycie – nieskończona pętla. Dzieje się tak wtedy, kiedy warunek zatrzymania pętli zostanie niewłaściwie określony (np. gdyby w naszym przykładzie pętla for wyglądała następująco: for(licznik=0;licznik+1;licznik++) ). Spróbujcie stworzyć program z taką petlą – zobaczycie, jak działa nieskończona pętla – do odważnych świat należy:).

**Wszelkie pytania i sugestie proszę przesyłać na mój adres e-mail. Z góry przepraszam, jeśli odpowiedzi na niektóre listy przyjdą z opóźnieniem, jest to spowodowane tym, że jestem teraz w trakcie pisania mojej pracy dyplomowej i nie zawsze mogę odpowiadać na czas.

Rafał Skopowski
[email protected]

0 komentarzy