8.7 Instrukcja warunkowa

Instrukcja warunkowa (ang. conditional statement) występuje w dwóch postaciach.

Prostsza to

       if ( b ) instr
gdzie b jest wyrażeniem o wartości logicznej, a  instr jest instrukcją. Pamiętamy przy tym, o czym już mówiliśmy, że w C/C++ również liczbowe wartości całkowite i wskaźnikowe mogą być trakowane jako wartości logiczne — cokolwiek różnego od zera jest traktowane jako true, a wartość zerowa jako false. Opracowanie instrukcji warunkowej w tej formie polega na obliczeniu wartości b a następnie: Zauważmy, że składnia mówi o jednej instrukcji instr. Jeśli zachodzi potrzeba wykonania (lub zaniechania wykonania) większej liczby instrukcji, to należy ująć je w nawiasy klamrowe, tak aby uczynić z nich jedną instrukcję złożoną (grupującą): np. wykonanie następującego fragmentu
       if ( s != 0 )
           cerr << "Cos nie w porzadku! Konczymy." << endl;
           exit(1);
spowoduje zawsze zakończenie programu, bo instrukcja exit nie jest wcale „pod ifem”! Powinniśmy raczej napisać
       if ( s != 0 ) {
           cerr << "Cos nie w porzadku! Konczymy." << endl;
           exit(1);
       }

Innym często popełnianym błędem jest stawianie średnika zaraz za zamknięciem nawiasu okrągłego w instrukcji warunkowej

       if ( s != 0 );
       {
           cerr << "Cos nie w porzadku! Konczymy." << endl;
           exit(1);
       }
Zauważmy, że kompilacja powyższego fragmentu powiedzie się. Po if (...) jest tu instrukcja, zgodnie ze składnią — jest nią mianowicie instrukcja pusta (średnik). Natomiast instrukcja grupująca, która po niej występuje, nie jest już „pod ifem” i wykona się zawsze, niezależnie od prawdziwości warunku ' s != 0'.

Inna pułapka związana jest z faktem, że w C/C++, jak mówiliśmy w rozdziale o typie logicznym , wartość całkowita jest traktowana jak wartość logiczna: false odpowiada wartości zerowej, true każdej innej. Powoduje to niestety częste błędy (które w Javie zostałyby wychwycone przez kompilator). Na przykład, jeśli ab są zmiennymi całkowitymi, to wartością przypisania ' a=b' jest, zgodnie z zasadą obowiązującą zresztą i w Javie, wartość lewej strony po przypisaniu, czyli wartość a. I to ona zostanie zinterpretowana jako wartość logiczna wyrażenia ' a=b' w instrukcji

       if ( a = b ) instr         // prawdopodobnie źle !!
choć zwykle intencją programisty było raczej porównanie: sprawdzenie, czy wartość a jest czy nie jest równa wartości b.


Druga forma instrukcji warunkowej to

       if ( b ) instr1
       else     instr2
gdzie, jak poprzednio, b jest wyrażeniem o wartości logicznej a  instr1instr2 są instrukcjami — prostymi lub złożonymi. Opracowanie instrukcji warunkowej w tej formie polega na obliczeniu wartości b, a następnie: I znów składnia mówi o jednej instrukcji instr1 i jednej instrukcji instr2. Jeśli zachodzi potrzeba użycia kilku instrukcji,to należy, jak poprzednio, zastosować instrukcję grupującą.

Każda z instrukcji instr1instr2 może z kolei też być instrukcją warunkową. Obowiązuje przy tym zasada, że frazie else odpowiada zawsze najbliższa poprzedzająca ją fraza if, po której nie było jeszcze frazy else i która jest zawarta w tym samym bloku na tym samym poziomie zagnieżdżenia co ta fraza else. Na przykład

       if ( b1 ) instr0 else if ( b2 ) instr1 if ( b3 ) instr2
       else instr3 else instr4
jest równoważne
       if ( b1 )           // 1
           instr0
       else                // 1
           if ( b2 ) {     // 2
               instr1
               if ( b3 )   // 3
                   instr2
               else        // 3
                   instr3
           }
           else            // 2
               instr4
gdzie tymi samymi liczbami w komentarzach oznaczone są odpowiadające sobie frazy ifelse.

Inny przykład:

      1.      if ( val >= 0 )
      2.      {
      3.          if ( val > 9 ) cout << "Za duzo" << endl;
      4.      }
      5.      else
      6.          cout << "Za malo!" << endl;
Zauważmy, że w powyższym przykładzie konieczne było ujęcie instrukcji z linii trzeciej w blok, mimo że jest to jedyna instrukcja „pod ifem” z linii pierwszej. Gdybyśmy tego nie uczynili, fraza else z linii 5 zostałaby zinterpretowana jako para do frazy if z linii 3, a nie do if z linii pierwszej!

T.R. Werner, 21 lutego 2016; 20:17