Условные конструкции позволяют направить ход программы по одному из возможных путей в зависимости от условия. В языке Си есть несколько операторов, которые позволяют это сделать.
Оператор if проверяет истинность условия, и если оно истинно, выполняет блок инструкций. Этот оператор имеет следующую сокращенную форму:
if (условие) инструкция;
В качестве условия может выступать любое выражение, которое возвращает число. Если это выражение возвращает ненулевое значение (то есть выражение истинно), то выполняется последующая инструкция:
#include <stdio.h> int main(void) { if(1) printf("Hello C \n"); if(0) printf("Hello World \n"); return 0; }
Здесь у нас две условных конструкции if. В качестве инструкции в обоих случаях выполняется функция printf. И в обоих случаях условие представляет просто число. В первом случае "условие" равно 1, то есть "истинно" (любое число, кроме 0, представляет истину). Поэтому на консоль
будет выполняться функция printf
, которая выведет на консоль строку "Hello C".
А во втором случае "условие" равно 0, то есть "не верно/ложно". Поэтому инструкция printf("Hello World \n")
НЕ будет выполняться.
В приведенном выше примере в качестве условий выступали числа 1 или 0. Однако в реальности в качестве условий выступает результат некоторых выражений, обычно, операций сравнения или логических операций. Однако все они в конечном счете возвращают либо 0 (условие не верно) или ненулевое значение (условие верно). Используем операции сравнения:
#include <stdio.h> int main(void) { int n = 10; if(n == 20) printf("n = 20 \n"); if(n == 10) printf("n = 10 \n"); return 0; }
Здесь также используются две условных конструкции if. В первом случае n == 20
условие не верно, оно возвращает 0, так как значение переменной n не равно 20,
поэтому поэтому последующая инструкция printf("n = 20 \n")
не будет выполняться.
А во втором случае операция сравнения n == 10
возвратит 1, так как условие истинно, поэтому будет выполняться инструкция printf("n = 10 \n")
.
Если в конструкции if необходимо выполнить не одну, а несколько инструкций, то эти инструкции оформляются в блок кода с помощью фигурных скобок:
#include <stdio.h> int main(void) { int x = 60; if(x > 50) { printf("if statement \n"); printf("x is greater than 50 \n"); } return 0; }
Здесь проверяем, больше ли переменная х чем 50. И если это условие истинно, выполняем последующий блок из двух инструкций
Условия могут более сложные:
#include <stdio.h> int main(void) { int x = 50; int y = 60; if (x > 20 && y < 100) { printf("the condition is true\n"); } return 0; }
Здесь проверяем больше ли значение переменно х чем 20 и меньше ли значение переменной y чем 100. Поскольку здесь два условия соединяются операцией &&
, то общее условие будет
истинно, если одновременно верны оба условия.
Но что, если мы хотим определить две пары действий: одни выполняются, если условие истинно, а другие, если условие ложно? В этом случае можно использовать другую форму конструкции if - if..else:
if(условие) инструкция_1 else инструкция_2
После оператора else мы можем определить набор инструкций, которые выполняются, если выражение_условия ложно, то есть возвращает 0. То есть если условие истинно, выполнится инструкция после оператора if, а если это выражение ложно, то выполняется инструкция после оператора else.
int x = 60; if(x > 60) printf("x is greater than 60 \n"); else printf("x is less or equal 60 \n");
Однако в данном случае у нас есть три условия: переменная x может быть больше 60, меньше 60 и равна 60. Для проверки альтернативных условий мы можем вводить выражения else if:
int x = 60; if(x > 60) printf("x is greater than 60 \n"); else if (x < 60) printf("x is less than 60 \n"); else printf("x is equal 60 \n");
То есть в данном случае мы получаем три ветки развития событий в программе.
И также если после операторов должен идти набор инструкций, то эти инструкции оформляются в блок кода:
#include <stdio.h> int main(void) { int x = 60; if(x > 60) { printf("if statement \n"); printf("x is greater than 60 \n"); } else if (x < 60) { printf("else if statement \n"); printf("x is less than 60 \n"); } else { printf("else statement \n"); printf("x is equal 60 \n"); } return 0; }
Другую форму организации ветвления программ представляет конструкция switch...case. Она имеет следующую форму:
switch(выражение) { case константа_1: инструкции_1; case константа_2: инструкции_2; default: инструкции; }
После ключевого слова switch в скобках идет сравниваемое выражение. Значение этого выражения последовательно сравнивается со значениями после оператора сase. И если совпадение будет найдено, то будет выполняться данный блок сase.
В качестве констант после оператора case могут выступать значения типов char, int
и unsigned
. Например, проверим с помощью конструкции
switch значение некоторого числа:
#include <stdio.h> int main(void) { int x = 2; switch(x) { case 1: printf("x = 1 \n"); break; case 2: printf("x = 2 \n"); break; case 3: printf("x = 3 \n"); break; } return 0; }
Здесь в качестве сравниваемого выражения выступает переменная x
. Ее значение последовательно сравнивается со значениями после операторов case
:
сначала программа переходит к выражению case 1
. Но переменная x не равна 1, поэтому выполнение переходит к следующему оператору case.
программа переходит к выражению case 2
. Поскольку переменная x равна 2, то выполняются инструкции данного оператора case:
case 2: printf("x = 2 \n"); break;
Чтобы избежать выполнения последующих блоков case, в конце каждого блока ставится оператор break. При его выполнение происходит выход из конструкции switch..case
В итоге мы получим следующий консольный вывод:
x = 2
При определении блоков case следует не забывать про добавление операторов break. Так, перепигем предыдущий пример без операторов break:
#include <stdio.h> int main(void) { int x = 2; switch(x) { case 1: printf("x = 1 \n"); case 2: printf("x = 2 \n"); case 3: printf("x = 3 \n"); } return 0; }
Так как x=2, то будет выполняться блок инструкций после выражения case 2
. Но поскольку этот блок не завершается оператором break, поэтому будут выполняться
все последующие блоки case, пока не встретится оператор break или конец конструкции switch. Консольный вывод:
x = 2 x = 3
В конце конструкции switch может стоять блок default. Он необязателен и выполняется в том случае, если ни одна совпадения в блоках case не было найдено. Например, сравним значение переменной с набором значений:
#include <stdio.h> int main(void) { int x = 5; switch(x) { case 1: printf("x = 1 \n"); break; case 2: printf("x = 2 \n"); break; case 3: printf("x = 3 \n"); break; default: printf("x is undefined \n"); break; } return 0; }
Поскольку здесь значение x не соответствует ни одному из значений после операторов case, то будет выполняться блок default. Консольный вывод:
x is undefined
Тернарный оператор ?: позволяет сократить определение простейших условных конструкций if и имеет следующую форму:
[первый операнд - условие] ? [второй операнд] : [третий операнд]
Оператор использует сразу три операнда. В зависимости от условия тернарный оператор возвращает второй или третий операнд: если условие равно 1 (то есть истинно), то возвращается второй операнд; если условие равно 0 (то есть ложно), то третий. Например:
#include <stdio.h> int main(void) { int x=5; int y=2; int z = x > y ? x-y : x+y; printf("z = %d", z); // z = 3 return 0; }
Здесь результатом тернарной операции является переменная z. Она имеет следующие операнды:
Условие
x > y
Действия, выполняемые, если условие истинно
x - y
Действия, выполняемые, если условие ложно
x + y
Поскольку в данном случае условие x < y
истинно (то есть x больше чем y), то будет выполняться вычитание x - y
, и переменная z
получит его результат - число 3.