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

94

7

 

const int SIZEARR = 100;

// Размер массива

int x[SIZEARR];

// Массив

Далее приведен пример работы программы.

Введите размер массива < 100: 10 Исходный массив:

346, 130, 10982, 1090, 11656, 7117, 17595, 6415, 22948, 31126 Отсортированный массив:

130, 346, 1090, 6415, 7117, 10982, 11656, 17595, 22948, 31126

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

7.7.Рекурсия

Вязыке C++ функции могут быть рекурсивными, то есть вызывать сами себя.

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

Программа 17. Рекурсивная печать целого

//Файл Recurs.cpp #include <iostream.h> #include <conio.h>

//printd: печатает n как целое десятичное число void printd(int n)

{

if(n < 0){

// Если число отрицательное,

cout.put('-');

// печатаем знак числа,

n = -n;

// делаем число положительным

}

 

if(n / 10)

// Если в n более одной цифры,

printd(n / 10);

// печатаем старшие цифры, иначе

cout.put('0' + n % 10);

// выводим последнюю цифру

}

void main()

{

int number;

cout << "\nВведите число: "; cin >> number;

Функции 95

printd(number);

}

Символы цифр ’0’, ’1’, …, ’9’ занимают в кодовой таблице непрерывный участок и расположены в порядке возрастания их значения. Код цифры ’0’ равен 48, у цифры ’1’ код 49 и т.д., поэтому выражение

n % 10 + ’0’ дает правильный код последней десятичной цифры числа n. Например, если n = 321, то n % 10 + '0' = 1 + 48 = 49, что равно коду цифры ’1’, и эту цифру изобразит на экране функция put в соответствии со значением своего аргумента.

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

Полезно выполнить данную программу в пошаговом режиме, наблюдая за работой рекурсивной функции, за значениями формального параметра n и состоянием экрана. Разберем работу функции printd. Пусть для number введено значение 123, то есть первый вызов функции имеет вид printd(123). Работу функции поясняет табл. 27. Углубление в рекурсию, когда функция вызывает сама себя, происходит, пока обрабатываемое число остается многозначным. Последний вызов printd происходит для однозначного числа 1, на экран выводится цифра ’1’ и работа 3-го вызова завершается, после чего управление передается во 2- й вызов на инструкцию:

cout.put(n % 10 + '0');

которая выводит предпоследнюю цифру, затем происходит возврат в 1-й вызов, печатается последняя цифра исходного числа и работа printd завершается.

Таблица 27. Работа рекурсивной функции

967

7.8.Перегруженные имена функций

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

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

Программа 18. Перегрузка функций

//Файл Module.cpp #include <iostream.h> #include <conio.h>

//module: возвращает абсолютную величину целого n int module(int n)

{

if(n < 0) return -n;

return n;

}

//module: возвращает абсолютную величину плавающего x double module(double x)

{

if(x < 0) return -x;

return x;

}

int main()

{

cout << "module(-3.14) = " << module(-3.14f) << "\n"; cout << "module(-3) = " << module(-3) << "\n"; getch();

return 0;

}

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

Функции 97

ищет такую, которая имеет наилучшее соответствие типов формальных и фактических параметров. Программа печатает:

module(-3.14) = 3.14 module(-3) = 3

Это показывает, что для числа с плавающей точкой -3.14f, имеющего тип float, вызывается функция

double module(double x);

а для целого -3 функция int module(int n);

7.9.Аргументы функций по умолчанию

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

Программа 19. Аргументы по умолчанию

Функция печати целого print рекурсивная. Если основание системы счисления base <= 10, используются обычные цифры 0, 1, …, 9. Если base > 10, то в качестве цифр используются заглавные латинские буквы

A, B, C, D, E, F, G, H,… со значениями: 10, 11, 12, 13, 14, 15, 16, 17,… // Файл ArgDeflt.cpp

#include <iostream.h> #include <conio.h>

// print: печать val в системе счисления с основанием base

void print(int val, int base = 10) // 10 – значение для base по умолчанию

{

if(val < 0){ cout.put('-'); print(-val, base);

}

if(val / base > 0) print(val / base, base);

int r = val % base; if(r < 10)

cout.put('0' + r);

//Если число многозначное,

//печатать старшие цифры

//Остаток от деления