Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
программирование билеты-ответы.doc
Скачиваний:
16
Добавлен:
24.09.2019
Размер:
113.15 Кб
Скачать

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

Способы передачи параметров в функцию

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

Подобный способ передачи параметров по значению имеет следующие ограничения:

Из тела функции нельзя обратиться к какому-либо объекту, если он не является глобальным по отношению к функции или если его имя перекрыто одноимённой локальной переменной.

При передаче больших объектов происходит их копирование и часто память расходуется напрасно.

Для снятия таких ограничений существует возможность передачи параметра по ссылке.

В этих случая в функцию передаётся адрес объекта и, соответственно, работа внутри функции происходит не с копией, а с оригиналом объекта.

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

Пример:

void func1(int val, int& ref) {

val++;

ref++;

}

...

int a = 10, b = 10;

func1(a,b);

cout << a << endl; // 10, значение будет увеличено, но внутри функции, как локальное

cout << b << endl; // 11, будет увеличено значение внешней переменной b

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

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

void decr(const int& n) {

cout << n; // читать можно

n--; // изменять нельзя, тут будет ошибка компиляции

}

В функцию можно передавать и указатели.

void prarr(int* a, const int& n) { // массив не копируется

for(int i = 0; i<n; i++) {

cout << a[i] << ' ';

}

*a = 100; // изменит первый элемент в глобальном массиве

a++; // не вызовет ошибки, ведь указатель не константный

}

...

int a[] = {0, 5, 10, 15, 20};

prarr(a, 5); // 0 5 10 15 20

cout << *a << endl; // 100

a++; // вызовет ошибку

В теле функции указатель a — это локальный объект, но он хранит адрес первого элемента глобального массива после входа в функцию.

Массив можно было передать в функцию и по-другом. Пример прототипа:

void prarr(int a[], const int& n);

При этом указатель a внутри функции не изменит своих свойств (будет локальной переменной, хранящей адрес глобального объекта).

Корректнее параметр, по которому будет передаваться указатель на первый элемент массива, объявлять как константный:

void prarr(int* const a, const int& n);

Тогда внутри функции мы не могли бы сместить указатель на соседний элемент.

Параметры со значениями по умолчанию (необязательные параметры)

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

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

Пример:

int pow(const int& a, const int& p) {

int res = 1;

for(int i = 1; i<=p; i++) {

res = res * a;

}

return res;

}

Перегрузка функций

Уникальность функции определяется не только её именем, но и набором её параметров и типом возвращаемого значения. C++ позволяет создавать функцию с именем ранее существовавшей при условии, что у новой функции будет иной набор параметров.

Пример:

void printarr(int* const a, const int& n) {

for(int i = 0; i<n; i++) cout << a[i] << ' ';

}

void printarr(char* const a) {

cout << a;

}

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

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

Шаблоны функций

Шаблоны — средство языка C++, предназначенное для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например, к типам данных).

Пример:

template <typename T>

void exchange ( T &a, T &b ) {

T t;

t = a;

a = b;

b = t;

}

Теперь вызвать функцию можно так:

int a=5, b=8;

exchange (a,b);

cout << a;

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

double p=3.14, e=2.71;

exchange <double> (p,e);