Instrukcje warunkowe

Ostatania modyfikacja: 22 kwietnia 2019, kategoria: Kurs C++

Programy napisane do tej pory potrafiły pobierać pewne informacje od użytkownika oraz wyświetlać je na ekran. Niestety, nie byliśmy w stanie uzależnić działania programu od pewnych warunków. Instrukcje warunkowe pozwalają sterować program w różny sposób w zależności od wartości zmiennych decyzyjnych. Dzięki temu, program pisane przez nas programy mogą zacząć „myśleć” i zachowywać się w różny sposób.

Instrukcja warunkowa IF

Instrukcja warunkowa if jest najprostszą instrukcją warunkową, którą będziesz stosował praktycznie w każdym swoim programie. Za jej pomocą możesz sprawdzić czy dany warunek jest prawdziwy, czy też nie. W zależności od tego Twój program może zachować się w różny sposób.

Składnia instrukcji warunkowej if jest następująca:

if (true) {
    cout << "prawda" << endl;
}

Przeanalizujmy powyższy kod. Po instrukcji warunkowej if występuje nawias, w którym znajduje się jakieś wyrażenie logiczne. Może ono być dowolną zmienną lub bezpośrednią wartością. Wyrażenia logiczne możemy budować korzystając z operatorów porównania. Oto ich lista:

Na powyższym obrazku zostało zaprezentowanych 6 operatorów porównania. Są to operatory obustronne. Oznacza to, że po obu stronach tych operatorów możemy wstawić jakąś wartość lub zmienną.

Kolejną ważną kwestią w instrukcjach warunkowych są klamry zasięgu. Klamry te oznaczają zasięg funkcji lub instrukcji warunkowej. Tak daleko jak sięga klamra, tak daleko będzie wykonywał się kod gdy warunek zostanie spełniony. Po co w programowaniu potrzebne są klamry? Po to abyśmy mogli wykonać wiele operacji w jednej funkcji, lub wiele operacji podczas spełnienia jednego warunku:

Na powyższym obrazku widać, jak analizowany jest warunek. Pełny kod programu może wyglądać następująco:

#include <iostream>

using namespace std;

int main()
{
    if (51 > 30) {
        cout << "tak" << endl;
        cout << "tak" << endk;
    }

    return 0;
}

Gdy warunek jest prawdziwy, wtedy program zacznie wykonywać kod w klamrach, a więc napis tak zostanie wyświetlony dwa razy. Gdyby warunek był nieprawdziwy, wtedy program ominie klamry i zacznie wykonywać kod poza nimi.

W ten sam sposób budujemy różne inne warunki. Przykładowo:

if (1 == 1) {
    cout << "Prawda" << endl;
}

Możemy także korzystać ze zmiennych:

int wiek = 15;

if (wiek < 18) {
    cout << "jestes niepelnoletni!" << endl;
}

Oraz:

bool administrator = true;

if (administrator == true) {
    cout << "tylko dla administratora" << endl;
}

Jak pewnie zauważyłeś, operatory porównania dają nam dużą kontrolę nad biegiem wykonania programu. Prawdziwą siłą są jednak operatory logiczne, zaprezentowane na poniższym rysunku:

Tak jak w przypadku operatorów porównania, tak samo operatory logiczne są operatorami dwustronnymi. Przykładowe ich wykorzystanie może wyglądać następująco:

int liczba = 13;

if (liczba >= 10 && liczba <= 20) {
    cout << "Liczba jest z zakresu 10-20" << endl;
}

W powyższym przykładzie zastosowany został operator &&, dzięki któremu możemy sprawdzić, czy warunki po obu stronach są prawdziwe. Inny przykład:

int wiek = 26;
bool nietrzezwy = true;

if (wiek < 18 || nietrzezwy == true) {
    cout << "Osobom ponizej 18 lub nietrzezwym alko nie sprzedajmy!" << endl;
}

W powyższym przykładzie zastosowany został operator ||, dzięki któremu cały warunek zostanie spełniony, jeżeli po którejkolwiek stronie pojawi się prawda. W tym przypadku tekst zostanie wyświetlony na ekranie, mimo, że wiek osoby to 26 lat.

Słowo kluczowe else

We wszystkich przykładach wyżej kod w klamrach wykona się, jeżeli warunek zostanie spełniony. Do instrukcji warunkowej można dopisać także rozkaz else, który oznacza dosłownie „w przeciwnym wypadku”. Jego zakres także regulujemy klamrami. Zostaną one wykonane, jeżeli warunek instrukcji if jest fałszywy. Przykładowo:

int wiek = 16;

if (wiek >= 18) {
    cout << "jestes pelnoletni" << endl;
} else {
    cout << "jestes niepelnoletni" << endl;
}

Złożone instrukcje warunkowe

Czasem logika naszego programu rośnie, a to zmusi nas do tworzenia coraz bardziej złożonych instrukcji warunkowych. Jednym z ciekawych zabiegów może być dodanie warunku if do rozkazu else. Przykładowo:

string jezyk = "c++";

if (jezyk == "C#") {
    cout << "jestes programista C#";
} else if (jezyk == "c++") {
    cout << "jestes programista C++";
} else if (jezyk == "java") {
    cout << "jestes programista java";
} else {
    cout << "nie wiem co to za jezyk";
}

Złożone instrukcje (if oraz else) są lepsze niż kilka występujących po sobie zwykłych instrukcji warunkowych (if). Dzieje się tak dlatego, że podczas trafia na pasujący warunek reszta kodu nie jest sprawdzana (jest to optymalne), a dodatkowo możemy użyć rozkazu else w przypadku gdy żaden z warunków nie został spełniony.

Zagnieżdżone instrukcje warunkowe

Nic nie stoi na przeszkodzie aby zagnieżdżać instrukcje warunkowe. Jedynym problemem może być utrzymanie czystości kodu i dbanie o poprawne zamykanie klamer zasięgu. Przykładowo:

bool student = true;
int nrPakietu = 1;

if (student == true) {
    if (nrPakietu == 1) {
        cout << "Studencki pakiet 1" << endl;
    } else {
        cout << "Nieznany pakiet" << endl;
    }
} else  {
    if (nrPakietu == 1) {
        cout << "Normalny pakiet 1" << endl;
    } else if (nrPakietu == 2) {
        cout << "Normalny pakiet 2" << endl;
    } else {
        cout << "Nieznany pakiet" << endl;
    }
}

Przydatne warunki

Ucząc się języka C++ warto znać kilka przydatnych warunków, których dość często się używa. Są to m.in. sprawdzanie długości wyrazu, sprawdzanie parzystości liczby. Mogą się one przydać szczególnie jeżeli np. przygotowujesz się do egzaminu maturalnego z informatyki.

Możesz sprawdzić długość dowolnej zmiennej tekstowej używając funkcji length(). W tym celu wywołaj ją na zmiennej używając operatora kropki:

string name = "Karol";
cout << name.length() << endl; // 5

Dzięki temu, możesz np. sprawdzić poprawność numeru PESEL:

string pesel;

cout << "Podaj numer PESEL" << endl;
cin >> pesel;

if (pesel.length() != 11) {
    cout << "niepoprawny pesel";
} else {
    cout << "pesel poprawny";
}

Aby sprawdzić parzystość liczby wystarczy użyć operatora dzielenia modulo. Jego symbolem w języku C++ jest znak %. Dzielenie modulo różni się od zwykłego dzielenia tym, że zwraca nam resztę z dzielenia a nie wynik dzielenia. Każda liczba parzysta podzielona na 2 zwraca resztę z dzielenia równą 0. Korzystając z tej własności można łatwo sprawdzić parzystość liczby:

int liczba;

cout << "Podaj liczbe" << endl;
cin >> liczba;

if (liczba % 2 == 0) {
    cout << "liczba parzysta";
} else {
    cout << "liczba nieparzysta";
}

Instrukcja warunkowa SWITCH

Zwykła instrukcja warunkowa if idealnie naddaje się do sterowania zachowaniem naszego programu. Jej konstrukcja jest prosta, dodatkowo możemy używać rozkazu else aby obsłużyć warunki, których nie przewidzieliśmy.

Problem pojawia się natomiast wtedy, gdy instrukcja warunkowa if zaczyna puchnąć czyli staje się tzw. złożoną instrukcją warunkową. W takim wypadku kod przestaje być czytelny dla programisty. Z pomocą przychodzi instrukcja warunkowa o nazwie switch. Została ona stworzona po to, aby redukować złożone instrukcje warunkowe, a dzięki temu upraszczać nasz kod. Rozważmy poniższy przykład:

int dzien = 3;

if (dzien == 1) {
    cout << "Poniedzialek" << endl;
} else if (dzien == 2) {
    cout << "Wtorek" << endl;
} else if (dzien == 3) {
    cout << "Sroda" << endl;
} else if (dzien == 4) {
    cout << "Czwartek" << endl;
} else if (dzien == 5) {
    cout << "Piatek" << endl;
} else if (dzien == 6) {
    cout << "Sobota" << endl;
} else if (dzien == 7) {
    cout << "Niedziela" << endl;
} else {
    cout << "Niepoprawny dzien tygodnia" << endl;
}

Czy powyższy kod wygląda dla Ciebie przejrzyście? Zapewne nie. Można go uprościć zamieniając go na instrukcję switch. Przykładowy kod:

int dzien = 3;

switch (dzien)
{
    case 1:
        cout << "poniedzialek";
        break;
    case 2:
        cout << "Wtorek" << endl;
        break;
    case 3:
        cout << "Sroda" << endl;
        break;
    case 4:
        cout << "Czwartek" << endl;
        break;
    case 5:
        cout << "Piatek" << endl;
        break;
    case 6:
        cout << "Sobota" << endl;
        break;
    case 7:
        cout << "Niedziela" << endl;
        break;
    default:
        cout << "Niepoprawny dzien tygodnia" << endl;
}

Powyższy kod zadziała w ten sam sposób. Przeanalizujmy jego strukturę:

  • parametrem rozkazu switch jest zmienna decyzyjna, na której opieramy warunki
  • wszystkie warunki obsługujemy za pomocą słów kluczowych case, którym musimy podać także wartość, którą obsługują
  • nie ma klamer zasięgu, a zakres kodu dla danego warunku sięga od słowa kluczowego case: aż do break;
  • na końcu można dodać słowo kluczowe default:, które pełni rolę else (czyli nieobsługiwany warunek)

Instrukcja warunkowa switch w języku C++ obsługuje tylko typy całkowite oraz tzw. typy wyliczeniowe enum. Z tego powodu jest dość rzadko używana przez programistów. Np. nie da się zbudować instrukcji switch, która obsługiwała by zmienną string.

Jeżeli zapomnisz użyć słowa kluczowego break; po warunku, wtedy kod zacznie wykonywać się dalej, skutkiem czego mogą być pewne błędy w działaniu programu. Tę właściwość można wykorzystać też na swoją korzyść tworząc takie konstrukcje, gdzie kilka warunków podpinamy pod jeden kod:

int dzien = 7;

switch (dzien)
{
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        cout << "Dzien pracujacy" << endl;
        break;
    case 6:
    case 7:
        cout << "Weekend" << endl;
        break;
    default:
        cout << "Niepoprawny dzien tygodnia" << endl;
}

Jak widzisz, w powyższym przykładzie w niektórych miejscach nie występują słowa kluczowe break; dlatego kilka warunków zostanie obsłużonych przez ten sam kod.

Użytkownik Radek napisał:

06 czerwca 2019


Witaj.
Ciesze się ,ze trafiłem na twoja strone.Mam juz swoje lata a opanowała mnie chec by nauczyc sie programowac. U Ciebie jest prosto i jasno wytłumaczone jak stosowac np ,ify .Kto wie ,moze sie naucze.

pozdrawiam

Użytkownik Magdalena napisał:

03 września 2019


Klamry zasięgu mogą występować pod każdą etykietą ‚case’.

Zachęcam Cię do zostawienia komentarza!

Ilość znaków: 0