Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

// копия

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

my_find
, передавая ее аргументы по константной ссылке.

// передача по ссылке: без копирования, доступ только для чтения

int my_find(const vector<string>& vs, const string& s);

8.5.5. Передача параметров по ссылке

А что делать,

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

void init(vector<double>& v) // передача по ссылке

{

for (int i = 0; i<v.size; ++i) v[i] = i;

}

void g(int x)

{

vector<double> vd1(10); // небольшой вектор

vector<double> vd2(1000000); // большой вектор

vector<double> vd3(x); // вектор неопределенного размера

init(vd1);

init(vd2);

init(vd3);

}

Итак, мы хотим, чтобы функция

init
изменяла вектор, являющийся ее аргументом. Иначе говоря, мы хотим не копировать его (т.е. передавать по значению), не объявлять с помощью константной ссылки (т.е. передавать по константной ссылке), а просто передать обычную ссылку на вектор.

Рассмотрим ссылки более подробно. Ссылка — это конструкция, позволяющая пользователю объявлять новое имя объекта. Например,

int&
— это ссылка на переменную типа
int
. Это позволяет нам написать следующий код:

int i = 7;

int& r = i; // r — ссылка на переменную i

r = 9; // переменная i становится равной 9

i = 10;

cout << r << ' ' << i << '\n'; // вывод: 10 10

Иначе говоря, любая операция над переменной

r
на самом деле означает операцию над переменной
i
. Ссылки позволяют уменьшить размер выражений. Рассмотрим следующий пример:

vector< vector<double> > v; // вектор векторов чисел типа double

Допустим, нам необходимо сослаться на некоторый элемент

v[f(x)][g(y)]
несколько раз. Очевидно, что выражение
v[f(x)][g(y)]
выглядит слишком громоздко и повторять его несколько раз неудобно. Если бы оно было просто значением, то мы могли бы написать следующий код:

double val = v[f(x)][g(y)]; // val — значение элемента v[f(x)][g(y)]

В таком случае можно было

бы повторно использовать переменную
val
. А что, если нам нужно и читать элемент
v[f(x)][g(y)]
, и присваивать ему значения
v[f(x)][g(y)]
? В этом случае может пригодиться ссылка.

double& var = v[f(x)][g(y)]; // var — ссылка на элемент v[f(x)][g(y)]

Теперь можем как считывать, так и изменять элемент

v[f(x)][g(y)]
с помощью ссылки
var
. Рассмотрим пример.

var = var/2+sqrt(var);

Это ключевое свойство ссылок — оно может служить “аббревиатурой” объекта и использоваться как удобный аргумент. Рассмотрим пример.

// передача по ссылке (функция ссылается на полученную переменную)

int f(int& x)

{

x = x+1;

return x;

}

int main

{

int xx = 0;

cout << f(xx) << endl; // вывод: 1

cout << xx << endl; // вывод: 1; функция f изменяет

// значение xx

int yy = 7;

cout << f(yy) << endl; // вывод: 8

cout << yy << endl; // вывод: 8; функция f изменяет

// значение yy

}

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

Сравните этот пример с соответствующим примером из раздела 8.5.3.

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

void swap(double& d1, double& d2)

{

double temp = d1; // копируем значение d1 в переменную temp

d1 = d2; // копируем значение d2 в переменную d1

d2 = temp; // копируем старое значение d1 в переменную d2

}

int main

{

double x = 1;

double y = 2;

Поделиться:
Популярные книги

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Имперец. Земли Итреи

Игнатов Михаил Павлович
11. Путь
Фантастика:
героическая фантастика
боевая фантастика
5.25
рейтинг книги
Имперец. Земли Итреи

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Кодекс Охотника. Книга XVI

Винокуров Юрий
16. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVI

Титан империи

Артемов Александр Александрович
1. Титан Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Титан империи

Вечная Война. Книга VIII

Винокуров Юрий
8. Вечная Война
Фантастика:
боевая фантастика
юмористическая фантастика
космическая фантастика
7.09
рейтинг книги
Вечная Война. Книга VIII

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Возвышение Меркурия. Книга 13

Кронос Александр
13. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 13

Кодекс Охотника XXVIII

Винокуров Юрий
28. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника XXVIII

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Новый Рал

Северный Лис
1. Рал!
Фантастика:
фэнтези
попаданцы
5.70
рейтинг книги
Новый Рал

Вечный. Книга III

Рокотов Алексей
3. Вечный
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга III