- •Базовые понятия информатики. Понятие «Информатика» и «Информация»
- •Информация
- •Информационные технологии
- •Понятие алгоритма. Свойства и классы алгоритмов. Формы представления алгоритмов
- •Понятие алгоритма. Базовые алгоритмические структуры
- •Представление данных в памяти персонального компьютера.
- •Принципы обработки программных кодов
- •Компиляторы
- •Интерпретатор
- •Язык с. История развития. Основные свойства языка
- •Отличительные особенности языкаC
- •Элементы языка c
- •Константы
- •Базовые типы данных
- •Директива #include
- •Использование void
- •Инструкция return
- •Описание переменных
- •Обработка данных. Операторы
- •Арифметические операторы
- •Приоритет операторов и порядок вычислений
- •Используемые алгоритмы обработки данных
- •Аккумуляторы
- •Преобразования типов данных
- •Декларации и дефиниции функций
- •Формальные и фактические параметры. Вызов функций
- •Возврат функцией значений
- •Переменные в функциях
- •Автоматические (локальные) переменные
- •Внешние (глобальные) переменные
- •Статические переменные
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Значения параметров по умолчанию
- •Перегрузка функций
- •Рекурсия
- •Встроенные функции
- •Обработка символьных данных
- •Функция puts()
- •Функция putchar()
- •Функция printf()
- •Выбор правильных средств вывода информации
- •Функция gets()
- •Функция getchar()
- •Функция scanf()
- •Выбор соответствующих средств ввода данных
- •Управляющие структуры Структуры выбора (if / else)
- •Структуры выбора (switch/case/default)
- •Структуры повторения (циклы)
- •Использование цикла for
- •Использование цикла do...While (постусловие)
- •Использование цикла while (предусловие)
- •Операторы передачи управления Оператор безусловного перехода goto
- •Оператор break
- •Оператор continue
- •Препроцессор языка Си
- •Массивы Объявление переменной массива
- •Использование индексной переменной
- •Инициализация массива при объявлении
- •Передача массивов в функции
- •Использование констант при объявлении массивов
- •Символьные строки
- •Массивы строк
- •Алгоритмы сортировки массива
- •Поиск заданного элемента в массиве
- •Указатели
- •Объявление указателя
- •Указатели на массивы
- •Операции над указателями
- •Указатели на строку
- •Указатели на функцию
- •Функции, возвращающие указатель
- •Указатели на многомерные массивы
- •Массивы указателей
- •Динамическое распределение памяти
- •Структуры данных
- •Реализация одних структур на базе других
- •Очередь
- •Операции над очередями
- •Операции над стеками
- •Ссылочные реализации структур данных
- •Операции над списками
Рекурсия
Как известно, в языке Си программу можно разбить на мелкие части, представляющие собой функции. При использовании функций программа становится более понятной, более легкой для программирования и отладки. Кроме того, функции, созданные для одной программы, часто пригодны для использования в другой. При выполнении программы одна функция может вызывать другую, которая, в свою очередь, вызывает третью и т.д.
Рекурсивной функцией называется функция, которая для выполнения определенной операции вызывает саму себя. Процесс вызова функцией самой себя называется рекурсией. По мере возрастания сложности программ и функций может оказаться, что при определении некоторых операций удобно использовать сами эти операции. В таких случаях имеет смысл создавать рекурсивные функции. Классическим примером рекурсивной обработки является вычисление факториала. Факториал значения 1 равен 1. Факториал значения 2 равен 2*1. Факториал значения 3 равен 3*2*1. Аналогично, факториал значения 4 равен 4*3*2*1. Этот процесс может быть продолжен до бесконечности. Если внимательно приглядеться к процессу вычисления факториала, то можно увидеть, что факториал, например, от 4 равен 4-кратному значению факториала от 3 (3*2*1). Аналогично, факториал от 3 равен 3-кратному значению факториала от 2 (2*1). Факториал от 2 равен двукратному значению факториала от 1 (1). В таблице демонстрируется вычисление факториала.
Таблица. Вычисление факториала
Значение |
Вычисление |
Результат |
Факториал |
1 |
1 |
1 |
1 |
2 |
2*1 |
2 |
2*Factorial(l) |
3 |
3*2*1 |
6 |
3* Factorial(2) |
4 |
4*3*2*1 |
24 |
4* Factorial(3) |
5 |
5*4*3*2*1 |
120 |
5* Factorial(4) |
В следующей программе представлена рекурсивная функция factorial, которая используется для вычисления факториала значений от 1 до 5:
#include <stdio.h>
int factorial (int value)
{
if (value ==1)
return(1);
else
return(value * factorial(value-1));
}
void main(void)
{
int i;
for (i =1; i <= 5; i++)
printf("Факториал от %d равен %d\n", i, factorial(i));
}
Как можно видеть, функция factorial возвращает значение, которое основывается на результате вызова самой этой функции.
При выполнении этой функции первым делом осуществляется проверка значения параметра на равенство 1. Если значение равно 1, то функция возвращает 1. В противном случае, в качестве результата возвращается значение, равное произведению значения входного параметра и факториала от числа, равного значению параметра минус 1. Например, предположим, что функция вызывается со значением 3. Тогда в качестве результата функцией будет возвращено 3*factorial(3-1). Обнаруживая в операторе return вызов функции factorial, компилятор организует повторный вызов, на этот раз со значением 3-1 или 2. Поскольку значение не равно 1, результатом выполнения функции будет 2*factorial(2-1). Наконец, при следующем вызове функции значение параметра равно 1, поэтому в качестве результата вызвавшей программе (функции) возвращается значение 1.
Рекурсивная функция чем-то похожа на конструкцию цикла в том, что в обоих случаях должно быть задано условие завершения. Если это не сделано, то функция никогда не завершится. Для рассмотренной функции вычисления факториала условием завершения является факториал от 1, который по определению равен 1.
Когда для реализации некоторой задачи функция обращается к самой себе, говорят, что она выполняет прямую рекурсию. Изучив несколько примеров рекурсивных функций, можно разобраться и в большинстве других, использующих прямую рекурсию. Более сложная форма рекурсии, косвенная рекурсия, образуется, когда некоторая функция (функция А) вызывает другую функцию (функцию В), которая в свою очередь вызывает первую функцию (функцию А). Поскольку косвенная рекурсия имеет более сложный код для понимания, следует по возможности избегать использования такого вида рекурсии.