- •Функции, часть 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-
- •Неоднозначность может быть также вызвана использованием в перегруженных функциях аргументов, передаваемых по умолчанию.
Вот как выглядят результаты выполнения этой программы.
100
100
99.1
#include <iostream> using namespace std; double &change_it(int i);
// Функция возвращает ссылку.
double vals[] = {1.1, 2.2, 3.3, 4.4, 5.5}; int main()
{
int i;
cout << "Вот исходные значения: ";
for(i=0; i<5; i++) cout << vals[i] << ' ';
change_it(1) = 5298.23; // Изменяем 2-й элемент.
change_it(3) = -98.8; // Изменяем 4-й элемент.
cout << "Вот измененные значения: ";
for(i=0; i<5; i++)
cout << vals[i] << ' ';
return 0;
}
double &change_it(int i)
{
return vals[i]; // Возвращаем ссылку на i-й элемент.
}
Результаты ее выполнения таковы.
Вот исходные значения:
1.12.2 3.3 4.4 5.5
Вот измененные значения:
1.1 5298.23 3.3 -98.8 5.5
//Здесь ошибка: нельзя возвращать
ссылку
//на локальную переменную.
int &f()
{
int i=10;
return i;
}
Создание ограниченного массива
Путем создания ограниченного, или безопасного, массива выход за его границы можно предотвратить.
При работе с таким массивом любой выходящий за установленные границы индекс не допускается для индексирования массива.
// Простой способ организации безопасного массива. #include <iostream>
using namespace std;
int &put(int i); // Помещаем значение в массив. int get(int i); // Считываем значение из массива. int vals[10];
int error = -1; int main()
{
put(0) = 10; // Помещаем значения в массив
put(1) = 20;
put(9) = 30;
cout << get(0) << ' ';
cout << get(1) << ' ';
cout << get(9) << ' ';
// А теперь специально генерируем ошибку.
put(12) =1; // Индекс за пределами границ массива.
return 0;
}
// Функция занесения значения в массив. int &put(int i)
{
if(i>=0 && i<10)
return vals[i]; // Возвращаем ссылку на i-й
элемент.else {
cout << "Ошибка нарушения границ!\n";
return error; // Возвращаем ссылку на error.
}
}
// Функция считывания значения из массива. int get(int i)
{
if(i>=0 && i<10)
return vals[i]; // Возвращаем значение i-го
элемента.else {
cout << "Ошибка нарушения границ!\n";
return error; // Возвращаем значение переменной error.
Результат, полученный при выполнении этой программы, выглядит так.
10 20 30 Ошибка нарушения границ!
Независимые ссылки
Независимая ссылка — это еще
одно название для переменных
некоторого иного типа.
Независимая ссылка должна указывать на некоторый объект. Ссылке будет присвоен адрес некоторой ранее объявленной переменной. После этого имя такой ссылочной переменной можно применять везде, где
#include <iostream> using namespace std; int main()
{
int j, k;
int &i = j; // независимая ссылка
j = 10;
cout << j << " " << i; // Выводится: 10 10
k = 121;
i = k; // Копирует в переменную j значение переменной k, а не адрес переменной k.
cout << "\n" << j; // Выводится: 121
return 0;
}
При выполнении эта программа выводит
следующие результаты.
10 10
121