Урок 4. Условия — if, else и switch
До сих пор программы выполнялись строка за строкой. Но часто нужно по-разному поступить в разных случаях: положительное число или отрицательное, верный пароль или нет. Для этого есть условия.
Сравнения
Сравнение даёт логическое значение bool — true или false:
| Запись | Значит |
|---|---|
a == b | равно (два знака =) |
a != b | не равно |
a < b, a > b | меньше, больше |
a <= b, a >= b | меньше или равно, больше или равно |
Один знак = — это присваивание, два == — сравнение. Если перепутать их в условии, C# не скомпилирует программу: if (x = 5) даёт ошибку, а не тихо неверный результат.
if и else
Console.Write("Введите число: ");
int n = int.Parse(Console.ReadLine() ?? "");
if (n > 0)
{
Console.WriteLine("Положительное");
}
else if (n < 0)
{
Console.WriteLine("Отрицательное");
}
else
{
Console.WriteLine("Ноль");
}Введите число: -7
Отрицательноеif (условие) { ... }— блок в фигурных скобках выполняется, только если условие истинно.else if— следующая проверка, если предыдущие не подошли. Их может быть сколько угодно.else— что делать, если не подошло ничего. Его можно не писать.
Выполняется только одна ветка — первая подходящая. Если в блоке одна команда, скобки можно опустить, но лучше всегда их ставить: так проще не ошибиться, когда в блок добавится вторая строка.
Чётное или нечётное
Остаток от деления % часто стоит в условиях: число чётное, если остаток от деления на 2 равен нулю.
int n = int.Parse(Console.ReadLine() ?? "");
if (n % 2 == 0)
{
Console.WriteLine($"{n} — чётное");
}
else
{
Console.WriteLine($"{n} — нечётное");
}1414 — чётноеПроверяйте именно n % 2 == 0 или n % 2 != 0. Условие n % 2 == 1 ошибается на отрицательных числах: у -3 % 2 остаток -1.
И, ИЛИ, НЕ
Условия соединяют логическими операторами:
&&— «и»: истинно, когда истинны обе части;||— «или»: истинно, когда истинна хотя бы одна;!— «не»: меняетtrueнаfalseи обратно.
int age = 15;
bool hasTicket = true;
if (age >= 12 && hasTicket)
{
Console.WriteLine("Проходите");
}
if (age < 6 || age > 65)
{
Console.WriteLine("Положена скидка");
}
if (!hasTicket)
{
Console.WriteLine("Нужен билет");
}Проходите&& и || проверяют вторую часть, только если без неё ответ ещё не ясен. Поэтому безопасно писать if (b != 0 && a / b > 2): при b == 0 деления не будет.
Проверку «число в диапазоне» удобно писать шаблоном (сравнением с образцом через is): if (n is >= 1 and <= 10) — то же, что if (n >= 1 && n <= 10).
Тернарный оператор
Когда нужно выбрать одно из двух значений, вместо if хватает записи условие ? если_да : если_нет. «Тернарный» значит «из трёх частей»: условие и два варианта.
int a = 7;
int b = 12;
int max = a > b ? a : b;
string kind = max % 2 == 0 ? "чётное" : "нечётное";
Console.WriteLine($"Большее: {max}, {kind}");Большее: 12, чётноеswitch
Если одну переменную сравнивают с несколькими конкретными значениями, удобнее switch:
int day = int.Parse(Console.ReadLine() ?? "");
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("Будний день");
break;
case 6:
case 7:
Console.WriteLine("Выходной");
break;
default:
Console.WriteLine("Нет такого дня недели");
break;
}6Выходнойcase 6:— метка: сюда программа переходит, еслиdayравно 6. Несколько меток подряд ведут к одному блоку.break— выход изswitch. В C# он обязателен в конце каждого блока: «провалиться» в следующийcase, как в C или C++, нельзя — компилятор выдаст ошибку CS0163.default— если не подошла ни одна метка.
switch работает и со строками: case "да":.
Выражение switch
Когда по значению нужно получить другое значение, есть короткая форма — выражение switch (появилось в C# 8, сравнения < и > в нём — в C# 9). В ней можно сравнивать не только на равенство:
int t = int.Parse(Console.ReadLine() ?? "");
string weather = t switch
{
< 0 => "мороз",
< 10 => "холодно",
< 20 => "прохладно",
< 30 => "тепло",
_ => "жарко"
};
Console.WriteLine(weather);15прохладноВарианты проверяются сверху вниз, берётся первый подходящий: 15 не меньше 0 и не меньше 10, но меньше 20. _ — «всё остальное». Варианты разделяются запятыми, а после закрывающей скобки ставится ;.
Частые ошибки
;сразу после условия:if (x > 0);— условие управляет пустой командой, а блок ниже выполняется всегда. Компилятор предупреждает:Possible mistaken empty statement(CS0642).Control cannot fall through from one case label(CS0163) — в конце блокаcaseзабытbreak.- Цепочка
ifбезelse: каждое условие проверяется отдельно, и могут сработать несколько веток. Если нужна ровно одна —else if. - Сравнение строк без учёта регистра:
"Да" == "да"— этоfalse. Как сравнивать — в справке Как сравнить строки.
Коротко
- Сравнения:
==,!=,<,>,<=,>=; результат —bool. if/else if/else— выполняется первая подходящая ветка.&&— и,||— или,!— не; диапазон —n is >= 1 and <= 10.условие ? a : b— выбор одного из двух значений.switchсcaseи обязательнымbreak; выражениеx switch { ... => ..., _ => ... }— короткая форма.