🔷 C#

Функции и рекурсия в C# (.NET 6): подробное руководство

Функции и рекурсия в C#

Введение: Зачем нужны функции?

Представь, что ты каждый день делаешь бутерброд. Сначала ты берешь хлеб, потом намазываешь масло, кладешь сыр... Если бы каждый раз нужно было писать все эти шаги заново, это было бы очень скучно. В программировании то же самое: часто нам нужно выполнять одно и то же действие много раз (например, складывать два числа или проверять, четное ли число).

Функция — это как рецепт. Ты один раз записываешь, что нужно сделать, даешь этому рецепту имя, а потом можешь использовать его снова и снова, просто называя имя. В C# мы пишем функции, чтобы сделать код короче, понятнее и не повторять одно и то же.

Основной синтаксис функций в C#

Функция в C# состоит из нескольких частей:

  • Тип возвращаемого значения — что функция отдает наружу (число, текст, или ничего, если void).
  • Имя функции — придумываешь сам.
  • Параметры — данные, которые функция принимает на вход (как ингредиенты для бутерброда).
  • Тело функции — сам код внутри фигурных скобок { }.
// Простая функция, которая складывает два числа
int Sum(int a, int b)
{
    return a + b; // return — это ответ, который функция отдает обратно
}

// Использование
int result = Sum(5, 3);
Console.WriteLine(result); // Выведет: 8

Пример 1: Семейный бюджет (сумма доходов)

Напишем функцию, которая принимает два числа (доходы) и возвращает их сумму. Это базовая задача на сложение.

using System;

class Program
{
    // Функция, которая считает общий доход
    static double CalculateTotal(double income1, double income2)
    {
        return income1 + income2;
    }

    static void Main()
    {
        Console.Write("Введите первый доход: ");
        double first = Convert.ToDouble(Console.ReadLine());
        
        Console.Write("Введите второй доход: ");
        double second = Convert.ToDouble(Console.ReadLine());
        
        double total = CalculateTotal(first, second);
        Console.WriteLine($"Общий доход: {total}");
    }
}

Пример 2: Сравнение температур

Функция принимает две температуры и возвращает большую из них. Здесь мы используем условный оператор if внутри функции.

static double MaxTemperature(double t1, double t2)
{
    if (t1 > t2)
        return t1;
    else
        return t2;
}

// В Main:
double temp1 = 25.5;
double temp2 = 30.1;
double max = MaxTemperature(temp1, temp2);
Console.WriteLine($"Большая температура: {max}"); // 30.1

Пример 3: Проверка четности числа

Функция возвращает true (истина) или false (ложь). Такие функции называются булевыми.

static bool IsEven(int number)
{
    // Если остаток от деления на 2 равен 0 — число четное
    return number % 2 == 0;
}

// В Main:
Console.Write("Введите количество коробок: ");
int boxes = Convert.ToInt32(Console.ReadLine());
if (IsEven(boxes))
    Console.WriteLine("Число четное, можно упаковывать в пары!");
else
    Console.WriteLine("Число нечетное, нужна еще одна коробка.");

Пример 4: Реверс строки (через функцию)

Здесь функция принимает строку и возвращает перевернутую строку. Мы используем цикл for.

static string ReverseString(string input)
{
    string result = ""; // Пустая строка для результата
    for (int i = input.Length - 1; i >= 0; i--) // Идем с конца
    {
        result += input[i]; // Добавляем каждый символ
    }
    return result;
}

// В Main:
Console.Write("Введите сообщение: ");
string message = Console.ReadLine();
string reversed = ReverseString(message);
Console.WriteLine($"Перевернутое сообщение: {reversed}");

Что такое рекурсия?

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

Важно: у рекурсии всегда должно быть условие остановки (базовый случай), иначе она будет вызывать себя бесконечно, и программа "зависнет".

Пример 5: Поиск минимального элемента в списке (через рекурсию)

Представим, что у нас есть список температур за день. Мы хотим найти самую низкую. Рекурсивно: если в списке один элемент — он и есть минимум. Если больше — сравниваем первый элемент с минимумом остальной части списка.

using System;
using System.Collections.Generic;

class Program
{
    static int FindMin(List<int> numbers, int index)
    {
        // Базовый случай: если мы дошли до последнего элемента
        if (index == numbers.Count - 1)
            return numbers[index];
        
        // Рекурсия: находим минимум в оставшейся части
        int minOfRest = FindMin(numbers, index + 1);
        
        // Сравниваем текущий элемент с минимумом остатка
        if (numbers[index] < minOfRest)
            return numbers[index];
        else
            return minOfRest;
    }

    static void Main()
    {
        List<int> temperatures = new List<int>() { 15, 12, 18, 10, 20, 8, 14 };
        int minTemp = FindMin(temperatures, 0);
        Console.WriteLine($"Самая низкая температура: {minTemp}"); // 8
    }
}

Частые ошибки новичков

  • Забыть ключевое слово static — в простых консольных программах функции в классе Program должны быть static, иначе их не вызвать из Main.
  • Не использовать return — если функция должна вернуть значение, а return нет, компилятор выдаст ошибку.
  • Бесконечная рекурсия — забыли написать условие выхода. Функция вызывает саму себя снова и снова, пока не закончится память.
  • Путать параметры — передавать аргументы в неправильном порядке. Функция Sum(3, 5) и Sum(5, 3) дадут одинаковый результат для сложения, но для других операций порядок важен.
  • Не использовать Convert для ввода — Console.ReadLine() возвращает строку, а нам часто нужно число. Забываем преобразовать — получаем ошибку.

Итоговый пример: Сложная задача с функциями

Давай решим задачу: "Семья записывает доходы за 3 дня. Нужно найти общую сумму и определить, был ли самый прибыльный день в начале недели (первый день) или в конце (последний)".

using System;

class Program
{
    // Функция для суммы всех доходов
    static int SumAll(int a, int b, int c)
    {
        return a + b + c;
    }

    // Функция для поиска максимального из трех чисел
    static int MaxOfThree(int a, int b, int c)
    {
        int max = a;
        if (b > max) max = b;
        if (c > max) max = c;
        return max;
    }

    static void Main()
    {
        Console.Write("Доход за первый день: ");
        int day1 = Convert.ToInt32(Console.ReadLine());
        
        Console.Write("Доход за второй день: ");
        int day2 = Convert.ToInt32(Console.ReadLine());
        
        Console.Write("Доход за третий день: ");
        int day3 = Convert.ToInt32(Console.ReadLine());
        
        int total = SumAll(day1, day2, day3);
        int maxIncome = MaxOfThree(day1, day2, day3);
        
        Console.WriteLine($"Общий доход за 3 дня: {total}");
        Console.Write("Самый прибыльный день был: ");
        if (maxIncome == day1)
            Console.WriteLine("в первый день");
        else if (maxIncome == day3)
            Console.WriteLine("в последний день");
        else
            Console.WriteLine("в середине недели");
    }
}

Важно помнить: Функции делают код чистым и понятным. Если ты видишь, что какой-то кусок кода повторяется — вынеси его в функцию. А рекурсия — это мощный инструмент для задач, где решение можно разбить на такие же маленькие шаги. Главное — не забывай про условие остановки!