ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4277
Скачиваний: 28
Г Л А В А
11
Дополнение
к функциям языка C
11.1. Передача аргументов
по умолчанию
В языке программирования С++ в прототипе функции или в оп-
ределении функции, если оно используется как прототип, можно
указать значения, которые задаются параметрам по умолчанию.
В этом случае, если при вызове функции некоторые или все ар-
гументы пропущены, то компилятор подставит вместо них значе-
ния, заданные по умолчанию. Если некоторый параметр имеет
значение по умолчанию, то значения по умолчанию должны так-
же иметь все параметры, которые расположены после него. Соот-
ветственно, если при вызове функции аргумент опускается, то
должны быть опущены и все аргументы после него.
В листинге 11.1 приведен пример передачи в функцию аргумен-
тов по умолчанию.
Листинг 11.1 Передача аргументов по умолчанию
#include <iostream>
using namespace std;
void print(int i, int j = 1, int k = 2)
{
cout << i << ' ' << j << ' ' << k << endl;
}
Глава 11. Дополнение к функциям языка C
147
int main()
{
print(0); // печатает 0 1 2
print(1, 3); // печатает 1 3 2
return 0;
}
11.2. Встроенные функции
Функция называется
встроенной
, если компилятор генерирует не
вызов этой функции, а встраивает ее код в тело программы. Для
определения встроенной функции используется ключевое слово
inline
, которое записывается перед именем функции или типом
возвращаемого функцией значения.
В листинге 11.2 приведен пример определения встроенной функ-
ции.
Листинг 11.2. Определение встроенной функции
#include <iostream>
using namespace std;
inline double cube(double x) { return (x * x * x); }
int main( )
{
double x = 1.1;
cout << "x^3 = " << cube(x) << endl; // x^3 = 1.331
return 0;
}
Ключевое слово
inline
рассматривается компилятором только
как пожелание встроить код функции в программу. Компилятор
может и не выполнить это пожелание. Это обычно происходит в
следующих двух случаях:
функция является рекурсивной;
функция вызывается только через указатель в данном исход-
ном файле.
Часть II. Язык программирования С++
148
Встроенная функция должна быть видна компилятору в месте ее
вызова, т. е. компилятор выполняет внутреннее связывание встро-
енных функций. Поэтому, в отличие от обычной функции, встро-
енная функция должна быть определена в каждом исходном фай-
ле, где есть обращение к ней. Причем эти определения должны
совпадать. Обычно для упрощения реализации определение
встроенной функции помещают в заголовочный файл, а затем
включают этот файл во все исходные файлы, где есть обращение
к встроенной функции.
11.3. Передача аргументов
и возврат значения через ссылки
В языке программирования С++ значения параметров могут пе-
редаваться функции через ссылки. Так как ссылка является псев-
донимом переменной, то вызов такой функции синтаксически не
отличается от вызова функции, аргументы которой передаются
по значению.
В листинге 11.3 приведен пример передачи аргументов через
ссылки.
Листинг 11.3. Передача аргументов через ссылки
#include <iostream>
using namespace std;
void swap(int& x, int& y)
{
int t;
t = x;
x = y;
y = t;
}
int main()
{
int a = 1, b = 2;
Глава 11. Дополнение к функциям языка C
149
cout << a << ' ' << b << endl; // печатает 1 2
swap(a, b);
cout << a << ' ' << b << endl; // печатает 2 1
return 0;
}
Ссылку можно использовать как тип возвращаемого функцией
значения. Это позволяет присваивать функции значения. Так как
ссылка является
псевдопеременной
, то возврат ссылки синтакси-
чески не отличается от возврата по значению.
В листинге 11.4 приведен пример возвращения значения функции
через ссылку.
Листинг 11.4. Возврат значения через ссылку
#include <iostream>
using namespace std;
int& item(int* a, int i) { return a[i]; }
int main()
{
int a[] = {1, 2, 3};
cout << a[1] << endl; // печатает 2
item(a, 1) = 15;
cout << a[1] << endl; // печатает 15
return 0;
}
Однако в этом случае нельзя допустить ошибку, когда ссылка
возвращается на объект, определенный в теле функции. Этот
объект является локальным и после выхода из функции он унич-
тожается. Поэтому такая ссылка будет ссылаться на неопреде-
ленное значение.
11.4. Перегрузка функций
Перегрузкой функций
называется объявление в одной области
видимости нескольких функций с одинаковым именем, но раз-
Часть II. Язык программирования С++
150
ными сигнатурами.
Сигнатурой функции
называется список ти-
пов ее параметров. На перегрузку функций накладываются сле-
дующие ограничения. Нельзя перегружать функции:
которые отличаются только возвращаемым значением, т. к.
в этом случае компилятор не знает, какую из них использовать
при вызове, если для возвращаемого значения требуется пре-
образование типов;
параметры которых отличаются только использованием ква-
лификаторов
const
и
volatile
;
параметры которых отличаются только тем, что переопреде-
лены при помощи объявления
typedef
;
параметры которых отличаются только тем, что один из них
массив, а второй указатель на тип, который соответствует типу
элементов массива;
параметры которых отличаются только значениями, заданны-
ми по умолчанию.
Например, в языке программирования C++ в одной программе
можно определить следующие функции:
int neg(int n) { return -n; }
float neg(float f) { return -f; }
Возможность перегрузки функций упрощает выбор имен для
функций, которые имеют схожую функциональность для разных
типов параметров.
В случае вызова одной из перегруженных функций, компилятор
выбирает нужную функцию по лучшему соответствию типов ар-
гументов типам параметров. Выбор такой функции разбивается
на три этапа, которые и описаны ниже.
На первом этапе строится множество
функций кандидатов
(candidate functions), т. е. таких функций, имя которых совпадает
с именем вызываемой функции.
На втором этапе из множества функций кандидатов выбираются
осуществимые функции
(viable functions), т. е. такие функции,
у которых количество параметров равно количеству аргументов
в вызываемой функции.