Чтение онлайн

ЖАНРЫ

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

34: cout << "doubledLong: " << doubledLong << "\n";

35: cout << "doubledFloat: " << doubledFloat << "\n";

36: cout << "doubledDouble: " << doubledDouble << "\n";

37:

38: return 0;

39: }

40:

41: int Double(int original)

42: {

43: cout << "In Double(int)\n";

44: return 2 * original;

45: }

46:

47: long Double(long original)

48: {

49: cout << "In Double(long)\n";

50: return 2 * original;

51: }

52:

53: float Double(float original)

54: {

55: cout << "In Double(float)\n";

56: return 2 * original;

57: }

58:

59: double Double(double original)

60: {

61: cout << "In Double(double)\n";

62: return 2 * original;

63: }

Результат:

myInt: 6500

myLong: 65000

myFloat: 6.5

myDouble: 6.5e+20

In Double(int)

In Double(long)

In Double(float)

In Double(double)

DoubledInt: 13000

DoubledLong 130000

DoubledFLoat: 13

DoubledDouble: 1.3e+21

Анализ:

Функция Double перегружается для приема параметров четырех типов: int, long, float и double. Прототипы функций занимают строки 6—9, а определения — строки 41-63.

В теле основной программы объявляется восемь локальных переменных. В строках 13-16 инициализируются первые четыре переменные, а в строках 28-31 остальным четырем переменным присваиваются результаты передачи значений первых четырех переменных функции Double. Обратите внимание, что по виду вызова эти функции ничем не отличаются друг от друга. Но удивительное дело: вы передаете аргумент — и вызывается нужная функция!

Дело в том, что компилятор определяет тип переданного аргумента, на основании которого выбирает соответствующий вариант функции Double. А результаты работы этой программы подтверждают ожидаемую очередность вызова вариантов этой перегруженной функции.

Дополнительные сведения о функциях

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

Подставляемые inline-функции

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

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

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

Если функция объявлена с ключевым словом inline (т.е. подставляемая), компилятор не создает функцию в памяти компьютера, а копирует ее строки непосредственно в код программы по месту вызова. Это равносильно вписыванию в программе соответствующих блоков вместо вызовов функций.

Обратите внимание, что использование подставляемых функций чревато и некоторыми издержками. Если функция вызывается 10 раз, то во время компиляции в программу будет вставлено 10 копий этой функции. За увеличение скорости выполнения программы нужно будет расплатиться размерами программного кода, в результате чего ожидаемого повышения эффективности программы может и не произойти.

Так какой же напрашивается вывод? Если в программе часто вызывается маленькая функция, состоящая из одной-двух строк, то это первый кандидат в подставляемые функции. Но если функция велика, то лучше воздержаться от ее многократного копирования в программе. Использование подставляемой функции демонстрируется в листинге 5.9.

Листинг 5.3. Использование подставляемых inline-функций

1: // Листинг 5.9. Подставляемые inline-функции

2:

3: <<include <iostгеагп.h>

4:

5: inline mt Double(int);

6:

7: int main

8: {

9: int target;

10:

11: cout << "Enter а number to work with:

12: cin >> target;

13: cout << "\n";

14:

15: target = Double(target);

16: cout << "Target: " << target << endl.

17:

18: target = Double(target):

19: coul << "Target: " << target << endl;

20:

21:

22: target = Double(target):

23: cout << "Target: " << target << endl;

24: return 0;

25: }

26:

27: int Double(int target)

28: {

29: return 2'target;

20: }

Результат:

Enter a number to work with: 20

Target: 40

Target: 80

Target: 160

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

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

target = 2 * target;

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

target = Double(target);

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

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

Рекурсия

Поделиться с друзьями: