if-else

В языке программирования C условное ветвление if-else оформляется следующим образом:

if (логич_выражение)
    выражение1;
else
    выражение2;

Как и в других языках, ветка else в C является необязательной.

В языке C для составления простейших логических выражений применяются операторы сравнения: >, <, >=, <=, ==, !=.

Если тело ветки состоит из нескольких операторов, то оно должно быть заключено в фигурные скобки:

if (логич_выражение) {
    выражение1;
    выражение2;
    …
}
else {
    выражениеN;
    …
}

В языке C возможно использование вложенных конструкций if-else. Часто рекомендуется вставлять их в ветку else, а не if, чтобы избежать путаницы. Рассмотрим такой пример:

if (…)
	if (…)
		…;
	else
		…;
else
	if (…)
		…;
	else
		…;

Для ясности вложенность отображается через отступы. Однако компилятор языка C игнорирует отступы, что может привести к недоразумениям. Важно знать, что компилятор свяжет ветку else с ближайшей ей сверху инструкцией if, не имеющей else. Здесь происходит следующее: первое else привязывается ко второму if, а второе else — к первому if, так как второе if уже "закрыто" предыдущей веткой else. Теперь взглянем на немного видоизмененный пример:

if (…)
	if (…)
		….;
else
	if (…)
		….;
	else
		…;

Программист использует отступы, чтобы показать связь между ветвями, однако компилятор интерпретирует это иначе:

if (…)
	if (…)
		….;
	else
		if (…)
			….;
		else
			….;

В результате, при ложном значении в главном if, обе ветки else могут не исполняться. В таких ситуациях для определения четкой структуры используют фигурные скобки, даже если в теле выполняется лишь одно выражение:

if (…) {
	if (…)
		….;
}
else
	if (…)
		….;
	else
		….;

Такое оформление позволяет компилятору однозначно определить структуру программы в соответствии с замыслом программиста.

В большинстве случаев для многократного ветвления используется подобная конструкция:

if (…) {
    …
} else if (…) {
    …
} else if (…) {
    …
} else {
    …
}

Здесь каждое else связывается с предыдущим if, но форматирование создает впечатление наличия в C операторов многофункционального ветвления. Такая конструкция завершает свое выполнение после исполнения первой подходящей ветки.

Условное выражение

Сокращенная форма if-else в C возможна через условное выражение, которое можно присвоить переменной:

(логич_выражение) ? выражение1 : выражение2

Такое выражение оценивает логич_выражение и возвращает выражение1, если оно истинно, и выражение2, если ложно. Например:

x = 12;
y = 16;
z = (x > y) ? x - 1 : y - 1;

Таким образом, переменной z будет присвоено значение 15. Условное выражение удобно в простых случаях ветвления, но оно не поддерживает сложные конструкции.

Операторы И (&&) и ИЛИ (||)

Логические выражения могут содержать несколько условий. В C операторы логические И и ИЛИ обозначаются парными символами амперсанда (&&) и вертикальной черты (||). Их приоритет ниже, чем у простых логических операторов, что позволяет объединять простые логические операции в сложные без заключения в скобки. Вот пример сложного логического выражения:

a > 100 && b != 0
Задания:

Проверьте и разъясните, что выводит функция printf(), если в нее передать простые или сложные логические выражения, такие как:

printf("%d\n", a == b && c < d);
printf("%d\n", c < d);

Оператор switch

Для организации множественного выбора, когда проверяется значение переменной на соответствие разным значениям, удобно применять оператор switch, вместо if-else. Выглядит он следующим образом:

switch (целочисленная_переменная) {
    case константа1:
        операции;
    case константа2:
        операции;
        ….
    default:
        операции;
}

В скобках после switch может находиться как переменная, так и выражение, результат которого — целочисленное значение (в том числе символ). Константы в case также могут быть результатом выражений. Несколько констант можно объединить в одном case, например, case 12, 13, 18. Ветка default необязательна.

При выполнении оператора switch, значение в скобках сравнивается с константами. Найденное соответствие начинает выполнение всех последующих операций case. Другими словами, исполняется не только совпавший кейс, но также все следующие за ним кейсы и default, чьи константы не совпадают со значением в switch. Рассмотрим такой код:

  int a=1;
 
  switch (a) {
    case 0:
      printf("%d ", 0);
    case 1:
      printf("%d ", 1);
    case 2:
      printf("%d ", 2);
    default:
      printf("%d ", -1);
  }
 
  printf("\n");

Отобразит:

1 2 -1

, поскольку при нахождении совпадения, были выполнены все последующие инструкции.

Чтобы избежать этого, в конце операций каждого case добавляют оператор break для принудительного выхода из switch. Например:

  int a=1;
 
  switch (a) {
    case 0:
      printf("%d\n", 0);
      break;
    case 1:
      printf("%d\n", 1);
      break;
    case 2:
      printf("%d\n", 2);
      break;
    default:
      printf("%d\n", -1);
  }

выведет только значение 1, поскольку выполнение switch будет прервано после break в case 1.

Вопросы для самопроверки:

  1. Как оформляется условное ветвление if-else в языке программирования C?
  2. Является ли ветка else обязательной в конструкциях if-else в C?
  3. Какой формат многократного ветвления используется в C?
  4. Как оформляется ветвление в сокращенной форме? Каковы ограничения сокращенной формы?
  5. Что делают операторы && и || в языке программирования C?
  6. Как используется оператор switch в C, и в чем его отличие от конструкции if-else?

Программа курса:

  1. Описание курса
  2. Введение в язык программирования C
  3. Типы данных в C и форматированный вывод
  4. Символьные типы и управляющие символы в C
  5. Операторы ветвления и switch в C
  6. Циклы и операторы в языке C
  7. Битовые операции в языке C
  8. Посимвольный ввод и вывод в C - буферизация
  9. Переменные, адреса и указатели в C
  10. Передача аргументов по ссылке и значению в C
  11. Форматированный ввод данных с использованием scanf
  12. Генерация псевдослучайных чисел на C
  13. Адресная арифметика в массивах C
  14. Передача массивов в функции и указатели
  15. Строки в языке C - особенности и функции работы
  16. Функции работы со строками в C
  17. Работа со структурами в C - создание и применение
  18. Динамические структуры данных в C
  19. Ввод и вывод данных из файлов в языке C
  20. Передача аргументов в C и работа с файлами
  21. Препроцессор в языке C - директивы и макросы
  22. Создание и компиляция многофайловых программ в C
  23. Использование статических и динамических библиотек в C