Программирование >>  Дополнительные возможности наследования 

1 ... 32 33 34 [ 35 ] 36 37 38 ... 265


17 18 19 20 21 22 23 24 25 26 27 28 29 30

cout << Target: << target << endl;

target = Double(target);

cout << Target: target << endl;

target = Double(target); cout Target: target endl; return 0;

int Double(int target) {

return 2*target;

Enter a number to work with: 20 40

Target Target Target

В строке 5 объявляется подставляемая функция DoubleO, принимающая параметр типа int и возвращающая значение типа int. Это объявление подобно любому другому прототипу за исключением того, что прямо перед типом возвращаемого значения стоит ключевое слово inline.

Результат компиляции этого прототипа равносилен замене в профамме сфоки

target = 2 * target;

вызовом функции DoubleO:

target = Double(target);

К моменту выполнения программы копии функции уже расставлены по своим местам и профамма готова к выполнению без частых переходов к функции и обратно.

(ПМЧАНИЕ

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

Рекурсия

Функция может вызывать самое себя. Это называется рекурсией, которая может быть прямой или косвенной. Когда функция вызывает самое себя, речь идет о прямой рекурсии. Если же функция вызывает другую функцию, которая затем вызывает первую, то в этом случае имеет место косвенная рекурсия.

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



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

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

Чтобы показать пример решение проблемы с помощью рекурсии, рассмотрим ряд Фибоначчи:

1,1,2,3,5,8,13,21,34 ,

Каждое число ряда (после второго) представляет собой сумму двух стоящих впереди чисел. Задача может состоять в том, чтобы, например, определить 12-й член ряда Фибоначчи.

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

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

При этом используется следующий алгоритм:

1. Предлагаем пользователю указать, какой член в ряду Фибоначчи следует рассчитать.

2. Вызываем функцию fib(), передавая в качестве аргумента порядковый номер члена ряда Фибоначчи, заданный пользователем.

3. В функции fib() выполняется анализ аргумента (п). Если п < 3, функция возвращает значение 1; в противном случае функция fib() вызывает самое себя (рекурсивно), передавая в качестве аргумента значение п-2, затем снова вызывает самое себя, передавая в качестве аргумента значение п-1, а после этого возвращает сумму.

Если вызвать функцию fib(l), она возвратит 1. Если вызвать функцию fib(2), она также возвратит 1. Если вызвать функцию fib(3), она возвратит сумму значений, возвращаемых функциями fib(2) и fib(l). Поскольку вызов функции fib(2) возвращает значение 1 и вызов функции fib(1) возвращает значение 1,то функция fib(3) возвратит значение 2.

Если вызвать функцию fib(4), она возвратит сумму значений, возвращаемых функциями fib(3) и fib(2). Мы уже установили, что функция fib(3) возвращает значение 2 (путем вызова функций fib(2) и fib(1)) и что функция fib(2) возвращает значение 1, поэтому функция fib(4) просуммирует эти числа и возвратит значение 3, которое будет являться четвертым членом ряда Фибоначчи.

Сделаем еще один шаг. Если вызвать функцию fib(5), она вернет сумму значений, возвращаемых функциями fib(4) и fib(3). Как мы установили, функция fib(4) возвращает значение 3, а функция fib(3) - значение 2, поэтому возвращаемая сумма будет равна числу 5.



Описанный метод - не самый эффективный способ решения этой задачи (при вызове функции flb(20) функция fib() вызывается 13 529 раз!), тем не менее он работает. Однако будьте осторож.1Ы. Если задатв слишком большой номер члена ряда Фибоначчи, вам может не хватить памяти. При каждом вызове функции tib() резервируется некоторая область памяти. При возвращении из функции память освобождается. Но при рекурсивных вызовах резервируются все новые области памяти, а при таком подходе системная память может исчерпаться довольно быстро. Реализация функции fibO показана в листинге 5.10.


предуореждение

При запуске программы, представленной в листинге 5,10, задавайте небольшие номера членов ряда Фибоначчи (меньше 15), Поскольку в этой программе используется рекурсия, возможны большие затраты памяти.

Лисшина 5.18. Пример иснодьзования рекурсии дня нахожевния члена ряда ШиОоначчн

ftinclude <iostream.h> int fib (int n);

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

int mainO {

int n, answer;

cout Enter number to find: ; 10: cin n; cout << \ n\ n ; answer = fib(n);

cout answer is the << n th Fibonacci number\ n ; 17: return 0;

int fib (int n) {

cout Processing fib( << n ),.. ; 23:

if (n < 3 )

cout Return 1!\ n ; return (1);

else {

cout << Call fib( << n-2 << ) and fib( n-1 << ),\ n ; return( fib(n-2) + fib(n-l));



1 ... 32 33 34 [ 35 ] 36 37 38 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика