Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
51
Добавлен:
16.02.2016
Размер:
1.18 Mб
Скачать

Встраиваемые (inline-) функции

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

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

#include <iostream.h>

// Прототип встраиваемой функции: inline int Sum(int, int);

int main()

{

int A=2, B=6, C=3; char eol = '\n';

// Вызовы встраиваемой функции, // генерируют вее тело функции

cout « Sum(А, В) « eol;

cout « Sum(В, С) « eol;

cout « Sum(A, С) « eol;

return 0;

}

int Sum(int x, int y)

{

return x + y;

}

В приведенном примере в каждом месте вызова функции Sum () будет сгенерирован код тела всей функции.

Рекурсивные функции

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

  • простой - если функция в теле содержит вызов самой себя;

  • косвенной - если функция вызывает другую функцию, а та в свою очередь вызывает первую.

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

Рис. 4.3. Рекурсивный вызов

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

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

#include <iostream.h>

int main ()

{

int count = 1; long int result =1;

while(count && count <31)

{

cout « "Введите целое число: ";

cin » count;

for(int i=count; i>l; i--)

{

result *= i;

}

cout « result « '\n'; result = 1;

}

return 0;

}

Ту же задачу можно решить более элегантно, применив рекурсию:

#include <iostream.h>

long int fact(long);

int main 0

{

int count = 1;

while(count && count <31)

{

cout « "Введите целое число: ";

cin » count;

cout « fact(count) « '\n';

}

return 0;

}

long int fact(long x)

{

if(x=0 || x=l) return 1;

return x * fact(x-l);

}

Как видно, тело функции main () во втором примере максимально упростилось и занимается фактически вводом значения и выводом результата, в то время как все вычисления возложены на единственную содержательную строку в рекурсивной функции fact().

Соседние файлы в папке ЯзыкС++Глушаков