⚙️ C++

Функции и рекурсия в C++17: подробное руководство

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

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

Представь, что ты пишешь программу для метеостанции. Тебе нужно 10 раз сравнить две температуры и найти большую. Если писать код сравнения каждый раз заново, программа станет огромной и запутанной. Функции — это как маленькие "кирпичики" или "инструменты". Ты создаёшь инструмент один раз, а потом используешь его сколько угодно раз.

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

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

Функция — это блок кода, у которого есть имя. Чтобы создать функцию, напиши:

тип_результата имя_функции(параметры) {
    // код функции
    return результат;
}

Пример: функция, которая складывает два числа (как в задаче "Семейный бюджет"):

#include <iostream>
using namespace std;

int summa(int a, int b) {  // функция принимает два числа, возвращает их сумму
    return a + b;
}

int main() {
    int x, y;
    cout << "Введите два дохода: ";
    cin >> x >> y;
    int result = summa(x, y);  // вызываем функцию
    cout << "Общая сумма: " << result << endl;
    return 0;
}

Результат работы:
Введите два дохода: 500 300
Общая сумма: 800

Функции с условиями (сравнение температур)

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

#include <iostream>
using namespace std;

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

int main() {
    double temp1, temp2;
    cout << "Введите две температуры: ";
    cin >> temp1 >> temp2;
    double result = maxTemperature(temp1, temp2);
    cout << "Большая температура: " << result << endl;
    return 0;
}

Результат работы:
Введите две температуры: 36.6 38.2
Большая температура: 38.2

Функции, возвращающие true/false (проверка чётности)

Такие функции называют булевыми. Они возвращают true (правда) или false (ложь):

#include <iostream>
using namespace std;

bool isEven(int number) {
    if (number % 2 == 0) {
        return true;
    } else {
        return false;
    }
}

int main() {
    int boxes;
    cout << "Сколько коробок произведено? ";
    cin >> boxes;
    if (isEven(boxes)) {
        cout << "Число чётное, можно упаковывать парами." << endl;
    } else {
        cout << "Число нечётное, одна коробка лишняя." << endl;
    }
    return 0;
}

Результат работы:
Сколько коробок произведено? 101
Число нечётное, одна коробка лишняя.

Рекурсия: функция вызывает саму себя

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

Пример: рекурсивный разворот строки (как в задаче "Реверс строки"):

#include <iostream>
#include <string>
using namespace std;

void reverseString(string s) {
    // Базовый случай: если строка пуста, выходим
    if (s.length() == 0) {
        return;
    }
    // Рекурсивный шаг: печатаем последний символ, затем вызываем для строки без последнего
    cout << s[s.length() - 1];
    reverseString(s.substr(0, s.length() - 1));
}

int main() {
    string text;
    cout << "Введите строку: ";
    getline(cin, text);
    cout << "Реверс: ";
    reverseString(text);
    cout << endl;
    return 0;
}

Результат работы:
Введите строку: Привет
Реверс: тевирП

Поиск минимума в списке (с помощью рекурсии)

Представь, что у тебя есть массив температур за день. Рекурсия поможет найти самую низкую температуру:

#include <iostream>
using namespace std;

int findMin(int arr[], int size) {
    // Базовый случай: если в массиве один элемент, он и есть минимум
    if (size == 1) {
        return arr[0];
    }
    // Находим минимум в оставшейся части
    int minOfRest = findMin(arr, size - 1);
    // Сравниваем последний элемент с минимумом остатка
    if (arr[size - 1] < minOfRest) {
        return arr[size - 1];
    } else {
        return minOfRest;
    }
}

int main() {
    int temps[5] = {22, 18, 25, 15, 20};
    int minTemp = findMin(temps, 5);
    cout << "Минимальная температура за день: " << minTemp << " градусов" << endl;
    return 0;
}

Результат работы:
Минимальная температура за день: 15 градусов

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

  • Забыли return — функция должна что-то возвращать, если у неё не тип void. Иначе программа выдаст мусор или ошибку.
  • Бесконечная рекурсия — если не написать базовый случай (условие остановки), функция будет вызывать себя вечно, и программа "зависнет".
  • Перепутали аргументы — при вызове функции порядок чисел важен. Если функция ждёт (a, b), а ты передаёшь (b, a), результат может быть неверным.
  • Изменение глобальных переменных внутри функции — лучше передавать всё через параметры, чтобы не было путаницы.

Итоговый пример: семейный бюджет с проверкой

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

#include <iostream>
using namespace std;

// Функция для сложения
int add(int a, int b) {
    return a + b;
}

// Функция для проверки чётности
bool isEven(int num) {
    return num % 2 == 0;
}

int main() {
    int income1, income2;
    cout << "Введите доход от первой работы: ";
    cin >> income1;
    cout << "Введите доход от второй работы: ";
    cin >> income2;

    int total = add(income1, income2);
    cout << "Общий доход: " << total << endl;

    if (isEven(total)) {
        cout << "Сумма чётная — можно отложить половину на сбережения!" << endl;
    } else {
        cout << "Сумма нечётная — добавьте 1 рубль для ровного счёта." << endl;
    }

    return 0;
}

Результат работы:
Введите доход от первой работы: 45000
Введите доход от второй работы: 32000
Общий доход: 77000
Сумма чётная — можно отложить половину на сбережения!

Совет: Сначала всегда пиши простые функции, которые делают одно маленькое дело. Потом собирай из них большие программы — как из кубиков Lego. Рекурсию используй, когда задача "распадается" на такие же, но меньшие задачи. Удачи в программировании!