Условный оператор обеспечивает выполнение некоторого оператора или группы операторов в зависимости от заданного условия. Синтаксис оператора выглядит следующим образом:
if (выражение)
инструкция1;
else
инструкция2;
Если при вычислении условного выражения в скобках результатом будет «истина» (true, любое отличное от нуля значение), то будет выполнена инструкция1, указанная после if. Если результатом условного выражения будет «ложь» (false, 0) то выполнится инструкция2, указанная после ключевого слова else.
Ветвь else в данном операторе является необязательной. Тогда он будет выглядеть так:
if (выражение)
инструкция1;
В данном случае если выражение в скобках ложно, то инструкция1 просто не выполняется и управление передаётся на следующий оператор.
Очень важным моментом является то, что после if и else допустима только одна инструкция. Если нужно выполнять более чем один оператор, необходимо использовать фигурные скобки {} для создания составного оператора. Например, так:
int x,y;
...
if (y == 0)
cout << "Нельзя делить на 0" << endl;
else
{
x = 1/y;
cout << "1/y = " << x << endl;
}
Здесь в ветви else логика программы требует двух операторов, поэтому они заключены в фигурные скобки. Если бы их не было, то второй оператор (cout) считался не входящим в конструкцию if…else и выполнялся бы всегда независимо от условия. С другой стороны, единственную инструкцию также можно заключать в операторный блок с помощью {}. Поэтому если не уверены – всегда используйте фигурные скобки для выделения границ ветвей в if…else.
В приведённом примере показано также правильное оформление оператора if. Инструкции не пишутся на одной строке с ключевыми словами if и else. Пишутся они с новой строки с отступом относительно ключевого слова if. Это облегчает отладку программы и упрощает её чтение, потому что при таком оформлении сразу видно какие инструкции относятся к ветвям if/else.
Операторы if…else могут быть вложенными друг в друга. Например, вычисление максимума среди трех чисел.
#include <iostream>
using namespace std;
void main()
{
int a,b,c;
int max;
cin >> a >> b >> c;
if (a > b && a > c)
max = a;
else if (b > c)
max = b;
else
max = c;
cout << "Max = " << max << endl;
system("PAUSE");
}
При использовании вложенных инструкций нужно помнить, что оператор else всегда относится к ближайшему оператору if , который находится в том же программном блоке, но ещё не связан ни с каким другим оператором else. Например
if (a)
{
if (b)
result = 1;
if (c)
result = 2;
else
result = 3; // относится к if(c)
if (d)
if (e)
result = 4;
else
result = 5; // относится к if(e)
if (f)
{
if (g)
result = 6;
}
else
result = 7; // относится к if(f)
}
else // относится к if(a)
result = 8;
В реальных программах на C++ часто используется особенность языка, состоящая в том, что любые значения, отличные от 0, в условиях интерпретируются как true, а равные 0 – как false. Поэтому часто можно столкнуться с условиями вида if (result), где result – какая-либо переменная. Если она не равна нулю – условие считается истинным, в противном случае – ложным. Поэтому сравнения вида if (x == 0) часто заменяются на if (!x), а условия if (x != 0) заменяются if (x). Например
FILE* fd;
if (fd = fopen("myfile.txt", "r"))
cout << "File was opened\n";
else
cerr << "Error!\nFile was not opened\n";
Здесь происходит попытка открытия файла myfile.txt с использованием функции fopen (более подробно работа с файлами будет рассмотрена позднее). Эта функция возвращает указатель на открытый файл. Если же при открытии произошла ошибка, то возвращается 0 (или NULL, что означает нулевой указатель). Поэтому внутри условия происходит следующее:
- сначала вызывается функция fopen, которая пытается открыть файл;
- результат её работы – указатель на файл или нулевой указатель присваивается в переменную fd;
- в качестве условного выражения if использует значение, присвоенное fd, поэтому если файл был открыт, в fd будет ненулевой указатель, а если произошла ошибка – ноль.
Еще одной особенностью оператора if является та, что он ограничивает область действия имен переменных, которые были в нём объявлены. Например
#include <iostream>
#include <time.h>
using namespace std;
void main()
{
srand(time(NULL));
if (int a = rand()) // область действия – только оператор if
int b = a/2; // область действия - одна строка
else
{
int c = a + rand(); // область действия - ветвь else
cout << c;
}
}
Здесь используется функция rand(), возвращающая случайное целое число из диапазона от 0 до RAND_MAX (32767). Перед использованием генератор случайных чисел инициализируется текущим значением времени с помощью функции srand.
В примере переменная a, объявленная внутри условия, действует в любых инструкциях, содержащихся внутри if. Переменная b действует только внутри той ветви, в которой она объявлена, т.е. она доступна в единственной строке. Переменная с также видима только внутри своей ветви – else. Ни одна из трех переменных не будет действовать после завершения оператора if.
6.1.2 Тернарный оператор ?:
Это, по сути, короткий и не совсем привычный способ записи оператора if…else. Эта операция имеет 3 операнда и потому называется тернарной. Её синтаксис выглядит следующим образом:
(выражение) ? инструкция1 : инструкция2
Если значение выражения истинно, то выполняется инструкция1, иначе – инструкция2. Результатом операции является значение, полученное в результате выполнения выбранной инструкции.
Например, определение максимального числа:
int x, y, max;
cin >> x >> y;
max = (x > y) ? x : y;
cout << max;
Здесь в операции ?: инструкций фактически нет, поэтому она возвращает значение x или y в зависимости от условия в скобках. В таком виде эта операция чаще всего и применяется. Также возможно использование вложенных операций ?:, например для поиска максимума из трех чисел:
int x, y, z, max;
cin >> x >> y >> z;
max = (x > y && x > z) ? x : (y > z) ? y : z;
cout << max;
Недостаток таких вложенных операций – их сложность для понимания и отладки.