# Управляющие конструкции: условные операторы и циклы

## Введение

Управляющие конструкции, в частности условные операторы и циклы, являются неотъемлемой частью языка программирования C#. Эти конструкции предоставляют программистам мощные средства для управления ходом выполнения программы, создания логических ветвлений и эффективной обработки данных.

Глава "Управляющие конструкции: условные операторы и циклы" направлена на раскрытие ключевых аспектов этих конструкций, начиная с простых условий и заканчивая более сложными циклами. Мы рассмотрим, как использовать условные операторы для принятия решений в зависимости от различных условий, а также как циклы обеспечивают эффективную обработку повторяющихся задач.

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

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

## Условные операторы

Условные операторы в языке программирования C# предоставляют средства принятия решений в зависимости от истинности или ложности определенных условий. Они позволяют вам создавать ветвления в коде, делая его более гибким и адаптивным к различным сценариям выполнения. В этом разделе мы рассмотрим основные условные операторы C#.

#### **`if` - простое условие**

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

```csharp
csharpCopy codeint number = 7;
if (number > 5)
{
    Console.WriteLine("Число больше 5");
}
```

#### **`else` - ветвление при ложном условии**

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

```csharp
csharpCopy codeint age = 16;
if (age >= 18)
{
    Console.WriteLine("Доступ разрешен");
}
else
{
    Console.WriteLine("Доступ запрещен. Вам несовершеннолетнему.");
}
```

#### **`else if` - дополнительные условия**

Оператор `else if` добавляет дополнительные условия к проверке `if`. Блок кода внутри `else if` выполняется, если предыдущее условие ложно, а текущее – истинно.

```csharp
csharpCopy codeint mark = 85;
if (mark >= 90)
{
    Console.WriteLine("Отличная оценка");
}
else if (mark >= 70)
{
    Console.WriteLine("Хорошая оценка");
}
else
{
    Console.WriteLine("Плохая оценка");
}
```

#### **Тернарный оператор**

Тернарный оператор (`? :`) предоставляет компактный синтаксис для создания условий в одной строке кода.

```csharp
csharpCopy codeint x = 10;
int y = 5;
string result = (x > y) ? "x больше y" : "y больше или равно x";
Console.WriteLine(result);
```

#### **`switch` - множественный выбор**

Оператор `switch` предоставляет возможность создавать множественные ветвления в зависимости от значения выражения.

```csharp
csharpCopy codeint day = 3;
switch (day)
{
    case 1:
        Console.WriteLine("Понедельник");
        break;
    case 2:
        Console.WriteLine("Вторник");
        break;
    case 3:
        Console.WriteLine("Среда");
        break;
    default:
        Console.WriteLine("День недели не определен");
        break;
}
```

Условные операторы играют ключевую роль в создании гибких программ, способных адаптироваться к различным сценариям выполнения. Их правильное использование позволяет эффективно управлять потоком выполнения кода и принимать решения в зависимости от различных условий.

## Циклы

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

#### **`while` - цикл с предусловием**

Цикл `while` проверяет условие перед каждой итерацией. Если условие истинно, выполняется блок кода внутри цикла.

Пример:

```csharp
csharpCopy codeint count = 0;
while (count < 5)
{
    Console.WriteLine($"Текущее значение счетчика: {count}");
    count++;
}
```

В данном примере цикл будет выполняться, пока `count` меньше 5. После каждой итерации значение `count` увеличивается на единицу.

#### **`do-while` - цикл с постусловием**

Цикл `do-while` гарантирует выполнение блока кода хотя бы один раз, так как условие проверяется после каждой итерации.

Пример:

```csharp
csharpCopy codeint number;
do
{
    Console.WriteLine("Введите положительное число:");
} while (!int.TryParse(Console.ReadLine(), out number) || number <= 0);
```

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

#### **`for` - цикл с определенным количеством итераций**

Цикл `for` предоставляет удобный способ определения начальных условий, условия продолжения и шага изменения переменной.

Пример:

```csharp
csharpCopy codefor (int i = 0; i < 5; i++)
{
    Console.WriteLine($"Текущее значение переменной i: {i}");
}
```

В данном примере цикл выполняется от 0 до 4 (включительно) с шагом 1.

#### **`foreach` - цикл для перебора элементов в коллекциях**

Цикл `foreach` предназначен для перебора элементов в коллекциях, таких как массивы, списки и другие объекты, реализующие интерфейс IEnumerable.

Пример:

```csharp
csharpCopy codestring[] colors = { "Красный", "Зеленый", "Синий" };
foreach (string color in colors)
{
    Console.WriteLine($"Текущий цвет: {color}");
}
```

Цикл `foreach` автоматически проходит по всем элементам коллекции `colors`.

#### **Прерывание циклов (`break` и `continue`)**

Оператор `break` используется для прерывания выполнения цикла, а `continue` позволяет пропустить текущую итерацию и перейти к следующей.

Пример:

```csharp
csharpCopy codefor (int i = 0; i < 10; i++)
{
    if (i == 5)
        break; // Прервать цикл при достижении i == 5
    if (i % 2 == 0)
        continue; // Пропустить четные значения i
    Console.WriteLine($"Текущее значение i: {i}");
}
```

В данном примере цикл `for` прервется при `i == 5` и пропустит четные значения, продолжая выполнение.

Циклы в C# предоставляют гибкость и мощные инструменты для обработки данных и выполнения многократных операций. Понимание различных видов циклов и их правильное применение улучшат структуру и эффективность вашего кода.

## Нестандартные управляющие конструкции

Помимо стандартных условных операторов и циклов, в языке программирования C# существуют несколько нестандартных управляющих конструкций, которые могут быть полезны в определенных сценариях. Ниже представлены две из них: `goto` и `yield`.

#### **`goto` - метка и переход**

Оператор `goto` предоставляет возможность создавать метки в коде и осуществлять переход к этим меткам. Использование `goto` требует осторожности, так как оно может сделать код менее читаемым и сложным для понимания.

Пример:

```csharp
csharpCopy codeint i = 0;
startLoop:
    Console.WriteLine(i);
    i++;
    if (i < 5)
        goto startLoop;
```

В данном примере цикл может быть заменен на более структурированный код, но `goto` служит для демонстрации возможности перехода к метке.

#### **`yield` - управление потоком в итераторах**

Оператор `yield` используется в контексте итераторов для управления потоком выполнения. Он позволяет создавать итерируемые последовательности без необходимости вычислять все значения сразу.

Пример:

```csharp
csharpCopy codepublic IEnumerable<int> GenerateNumbers()
{
    for (int i = 0; i < 5; i++)
    {
        yield return i;
    }
}
```

В данном примере метод `GenerateNumbers` возвращает последовательность чисел от 0 до 4. Оператор `yield` приостанавливает выполнение метода и возвращает текущее значение, сохраняя состояние для следующего вызова.

Использование `goto` и `yield` требует внимательного обращения, чтобы избежать создания сложных и трудноподдерживаемых конструкций. Однако они могут быть полезны в определенных сценариях, где стандартные управляющие конструкции не справляются.

## Лучшие практики при использовании управляющих конструкций

Эффективное использование управляющих конструкций в языке программирования C# требует внимательного и осмысленного подхода. Ниже представлены несколько лучших практик, которые помогут улучшить читаемость кода и повысить его эффективность.

#### **Читаемость кода**

* **Используйте информативные имена:** Названия переменных, меток и функций должны быть понятными и описательными. Это улучшит читаемость кода.

```csharp
csharpCopy code// Плохо
int a = 10;
int b = 5;
for (int i = 0; i < a; i++)

// Хорошо
int numberOfIterations = 10;
int step = 5;
for (int iterationCount = 0; iterationCount < numberOfIterations; iterationCount++)
```

* **Форматируйте код правильно:** Используйте правильные отступы, пробелы и пустые строки для лучшей структурированности кода.

```csharp
csharpCopy code// Плохо
for(int i=0;i<10;i++){
Console.WriteLine(i);}

// Хорошо
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}
```

* **Разбивайте сложные условия:** Если условие становится слишком сложным, разбейте его на более простые части с использованием дополнительных переменных.

```csharp
csharpCopy code// Плохо
if (age >= 18 && (isStudent || hasJob) && !isUnderProbation)

// Хорошо
bool isAdult = age >= 18;
bool isEmployedOrStudent = isStudent || hasJob;
bool isNotUnderProbation = !isUnderProbation;
if (isAdult && isEmployedOrStudent && isNotUnderProbation)
```

#### **Эффективность выполнения**

* **Избегайте избыточных операций:** Не выполняйте ненужные действия внутри циклов и условных операторов, чтобы избежать избыточных затрат ресурсов.

```csharp
csharpCopy code// Плохо
for (int i = 0; i < GetExpensiveOperationResult(); i++)

// Хорошо
int result = GetExpensiveOperationResult();
for (int i = 0; i < result; i++)
```

* **Оптимизируйте условия:** Если условие всегда истинно или ложно в определенных сценариях, рассмотрите возможность оптимизации или реорганизации кода.

```csharp
csharpCopy code// Плохо
if (true)
{
    // ...
}

// Хорошо
// Обозначить намерение сделать что-то всегда
const bool alwaysDoSomething = true;
if (alwaysDoSomething)
{
    // ...
}
```

#### **Избегание злоупотребления `goto`**

* **Используйте `goto` осторожно:** Избегайте чрезмерного использования `goto`, так как это может усложнить понимание кода и создать трудноподдерживаемую логику.

```csharp
csharpCopy code// Плохо
startLoop:
    // ...
    goto startLoop;

// Хорошо
while (condition)
{
    // ...
}
```

#### **Разумное применение тернарного оператора**

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

```csharp
csharpCopy code// Плохо
int result = (condition1 && condition2) ? value1 + value2 : value3 - value4;

// Хорошо
int result = (condition1 && condition2)
    ? CalculateSum(value1, value2)
    : CalculateDifference(value3, value4);
```

* **Избегайте вложенности:** Избегайте вложенных тернарных операторов, так как они могут сделать код сложным для понимания.

```csharp
csharpCopy code// Плохо
int result = condition1
    ? (condition2 ? value1 : value2)
    : (condition3 ? value3 : value4);

// Хорошо
int result = CalculateResult(condition1, condition2, condition3, value1, value2, value3, value4);
```

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

## Заключение

Управляющие конструкции в языке программирования C# являются фундаментальным элементом разработки, обеспечивая программистам мощные средства управления ходом выполнения кода. В данной главе мы рассмотрели разнообразные аспекты управляющих конструкций, начиная от условных операторов и циклов, заканчивая нестандартными конструкциями, такими как `goto` и `yield`.

Использование условий позволяет создавать гибкие и адаптивные программы, способные принимать решения в зависимости от различных сценариев выполнения. Циклы предоставляют эффективные средства для обработки повторяющихся задач, а нестандартные конструкции, хотя и требуют осторожного обращения, могут быть полезны в определенных случаях.

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

Бережное отношение к нестандартным управляющим конструкциям, таким как `goto`, и разумное применение тернарного оператора способствуют созданию кода, который не только легко понимать, но и легко поддерживать. В конечном итоге, грамотное использование управляющих конструкций в разработке программ на C# является ключевым компонентом создания надежных и эффективных приложений.

***

## Упражнения

#### **Упражнение 1: Калькулятор условий**

**Задача:** Напишите программу на C#, которая запрашивает у пользователя два числа и оператор (‘+’, ‘-’, ‘\*’ или ‘/’). В зависимости от введенного оператора программа выполняет соответствующую операцию и выводит результат.

<details>

<summary>Решение</summary>

```csharp
// Упражнение 1: Калькулятор условий
using System;

class Program
{
    static void Main()
    {
        // Ввод данных
        Console.Write("Введите первое число: ");
        double number1 = double.Parse(Console.ReadLine());

        Console.Write("Введите второе число: ");
        double number2 = double.Parse(Console.ReadLine());

        Console.Write("Введите оператор (+, -, *, /): ");
        char operatorSymbol = char.Parse(Console.ReadLine());

        // Выполнение операции в зависимости от введенного оператора
        switch (operatorSymbol)
        {
            case '+':
                Console.WriteLine($"Результат сложения: {number1 + number2}");
                break;
            case '-':
                Console.WriteLine($"Результат вычитания: {number1 - number2}");
                break;
            case '*':
                Console.WriteLine($"Результат умножения: {number1 * number2}");
                break;
            case '/':
                if (number2 != 0)
                {
                    Console.WriteLine($"Результат деления: {number1 / number2}");
                }
                else
                {
                    Console.WriteLine("Деление на ноль невозможно.");
                }
                break;
            default:
                Console.WriteLine("Неверный оператор.");
                break;
        }
    }
}
```

</details>

#### **Упражнение 2: Проверка четности**

**Задача:** Напишите программу, которая запрашивает у пользователя целое число и проверяет, является ли оно четным или нечетным. Выведите соответствующее сообщение.

<details>

<summary>Решение</summary>

```csharp
// Упражнение 2: Проверка четности
using System;

class Program
{
    static void Main()
    {
        // Ввод данных
        Console.Write("Введите целое число: ");
        int number = int.Parse(Console.ReadLine());

        // Проверка четности и вывод результата
        if (number % 2 == 0)
        {
            Console.WriteLine("Число четное.");
        }
        else
        {
            Console.WriteLine("Число нечетное.");
        }
    }
}
```

</details>

#### **Упражнение 3: Таблица умножения**

**Задача:** Напишите программу, которая выводит на экран таблицу умножения для заданного числа. Пользователь вводит число, и программа выводит умножение этого числа на числа от 1 до 10.

<details>

<summary>Решение</summary>

```csharp
// Упражнение 3: Таблица умножения
using System;

class Program
{
    static void Main()
    {
        // Ввод данных
        Console.Write("Введите число для таблицы умножения: ");
        int multiplier = int.Parse(Console.ReadLine());

        // Вывод таблицы умножения для заданного числа
        for (int i = 1; i <= 10; i++)
        {
            Console.WriteLine($"{multiplier} * {i} = {multiplier * i}");
        }
    }
}
```

</details>

#### **Упражнение 4: Поиск максимального значения**

**Задача:** Напишите программу, которая запрашивает у пользователя три числа и определяет максимальное из них. Выведите результат на экран.

<details>

<summary>Решение</summary>

```csharp
// Упражнение 4: Поиск максимального значения
using System;

class Program
{
    static void Main()
    {
        // Ввод данных
        Console.Write("Введите первое число: ");
        int number1 = int.Parse(Console.ReadLine());

        Console.Write("Введите второе число: ");
        int number2 = int.Parse(Console.ReadLine());

        Console.Write("Введите третье число: ");
        int number3 = int.Parse(Console.ReadLine());

        // Поиск максимального значения и вывод результата
        int maxNumber = Math.Max(number1, Math.Max(number2, number3));
        Console.WriteLine($"Максимальное число: {maxNumber}");
    }
}
```

</details>

#### **Упражнение 5: Генератор случайных чисел**

**Задача:** Напишите программу, которая генерирует случайное число от 1 до 100 и предлагает пользователю угадать это число. Программа должна предоставлять подсказки (больше/меньше), пока пользователь не угадает число.

<details>

<summary>Решение</summary>

```csharp
// Упражнение 5: Генератор случайных чисел
using System;

class Program
{
    static void Main()
    {
        // Генерация случайного числа от 1 до 100
        Random random = new Random();
        int secretNumber = random.Next(1, 101);

        int userGuess;

        do
        {
            // Ввод предположения пользователя
            Console.Write("Угадайте число от 1 до 100: ");
            userGuess = int.Parse(Console.ReadLine());

            // Проверка и вывод подсказки
            if (userGuess < secretNumber)
            {
                Console.WriteLine("Загаданное число больше.");
            }
            else if (userGuess > secretNumber)
            {
                Console.WriteLine("Загаданное число меньше.");
            }
            else
            {
                Console.WriteLine("Поздравляю! Вы угадали число.");
            }
        } while (userGuess != secretNumber);
    }
}
```

</details>

***

## Вопросы

#### **Условные операторы**

Какие ключевые слова используются для создания условных операторов в C#?

#### **Оператор switch**

В чем отличие между операторами `if-else` и `switch` в C#?

#### **Цикл for**

Как выглядит структура оператора цикла `for` в C#?

#### **Цикл while**

Какова основная идея оператора цикла `while` в C#?

#### **Цикл do-while**

В чем отличие между циклами `while` и `do-while` в C#?

#### **Оператор break**

Для чего используется оператор `break` в циклах в C#?

#### **Оператор continue**

Как работает оператор `continue` в циклах в C#?

#### **Вложенные циклы**

Что такое вложенные циклы, и в каких ситуациях их целесообразно использовать?

#### **Операторы инкремента и декремента**

Какие операторы в C# используются для увеличения и уменьшения значения переменной на единицу?

#### **Безусловный оператор goto**

Почему использование оператора `goto` считается не рекомендуемым в языке C#?

***

## Тесты

{% embed url="<https://docs.google.com/forms/d/e/1FAIpQLSeoBrBj8fZCTcu9fgcuO7JOeogmrYKuUPI_VX20XISZNlwb1A/viewform?usp=sf_link>" fullWidth="true" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://axideli.gitbook.io/osnovy-programmirovaniya-na-yazyke-c/upravlyayushie-konstrukcii-uslovnye-operatory-i-cikly.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
