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

на главную

Жанры

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

15: return 0;

16: }

17:

18: void swap(int &rx, int &ry)

19: {

20: int temp;

21:

22: cout << "Swap. Before swap, rx: " << rx << " ry: " << ry << "\n";

23:

24: temp = rx;

25: rx = ry;

26: ry = temp;

27:

28: cout << "Swap. After swap, rx: " << rx << " ry: " << ry << "\n";

29:

30: }

Результат:

Main. Before swap, x:5 y: 10

Swap. Before swap, rx:5 ry:10

Swap. After swap, rx:10 ry:5

Main. After swap, x:10, y:5

Анализ:

Точно так же, как и в примере с указателями, в строке 10 объявляются две переменные, а их значения выводятся на экран в строке 12. В строке 13 вызывается функция swap, но обратите внимание на то, что ей передаются именно значения x и у, а не их адреса. Вызывающая функция просто передает свои переменные.

После вызова функции swap выполнение программы переходит к строке 18, в которой эти переменные идентифицируются как ссылки. Их значения выводятся на экран в строке 22, но заметьте, что для этого не требуется никаких специальных операторов, поскольку мы имеем дело с псевдонимами для исходных значений и используем их в этом качестве.

В строках 24—26 выполняется обмен значений, после чего они выводятся на экран в строке 28. Управление программой вновь возвращается в вызывающую функцию, и в строке 14 эти значения опять выводятся на экран, но уже в функции main. Поскольку параметры для функции swap объявлены как ссылки, то и переменные из функции main передаются как ссылки, следовательно, они также изменяются и в функции main.

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

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

В листинге 9.6 показана функция swap, использующая в качестве аргументов указатели, а в листинге 9.7 — та же функция, но с использованием ссылок. Использовать функцию, которая принимает в качестве параметров ссылки, легче, да и в программе такая функция проще читается, но как вызывающей функции узнать о том, каким способом переданы параметры — по ссылке или по значению? Будучи клиентом (или пользователем) функции swap, программист должен быть уверен в том, что функция swap на самом деле изменит параметры.

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

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

В языке C++ клиенты классов и функций всю необходимую информацию черпают из файлов заголовков. Этот файл выполняет роль интерфейса

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

Когда Колонел Джон Роблинг (Colonel John Roebling) проектировал свой Бруклинский мост (Brooklyn Bridge), он интересовался деталями процесса литья и изготовления проводов. Он глубоко вникал в подробности механических и химических процессов, которые требовалось обеспечить для создания необходимых материалов. Но в наши дни инженеры более эффективно используют свое рабочее время, доверяя информации о строительных материалах и не интересуясь подробностями их изготовления.

В этом и состоит цель языка C++ — позволить программистам полагаться на описанные классы и функции, не вникая во внутренние механизмы их действия. Эти составные части можно собрать в одну программу, подобно тому как строители из отдельных блоков, проводов, труб, кирпичей и других элементов создают дома и мосты.

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

Возвращение нескольких значений

Как упоминалось выше, функции могут возвращать только одно значение. Что же делать, если нужно получить от функции сразу два значения? Один путь решения этой проблемы — передача функции двух объектов как ссылок. В ходе выполнения функция присвоит этим объектам нужные значения. Факт передачи объектов как ссылок, позволяющий функции изменить исходные объекты, равносилен разрешению данной функции возвратить два значения. В этом случае мы обходимся без возвращаемого значения, которое (зачем же пропадать добру) можно использовать для сообщения об ошибках.

И вновь одинакового результата можно достичь, используя как ссылки, так и указатели. В листинге 9.8 показана функция, которая возвращает три значения: два в виде параметров-указателей и одно в виде возвращаемого значения функции.

Листинг 9.8. Возвращение значений с помощью указателей

1: // Листинг 9.8.

2: // Возвращение нескольких значений из функции с помощью указателей

3:

4: #include <iostream.h>

5: int

6: short Factor(int n, int* pSquared, int* pCubed);

7:

8: int main

9: {

10: int number, squared, cubed;

11: short error;

12:

13: cout << "Enter a number (0 - 20): ";

14: cin >> number;

15:

16: error = Factor(number, &squared, &cubed);

17:

18: if (!error)

19: {

20: cout << "number: " << number << "\n";

21: cout << "square: " << squared << "\n";

22: cout << "cubed: " << cubed << "\n";

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

Владеющий

Злобин Михаил
2. Пророк Дьявола
Фантастика:
фэнтези
8.50
рейтинг книги
Владеющий

Имперец. Том 1 и Том 2

Романов Михаил Яковлевич
1. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 1 и Том 2

Шериф

Астахов Евгений Евгеньевич
2. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
6.25
рейтинг книги
Шериф

Двойник Короля 5

Скабер Артемий
5. Двойник Короля
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Двойник Короля 5

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

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Черный дембель. Часть 4

Федин Андрей Анатольевич
4. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 4

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Дочь опальной герцогини

Лин Айлин
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дочь опальной герцогини

Идеальный мир для Лекаря

Сапфир Олег
1. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

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

INDIGO
16. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 3

Рейдер 2. Бродяга

Поселягин Владимир Геннадьевич
2. Рейдер
Фантастика:
фэнтези
попаданцы
7.24
рейтинг книги
Рейдер 2. Бродяга

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Проданная невеста

Wolf Lita
Любовные романы:
любовно-фантастические романы
5.80
рейтинг книги
Проданная невеста