Функции в языке C - Урок программирования для 9 класса
💻 Информатика 9 класс

Функции в языке C

Привет! Сегодня мы погрузимся в мир функций — мощного инструмента, который делает код понятным, удобным и профессиональным. Представь: ты пишешь программу для игры, и один и тот же код повторяется раз пять. Копировать? Неудобно! Вот для этого и нужны функции. Готов? Поехали!

Функции — это детали конструктора программы

Зачем нужны функции?

Когда ты работаешь над большим проектом (будь то программа для обработки фото, бот для Discord или игра), код быстро разрастается. Функции — это как отдельные "мини-программы" внутри основной программы.

✨ Что дают нам функции

  • Не повторяться: написал один раз — используй хоть сто раз
  • Легче находить ошибки: проблема в одном месте, а не размазана по всему коду
  • Делиться кодом: твою функцию может использовать друг в своём проекте
  • Думать проще: разбиваешь большую задачу на маленькие понятные кусочки

💡 Важно знать

В языке C все подпрограммы называются функциями. Даже главная программа — это функция main()! Но функции бывают разные: одни возвращают результат, другие просто выполняют действия.

Функции с возвращаемым значением

Функция с возвращаемым значением — это функция, которая вычисляет и возвращает конкретный результат. Это самый распространённый и понятный тип функций в C.

Функция с return — математическая машина

Функция с return — это математическая машина: засунул значения, получил ответ

📐 Общая структура функции

<тип_результата> <имя_функции>(<параметры>) {
    // объявление локальных переменных
    // вычисления
    return <результат>;
}

Разбираем по частям:

  • Тип результата — какое значение вернёт функция: int, double, char и т.д.
  • Имя — даёшь функции понятное имя (например, max, sumDigits, isPrime)
  • Параметры — данные, которые функция получает для работы
  • return — оператор, который возвращает результат
  • Фигурные скобки {} — внутри них все действия функции

Пример 1: Функция максимума

Давай напишем функцию, которая находит максимум из двух чисел. Это классика программирования!

🔢 Функция max

int max(int x, int y) {
    if (x > y)
        return x;
    else
        return y;
}

Как использовать?

#include <stdio.h>

int max(int x, int y) {
    if (x > y)
        return x;
    else
        return y;
}

int main() {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    printf("MAX = %d\n", max(max(a, b), max(c, d)));
    return 0;
}

✨ Магия вложенных вызовов

Смотри, как удобно: функцию max можно вкладывать друг в друга! Сначала находим максимум из a и b, потом из c и d, а затем максимум из этих двух результатов. Три строчки кода вместо кучи if-ов!

Пример 2: НОД — алгоритм Евклида

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

Функция обрабатывает данные и возвращает результат

Функция принимает данные, обрабатывает их и возвращает результат

📝 Код функции

int nod(int a, int b) {
    while (a != b) {
        if (a > b)
            a = a - b;
        else
            b = b - a;
    }
    return a;
}

🎯 Что здесь происходит?

  • a и b — числа для НОД
  • Цикл while работает, пока числа не равны
  • Уменьшаем большее число на меньшее
  • Возвращаем результат через return

🚀 Как вызвать функцию?

int result = nod(36, 15);  // result = 3
printf("НОД = %d\n", result);

// или короче:
printf("НОД = %d\n", nod(36, 15));

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

Задача: пользователь вводит число k, а программа выводит НОД для каждой пары соседних чисел из последовательности от 1 до k.

💻 Полная программа

#include <stdio.h>

int nod(int a, int b) {
    while (a != b) {
        if (a > b)
            a = a - b;
        else
            b = b - a;
    }
    return a;
}

int main() {
    int i, k, x, y;
    
    printf("Введите k: ");
    scanf("%d", &k);
    scanf("%d", &x);
    
    for (i = 2; i <= k; i++) {
        scanf("%d", &y);
        x = nod(x, y);  // записываем результат обратно в x
    }
    
    printf("НОД = %d\n", x);
    return 0;
}

🔑 Ключевая мысль

Функцию nod мы написали один раз, а используем внутри цикла много раз! Вот в чём сила функций — не нужно повторять один и тот же код.

Пример 4: Простые делители

Эта программа выводит все простые делители числа. Функция ppd находит наименьший простой делитель.

📝 Код программы

#include <stdio.h>

int ppd(int n) {
    int d = 2;
    while (n % d > 0)
        d = d + 1;
    return d;
}

int main() {
    int a, p;
    
    printf("a = ");
    scanf("%d", &a);
    
    while (a > 1) {
        p = ppd(a);
        printf("%d ", p);
        a = a / p;
    }
    printf("\n");
    
    return 0;
}

🔍 Как это работает?

  1. Вводим число a (например, 120)
  2. Функция находит наименьший делитель (2)
  3. Выводим его и делим a на него
  4. Повторяем, пока число не станет 1

Результат для 120: 2 2 2 3 5
(потому что 120 = 2³ × 3 × 5)

Функции типа void

Иногда нам не нужен результат — мы просто хотим, чтобы функция что-то сделала: вывела текст, нарисовала фигуру, проверила условие. Для таких случаев используется тип void (пустота).

Функции void выполняют действия без возврата значения

Функции void выполняют действия, но не возвращают результат — как кнопка, которая что-то делает

💡 Определение

Функция типа void — это функция, которая выполняет действия, но не возвращает значение.

📊 Пример: Таблица умножения

void printTable(int n) {
    int i;
    printf("\nТаблица для %d:\n", n);
    for (i = 1; i <= 10; i++) {
        printf("%d x %d = %d\n", 
               n, i, n * i);
    }
}

int main() {
    int num;
    printf("Введите число: ");
    scanf("%d", &num);
    printTable(num);
    return 0;
}

📋 Пример: Меню программы

void showMenu() {
    printf("\n===== МЕНЮ =====\n");
    printf("1. Найти НОД\n");
    printf("2. Найти максимум\n");
    printf("3. Простые делители\n");
    printf("0. Выход\n");
    printf("================\n");
    printf("Ваш выбор: ");
}

int main() {
    int choice;
    showMenu();
    scanf("%d", &choice);
    // обработка выбора...
    return 0;
}

🎯 Обрати внимание

Функция printTable имеет тип void — она ничего не возвращает, просто выводит таблицу на экран. Внутри неё НЕТ оператора return (или он пустой: return;).

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

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

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

Рекурсия — функция, которая решает задачу, вызывая сама себя для более простых случаев

🐰 История о кроликах Фибоначчи

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

Правило последовательности:

  • f(1) = 1 (январь — одна пара)
  • f(2) = 1 (февраль — они ещё маленькие)
  • f(3) = 2 (март — появился первый приплод)
  • f(n) = f(n-1) + f(n-2) для всех остальных

💻 Рекурсивная функция Фибоначчи

int fib(int n) {
    if (n == 1 || n == 2)
        return 1;
    else
        return fib(n - 1) + fib(n - 2);
}

Полная программа:

#include <stdio.h>

int fib(int n) {
    if (n == 1 || n == 2)
        return 1;
    else
        return fib(n - 1) + fib(n - 2);
}

int main() {
    int i;
    printf("Последовательность Фибоначчи:\n");
    for (i = 1; i <= 12; i++) {
        printf("f(%d) = %d\n", i, fib(i));
    }
    return 0;
}

🤔 Как это работает?

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

Факториал через рекурсию

Факториал числа n (обозначается n!) — это произведение всех чисел от 1 до n. Например: 5! = 1 · 2 · 3 · 4 · 5 = 120

📐 Рекурсивное определение

  • 1! = 1 (базовый случай)
  • n! = n · (n-1)! (рекурсивный случай)

Код функции:

long long factorial(int n) {
    if (n <= 1)
        return 1;
    else
        return n * factorial(n - 1);
}

🔄 Как работает factorial(5)?

factorial(5)
= 5 * factorial(4)
= 5 * 4 * factorial(3)
= 5 * 4 * 3 * factorial(2)
= 5 * 4 * 3 * 2 * factorial(1)
= 5 * 4 * 3 * 2 * 1
= 120

Функция "спускается" до базового случая (1), а потом "поднимается" обратно, перемножая числа!

Прототипы функций

В C есть одна особенность: компилятор читает код сверху вниз. Если ты вызываешь функцию раньше, чем она определена, компилятор не знает, что это такое!

❌ Проблема

#include <stdio.h>

int main() {
    printf("MAX = %d\n", max(5, 8));  // Ошибка!
    return 0;
}

int max(int x, int y) {
    return (x > y) ? x : y;
}

Компилятор не знает про функцию max в момент её вызова!

✅ Решение 1: Функция ДО main()

#include <stdio.h>

int max(int x, int y) {
    return (x > y) ? x : y;
}

int main() {
    printf("MAX = %d\n", max(5, 8));
    return 0;
}

✅ Решение 2: Прототип

#include <stdio.h>

// Прототип функции
int max(int x, int y);

int main() {
    printf("MAX = %d\n", max(5, 8));
    return 0;
}

// Определение функции
int max(int x, int y) {
    return (x > y) ? x : y;
}

💡 Что такое прототип?

Прототип функции — это как анонс "скоро будет такая функция". Прототипы обычно пишут в начале файла. Это позволяет располагать функции в любом порядке!

Возведение в степень — практика

Напишем функцию для возведения числа в степень — полезный инструмент для многих задач!

🔢 Функция power

double power(double x, int n) {
    int i;
    double result = 1.0;
    
    for (i = 0; i < n; i++) {
        result = result * x;
    }
    
    return result;
}

🚀 Пример использования

#include <stdio.h>

double power(double x, int n) {
    int i;
    double result = 1.0;
    for (i = 0; i < n; i++) {
        result = result * x;
    }
    return result;
}

int main() {
    double x;
    int n;
    
    printf("Введите x и n: ");
    scanf("%lf %d", &x, &n);
    
    // Вычисляем s = x^3 + x^5 + x^n
    double s = power(x, 3) + power(x, 5) + power(x, n);
    
    printf("Результат: %.2f\n", s);
    return 0;
}

📌 Самое главное

Давайте подведём итоги нашего путешествия в мир функций на языке C:

Функции помогают избежать повторения кода и делают программу понятнее
Функции с return вычисляют и возвращают значение указанного типа
Функции void выполняют действия, но не возвращают значение
Параметры функций передаются по значению — функция работает с копией
Рекурсия — функция вызывает саму себя для решения задачи
Прототипы нужны, чтобы компилятор знал о функции до её использования

🤔 Проверь себя

Проверьте, как хорошо вы усвоили материал о функциях в C!

1. Зачем вообще нужны функции? Как они упрощают разработку программ?

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

2. В чём разница между функцией типа void и функцией с return?

Подумай:

  • Когда нужна каждая из них?
  • Можно ли использовать результат функции void в выражении?
  • Приведи примеры из жизни
3. Задачка на смекалку: функция countDigits

Напиши функцию countDigits, которая считает количество цифр в целом числе. Например, для числа 2025 она должна вернуть 4.

int countDigits(int n) {
    // твой код здесь
}

Подсказка: используй цикл и деление на 10.

4. Усложняем: функция sumDigits

Напиши функцию sumDigits, которая вычисляет сумму цифр числа. Например, для 2025 результат: 2 + 0 + 2 + 5 = 9.

int sumDigits(int n) {
    // твой код здесь
}
5. НОК и НОД: связь двух понятий

Как связаны НОК (наименьшее общее кратное) и НОД (наибольший общий делитель) двух чисел?

Формула: НОК(a, b) = (a · b) / НОД(a, b)

Напиши функцию для вычисления НОК, используя функцию nod:

int nok(int a, int b) {
    return (a * b) / nod(a, b);
}

Протестируй её на числах: 36, 54, 18 и 15.

6. Проверка на простоту

Напиши функцию isPrime, которая проверяет, является ли число простым (делится только на 1 и на себя).

Функция должна возвращать 1 (истина), если число простое, и 0 (ложь) — если нет.

int isPrime(int n) {
    // твой код здесь
    // проверь делители от 2 до n-1
}
7. Факториалы: суммирование

Напиши программу для вычисления выражения:

s = 1! + 2! + 3! + ... + n!

где n! (факториал) = 1 · 2 · 3 · ... · n

Используй функцию factorial из примеров.

8. Степени: вычисление суммы

Напиши программу для вычисления выражения s = x³ + x⁵ + xⁿ, где x и n вводятся с клавиатуры.

Используй функцию power для возведения в степень.

9. Геометрия в коде: расстояние между точками

Напиши функцию, которая вычисляет длину отрезка по координатам его концов (x1, y1) и (x2, y2).

Формула: d = √((x2-x1)² + (y2-y1)²)

#include <math.h>

double distance(double x1, double y1, 
                double x2, double y2) {
    // твой код здесь
    // используй функцию sqrt()
}

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

10. Задача со звёздочкой ⭐: минимум из трёх

Напиши функцию minOfThree, которая находит минимум из трёх чисел.

Можешь использовать вложенные вызовы функции min (которая находит минимум из двух чисел), по аналогии с примером максимума из четырёх чисел.

int min(int x, int y) {
    return (x < y) ? x : y;
}

int minOfThree(int a, int b, int c) {
    // используй функцию min
}
11. Что такое прототип функции и зачем он нужен?

Объясни своими словами:

  • Почему компилятор C может не знать о функции?
  • Как прототип решает эту проблему?
  • Где обычно размещают прототипы?
12. Объясни рекурсию простыми словами

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

Обязательно упомяни:

  • Что такое базовый случай?
  • Почему рекурсия не работает бесконечно?
  • В чём преимущество рекурсивного подхода?
13. Чем отличаются параметры-значения от параметров-переменных?

Подумай: В нашем материале мы использовали только передачу по значению. Как ты думаешь, почему?

Подсказка: Это проще для понимания на начальном этапе. Позже ты узнаешь об указателях!

🎯 Практические задания

Попробуй применить полученные знания на практике! Эти задания помогут закрепить материал.

✍️ Задание 1: Простая функция

Напиши функцию isEven, которая проверяет, является ли число чётным.

int isEven(int n) {
    // вернуть 1, если чётное
    // вернуть 0, если нечётное
}

Подсказка: используй оператор остатка от деления %

🔢 Задание 2: Возведение в квадрат

Напиши функцию square, которая возводит число в квадрат.

int square(int x) {
    // твой код
}

Используй её для вычисления суммы квадратов чисел от 1 до 10.

📊 Задание 3: Таблица степеней

Напиши программу, которая выводит таблицу степеней числа 2 от 2⁰ до 2¹⁰.

Используй функцию power из примеров или напиши свою.

Ожидаемый вывод:

2^0 = 1
2^1 = 2
2^2 = 4
...
2^10 = 1024

🎲 Задание 4: НОД трёх чисел

Напиши программу для нахождения НОД трёх чисел.

Подсказка: НОД(a, b, c) = НОД(НОД(a, b), c)

Используй функцию nod из примеров.

🔄 Задание 5: Переворот числа

Напиши функцию reverse, которая переворачивает цифры числа.

Пример: reverse(1234) должна вернуть 4321

int reverse(int n) {
    // используй цикл и операции % и /
}

⭐ Задание 6: Числа Фибоначчи без рекурсии

Напиши функцию для вычисления n-го числа Фибоначчи БЕЗ использования рекурсии (через цикл).

int fibLoop(int n) {
    // используй цикл for
    // храни два предыдущих значения
}

Сравни скорость работы с рекурсивной версией для больших n (например, n=40).

💡 Творческое задание

Придумай свой пример! Какую функцию ты бы написал для своего проекта?

🎮 Идеи для вдохновения

Для игры:

  • Функция проверки столкновения объектов
  • Функция подсчёта очков
  • Функция генерации случайного числа в диапазоне
  • Функция проверки победы

Для калькулятора:

  • Функция вычисления процента от числа
  • Функция конвертации температур
  • Функция вычисления площади фигур
  • Функция решения квадратного уравнения

📝 План описания твоей функции:

  1. Название: как ты назовёшь свою функцию?
  2. Что делает: опиши своими словами
  3. Параметры: какие данные принимает?
  4. Возвращаемое значение: что она возвращает? (или это void?)
  5. Пример использования: как бы ты её вызвал?

🔍 Дополнительно: интересные факты

Несколько любопытных фактов о функциях в программировании!

📚 История

Концепция функций (или подпрограмм) появилась ещё в 1940-х годах! Это одна из самых старых и важных идей в программировании.

🚀 Оптимизация

Современные компиляторы могут "встраивать" маленькие функции прямо в код, чтобы программа работала быстрее. Это называется inline-оптимизация.

🌐 Универсальность

Концепция функций есть почти во всех языках программирования: C, Python, JavaScript, Java и многих других!

🎯 Совет профессионала

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

Теперь ты знаешь всё о функциях в C!

Теперь ты знаешь всё о функциях в C и можешь писать профессиональный код!

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

В следующих уроках мы узнаем о массивах, строках и указателях — инструментах, которые сделают твои программы ещё мощнее!

Информатика — твой билет в цифровое будущее