- •Функции, часть 2:
- •-Ссылка — это неявный указатель.
- •Два способа передачи аргументов
- •2. При вызове по ссылке функции передается адрес аргумента.
- •void swap(int *х, int *у)
- •Результаты выполнения этой программы
- •Ссылочные параметры
- •При использовании ссылочного параметра функции автоматически передается адрес (а не значение) аргумента.
- •При выполнении этой программы получаем такой результат.
- •Инструкция
- •void swap(int &х, int &у)
- •Присваивая некоторое значение ссылке, вы в действительности присваиваете это значение переменной, на которую
- •Объявление ссылочных параметров
- •Некоторые программисты определяют в таком стиле и указатели, связывая символ "*" с типом,
- •Подобное связывание символа "&" или "*" с типом (а не с переменной) не
- •Возврат ссылок
- •Вот как выглядят результаты выполнения этой программы.
- •Результаты ее выполнения таковы.
- •//Здесь ошибка: нельзя возвращать
- •Создание ограниченного массива
- •// Функция занесения значения в массив. int &put(int i)
- •Результат, полученный при выполнении этой программы, выглядит так.
- •Независимые ссылки
- •Ограничения при использовании ссылок
- •Перегрузка функций
- •void f(int i)
- •При выполнении эта программа генерирует следующие результаты.
- •Чтобы лучше понять выигрыш от перегрузки функций, рассмотрим три функции из стандартной библиотеки:
- •// Создание функций myabs() — перегруженной версии функции abs().
- •int myabs(int i)
- •Результаты выполнения этой программы таковы.
- •Принципиальная значимость перегрузки состоит в том, что она позволяет обращаться к связанным функциям
- •Благодаря полиморфизму программисту нужно помнить не три различных имени, а только одно.
- •Анахронизм в виде ключевого
- •Аргументы, передаваемые функции по умолчанию
- •Чтобы предусмотреть максимально возможное количество ситуаций и обеспечить их корректную обработку, функции часто
- •Аргумент, передаваемый функции по умолчанию, представляет собой
- •При создании функций, имеющих значения аргументов, передаваемых по умолчанию, необходимо помнить, что значения
- •Важно понимать, что все параметры, которые принимают значения по умолчанию, должны быть расположены
- •void mystrcat(char *s1, char *s2, int len);
- •// Применение пользовательской версии функции strcat()
- •// Пользовательская версия функции strcat().
- •Перегрузка функций и неоднозначность
- •Неоднозначность в программе вызвана не перегрузкой функции myfunc(), объявленной дважды для приема double-
- •Неоднозначность может быть также вызвана использованием в перегруженных функциях аргументов, передаваемых по умолчанию.
При выполнении этой программы получаем такой результат.
Старое значение переменной val: 1
Новое значение переменной val: 10
Инструкция
i = 10;
(в данном случае она одна составляет тело функции) не присваивает переменной i значение 10. В действительности значение 10 присваивается переменной, на которую ссылается переменная i (в нашей программе ею является переменная val).
#include <iostream> using namespace std;
// Объявляем функцию swap() с использованием ссылочных параметров.
void swap(int &х, int &у); int main()
{
int i, j;
i = 10; j = 20;
cout << " Исходные значения переменных i и j: ";
cout << i << ' ' << j << '\n';
swap (j, i);
cout << " Значения переменных i и j после обмена: ";
cout << i << ' ' << j << '\n';
return 0;
}
void swap(int &х, int &у)
{
int temp;
temp = x; // Сохраняем значение,
расположенное по адресу х.
х = у; // Помещаем значение, хранимое по
адресу у, в адрес х.
у = temp; // Помещаем значение, которое
раньше хранилось по адресу х, в адрес у.
}
Присваивая некоторое значение ссылке, вы в действительности присваиваете это значение переменной, на которую указывает эта ссылка.
Поэтому, применяя ссылку в качестве аргумента функции, при вызове функции вы в действительности используете такую переменную.
Объявление ссылочных параметров
В изданной в 1986 г. книге Язык программирования C++ (в которой был впервые описан синтаксис C++) Бьерн Страуструп представил стиль объявления ссылочных параметров, одобренный другими программистами.
В соответствии с этим стилем оператор "&" связывается с именем типа, а не с именем переменной. Например, вот как выглядит еще один способ записи прототипа функции swap().
void swap(int& х, int& у);
Некоторые программисты определяют в таком стиле и указатели, связывая символ "*" с типом, а не с переменной, как в этом примере.
float* р;
Подобное связывание символа "&" или "*" с типом (а не с переменной) не распространяется, в соответствии с формальным синтаксисом C++, на весь список переменных, приведенных в объявлении, что может привести к путанице. Например, в следующем объявлении создается один указатель (а не два) на целочисленную переменную.
int* а, b;
Здесь b объявляется как
целочисленная переменная (а не как
Возврат ссылок
Если функция возвращает ссылку, это означает, что она возвращает неявный указатель на значение, передаваемое ею в инструкции
return.
// Возврат ссылки. #include <iostream> using namespace std; double &f();
double val = 100.0; int main()
{
double newval;
cout << f() << '\n'; // Отображаем значение val. newval = f(); // Присваиваем знач. val перем. newval.
cout << newval << '\n'; // Отображаем newval.
f() = 99.1; // Изменяем значение val.
cout << f() << '\n'; // новое значение val.
return 0;
}
double &f()
{
return val; // Возвращаем ссылку на val.
}
