Instrukcje warunkowe

Dotychczas nasze programy były, można by powiedzieć, goopie :-P. Potrafiły tylko wykonywać instrukcje w takiej kolejności, w jakiej umieszczone były w programie, czyli jedna za drugą. Teraz to się zmieni, bo nauczymy nasze programy podejmować decyzje. Zależnie od podjętych decyzji program będzie się "rozgałęziać" i jego wykonanie potoczy się dalej jedną z możliwych dróg.

Instrukcja if

Wykonanie instrukcji można uzależnić od spełnienia jakiegoś warunku. Do tego celu służy instrukcja warunkowa. Najprostsza jej postać wygląda tak:

if ( wyrażenie_logiczne ) instrukcja_zależna

Jak widzisz, instrukcja warunkowa rozpoczyna się słowem kluczowym if [ang. if = jeśli]. Następnie jest para nawiasów, która ogranicza z obu stron wyrażenie logiczne. Jest to takie wyrażenie, które daje w wyniku wartość logiczną [typu bool], czyli może być albo prawdziwe, albo fałszywe. Jeśli wartość wyrażenia jest innego typu, zostanie skonwertowana na typ bool [o ile taka konwersja jest możliwa].

Tuż po zamykającym nawiasie znajduje się instrukcja, która wykona się tylko wtedy, gdy warunek zostanie spełniony. Jest to tak zwana instrukcja zależna, bo jej wykonanie zależy od spełnienia warunku. Jeśli wartością wyrażenia w nawiasie jest prawda, instrukcja zależna zostanie wykonana. Jeśli wartością wyrażenia jest fałsz, instrukcja się nie wykona [zostanie pominięta], i program będzie działał dalej od następnej instrukcji.

Zobaczmy teraz, jak to zastosować w programie. Weź kod programu, który napisaliśmy poprzednio: ten, który pytał użytkownika o wiek. Załóżmy, że chcesz w nim dopisać jeszcze taką instrukcję:

std::cout << "Ty stary koniu! :-P";

jednak chcesz, by ten tekst wyświetlał się tylko wtedy, gdy użytkownik podał wiek większy niż 18 lat. Jak to zrobić? Ano trzeba zrobić z niej instrukcję warunkową ;-) Wygląda to tak:

if (Wiek >= 18)  std::cout << "Ty stary koniu! :-P";

Jak widzisz, instrukcja została poprzedzona słowem kluczowym if i wyrażeniem warunkowym w nawiasie. Wyrażenie to wygląda tak:

Wiek >= 18

Z lekcji o operatorach już pewnie się domyślasz, że będzie ono prawdą tylko wtedy, gdy Wiek jest większy lub równy 18, i wtedy instrukcja się wykona. Cały program wygląda teraz tak:

#include <iostream>
int main()
{
  std::cout << "Ile masz lat?";
  int Wiek;  std::cin >> Wiek;
  if (Wiek >= 18)  std::cout << "Ty stary koniu! :-P";
}

Możesz go teraz skompilować i pobawić się nim chwilkę, podając mu za każdym razem inny wiek. Najlepiej sprawdź wartości w pobliżu 18 by przekonać się, że warunek jest zbudowany prawidłowo ;-) Możesz też spróbować napisać inne wyrażenie warunkowe, może jakieś bardziej skomplikowane. A poniżej masz przykład mojej rozmowy z programem:

Ile masz lat? 24
Ty stary koniu :-P

Instrukcja if...else

Po krótkiej zabawie programem pewnie rzuciło ci się w oczy, że jeśli użytkownik podał wiek mniejszy niż 18 lat, to nie dostaje żadnego tekstu na ekranie. Może być tym trochę zaniepokojony i zastanawiać się, po co było to pytanie jeśli teraz nic się nie dzieje ;-J Jak to naprawić? Jeśli po prostu dopiszesz kolejną instrukcję wyświetlającą tekst na konsoli:

if (Wiek >= 18)  std::cout << "Ty stary koniu! :-P";
std::cout << "To mlode ciele z ciebie :-)";

to program nie zadziała tak jak tego oczekujemy. Zresztą jak nie wierzysz to sprawdź jak zadziała ;-) Okaże się, że tekst "To mlode ciele z ciebie :-)" zostanie wypisany niezależnie od odpowiedzi użytkownika. Po prostu po wykonaniu [lub nie] instrukcji warunkowej, wykonanie programu zawsze dojdzie do tego miejsca.

Żeby osiągnąć pożądany efekt, trzeba posłużyć się drugą formą instrukcji warunkowej, której "szkielet" wygląda tak:

if ( wyrażenie_warunkowe ) instrukcja1 else instrukcja2

Jak widzisz, doszło nam tu słowo kluczowe else [ang. else = albo, inaczej, w przeciwnym wypadku], po którym występuje kolejna instrukcja zależna. Ta forma instrukcji warunkowej działa tak, że jeśli wyrażenie warunkowe daje w wyniku prawdę, to wykona się instrukcja1, natomiast w przeciwnym wypadku [i tylko wtedy!] wykona się instrukcja2.

A oto jak można zastosować to w naszym programie:

if (Wiek >= 18)  std::cout << "Ty stary koniu! :-P";
else  std::cout << "To mlode ciele z ciebie :-)";

Instrukcji nigdy za wiele...

Oczywiście tam, gdzie można użyć jednej instrukcji, można też użyć bloku instrukcji. Jeśli więc chcesz oddać więcej instrukcji naraz pod kontrolę instrukcji warunkowej, wystarczy że w miejscu pojedynczej instrukcji:

if (warunek)
  instrukcjaA;
else
  instrukcjaB;

wstawisz blok instrukcji zamkniętych w klamry, np. tak:

if (warunek)
{
  instrukcjaA1;
  instrukcjaA2;
  instrukcjaA3;
  // ...
}
else
  instrukcjaB;

Wtedy jeśli warunek zostanie spełniony, trzy instrukcje z klamry zostaną wykonane. W przeciwnym wypadku wszystkie trzy zostaną przeskoczone [pominięte] i wykona się instrukcjaB;.

Skoro mamy tutaj klamry bloku, to co takiego się stanie, jeśli zadeklarujemy wewnątrz bloku jakiś obiekt? Na przykład tak?:

if (warunek)
{
  int x = 7;
  // ...
}

Tak, twoje domysły są słuszne ;-) Obiekt ten będzie lokalny dla bloku i będzie istniał tylko w jego obrębie. Nie będzie dostęny nigdzie na zewnątrz niego. Przydaje się to wtedy, gdy wewnątrz instrukcji warunkowej potrzebujesz jakichś obiektów, ale nie chcesz, by po jej zakończeniu plątały ci się w programie [jeszcze byś ich przypadkowo użył ;-P].

Na co trzeba uważać?

Pokażę ci teraz kod, w którym najwięcej początkujących robi błędy. Szczególnie jeśli wcześniej programowali oni w języku Pascal :-P Oto on:

if (Wiek = 13)  std::cout << "Pechowy wiek :-P";

Zamysłem autora tego kodu było porównanie wartości obiektu Wiek z liczbą 13. Ku jego zdziwieniu program wyświetli ten tekst niezależnie od tego, jaki wiek się mu wpisze. Dlaczego?

Ponieważ zamiast operatora porównania == użył operatora przypisania =. Błąd ten jest szczególnie trudny do wykrycia, bo dla kompilatora jest to poprawny kod. Po prostu wartość 13 zostanie wpisana do obiektu Wiek, zastępując jego poprzednią wartość. Jak już wspomniałem w lekcji o wyrażeniach, operator = daje w wyniku wartość obiektu, do którego przypisał.

Tak, tak też można ;-) eden arcyciekawy przypadek: W wyrażeniu warunkowym też możesz umieścisz deklarację obiektu. Będzie można wtedy użyć jego nazwy w całym obrębie instrukcji warunkowej - nie tylko w

if (int x = 7)
{
  
  // ...
}

Instrukcja switch...case

Szkielet instrukcji switch jest następujący:

switch (wyrażenie) instrukcja_zależna

Jeśli więc ułożysz tą instrukcję tak:

switch (<odpowiedz<)  std::cout << "Ten napis zjadly smoki :-)";

to tekst nigdy się nie wyświetli, bo w instrukcji zależnej kontrolowanej przez switch nie ma żadnej instrukcji, która miałaby etykietę case. Po sprawdzeniu wartości zmiennej odpowiedx program przeskoczy całą resztę instrukcji i zacznie wykonywać następną w kolejności.


Subskrybcja

Buttony
Pomagał GIMP Powered by NAVI GameCreator GameCreator GameCreator