Бьерн Страуструп - Язык программирования С++. Главы 2-4 - Выбирающие операторы

ОГЛАВЛЕНИЕ

3.3.1  Выбирающие операторы

Значение можно проверить с помощью операторов if или switch:

          if ( выражение )  оператор
          if ( выражение )  оператор  else  оператор
          switch  ( выражение )  оператор

В языке С++ среди основных типов нет отдельного булевского (тип со значениями истина, ложь). Все операции отношений:

          ==   !=   <   >   <=   >=

дают в результате целое 1, если отношение выполняется, и 0 в противном случае. Обычно определяют константы TRUE как 1 и FALSE как 0.

В операторе if, если выражение имеет ненулевое значение, выполняется первый оператор, а иначе выполняется второй (если он указан). Таким образом, в качестве условия допускается любое выражение типа целое или указатель. Пусть a целое, тогда

           if (a)  // ...

эквивалентно

           if (a != 0) ...

Логические операции

           &&    ||   !

обычно используются в условиях. В операциях && и || второй операнд не вычисляется, если результат определяется значением первого операнда. Например, в выражении

           if (p && l<p->count)  // ...

сначала проверяется значение p, и только если оно не равно нулю, то проверяется отношение l<p->count.

Некоторые простые операторы if удобно заменять выражениями условия. Например, вместо оператора

           if (a <= b)
              max = b;
           else
              max = a;

лучше использовать выражение

           max = (a<=b) ? b : a;

Условие в выражении условия не обязательно окружать скобками, но если их использовать, то выражение становится понятнее.

Простой переключатель (switch) можно записать с помощью серии операторов if. Например,

            switch (val) {
            case 1:
                f();
                break;
            case 2:
                g();
                break;
            default:
                h();
                break;
            }

можно эквивалентно задать так:

            if (val == 1)
               f();
            else if (val == 2)
               g();
            else
               h();

Смысл обеих конструкций совпадает, но все же первая предпочтительнее, поскольку в ней нагляднее показана суть операции: проверка на совпадение значения val со значением из множества констант. Поэтому в нетривиальных случаях запись, использующая переключатель, понятнее.

Нужно позаботиться о каком-то завершении оператора, указанного в варианте переключателя, если только вы не хотите, чтобы стали выполняться операторы из следующего варианта. Например, переключатель

           switch (val) {       // возможна ошибка
           case 1:
               cout << "case 1\n";
           case 2:
               cout << "case 2\n";
           default:
               cout << "default: case not found\n";
           }

при val==1 напечатает к большому удивлению непосвященных:

           case 1
           case 2
           default: case not found

Имеет смысл отметить в комментариях те редкие случаи, когда стандартный переход на следующий вариант оставлен намеренно. Тогда этот переход во всех остальных случаях можно смело считать ошибкой. Для завершения оператора в варианте чаще всего используется break, но иногда используются return и даже goto. Приведем пример:

           switch (val)  {       // возможна ошибка
           case 0:
               cout << "case 0\n";
           case1:
           case 1:
               cout << "case 1\n";
               return;
           case 2:
               cout << "case 2\n";
               goto case1;
           default:
               cout << "default: case not found\n";
               return;
           }

Здесь при значении val равном 2 мы получим:

           case 2
           case 1

Отметим, что метку варианта нельзя использовать в операторе goto:

           goto case 2;  // синтаксическая ошибка