77. Передача данных по ссылке
Передача данных с использованием указателей несколько трудоемка, поскольку требует при вызове функций передавать адрес аргумента, а внутри функции разыменовывать параметры-указатели. Кроме того, неправильное выполнение этих дополнительных действий может привести к появлению ошибок.
В языке C++ имеется более простой способ передачи данных по адресу, а именно – передача данных по ссылке.
Переделаем пример предыдущего параграфа так, чтобы данные в нем передавались не через указатель, а по ссылке:
int Div (int N1, int N2, int &Ost) // int &Ost – параметр-ссылка
{
Ost = N1 % N2; // Разыменования параметра-ссылки Ost не требуется
return N1 / N2;
}
int main()
{
int I = 10, J = 3, R, O;
R = Div (I, J, O); // Используется сам аргумент О, а не его адрес
cout << I << “ / ” << J << “ = ” << R << “. Остаток равен “ << O << endl;
return 0;
}
Из этого примера видно, что для определения параметра, с помощью которого функция может вернуть остаток от деления, используется символ &, а не *. Именно так определяются параметры-ссылки. Внутри процедуры, для получения доступа к значению данных, разыменовывать параметр-ссылку не нужно. При вызове процедуры используется сам аргумент, а не его адрес. Таким образом, использование передачи данных по ссылке значительно проще, чем передача данных через указатели.
На самом деле в этом способе передача данных осуществляется точно так же, как и при использовании указателей, только операции взятия адреса аргумента и разыменования параметра-ссылки осуществляется компилятором автоматически, скрытно от нас.
Способ передачи данных по ссылке также можно отнести к передаче данных по адресу, и он полностью эквивалентен по своему эффекту передачи данных через указатели.
В целом, передача данных по адресу (с помощью указателей или по ссылке), является более эффективной, чем передача данных по значению. Это объясняется тем, что при передаче данных по значению осуществляется создание копии аргумента функции, а на это тратится и память и время. При передаче по адресу затраты памяти и времени существенно меньше, так как в функцию передается только адрес данных, а не сами данные, объем которых часто существенно превышает размер адреса.
Возникает вопрос: почему всегда не использовать передачу данных по адресу, поскольку это более эффективно? Недостатком передачи данных по адресу является скрытый побочный эффект, связанный с возможным непредвиденным изменением внутри функции значения аргумента переданного по адресу. Однако этого эффекта можно избежать, если определить соответствующий параметр функции как константу:
void Proc(const double *D)
{
……
*D = 3.14; // Ошибка в процессе компиляции
……
}
- 2. Структура и основные элементы программы
- 3.Общее понятие типов данных
- 4. Переменные и константы
- 5.Основные типы данных
- 6. Спецификаторы типов данных
- 7. Определение переменных и констант в программе
- 8. Инициализация переменных различных типов
- 9.Целочисленные типы данных
- 10. Вещественные типы данных
- 11. Особенности представления вещественных типов данных
- 12.Логический тип данных
- 13. Символьный тип данных
- 14. Управляющие последовательности
- 15. Операции и выражения
- 16. Операция присваивания, составные операции присваивания
- 17. Понятие l-значения
- 18. Преобразование типов данных
- 19. Арифметические операции
- 20. Операции инкремента и декремента, их разновидности
- 21. Операции отношения
- 22. Логические операции
- 23. Побитовые операции сдвига
- 24. Побитовые логические операции
- 25. Примеры применения побитовых операций
- 26. Условная операция и ее использование
- 27. Определение объема памяти, необходимого для размещения объектов
- 28. Понятие приоритета операций и его влияние на результаты вычислений
- 31.Флаги форматирования потоков ввода-вывода
- 32. Форматирование ввода-вывода с помощью манипуляторов
- 33.Форматирование ввода-вывода с помощью функций потоков ввода-вывода
- 34. Управление шириной поля вывода и выравниванием данных при выводе
- 35. Управление форматом вывода вещественных значений
- 36. Основные понятия структурного программирования
- 37. Базовый набор управляющих структур
- 39.Условная инструкция (if)
- 40. Инструкция множественного выбора (switch)
- 42. Цикл с постусловием (do while)
- 43. Итерационный цикл (for)
- 46. Инструкция перехода goto
- 47. Понятие рекуррентных вычислений, примеры
- 48. Понятие инварианта цикла
- 49. Понятие и определение массива
- 52. Ввод элементов массивов с клавиатуры
- 53. Декларативная и программная инициализация массивов
- 54. Копирование массивов
- 55. Нахождение минимальных и максимальных значений в массивах
- 56. Сдвиг элементов массивов
- 57. Перестановка элементов в массивах
- 58. Поиск данных в массивах
- 59. Сортировка данных в массивах
- 60. Вычисление сумм и произведений элементов массивов
- 61. Представление текстовых строк в виде массива символов
- 62. Ввод-вывод символьных строк
- 63. Определение фактической длины строки
- 64. Копирование символьных строк
- 65. Основные функции обработки строк библиотеки cstring
- 66. Массивы текстовых строк (двумерные массивы символов)
- 67. Указатели Понятие указателя
- Работа с указателями
- 68. Арифметика указателей
- 69. Индексирование указателей
- 70. Ссылки
- 71. Определение функции
- 72. Инструкция return
- 73. Завершение работы функции
- 74. Механизмы передачи данных через параметры функций
- 75. Передача данных по значению
- 76. Передача данных через указатели
- 77. Передача данных по ссылке
- 78. Параметры по умолчанию
- 79. Функции с переменным числом параметров
- 80. Inline функции
- 81. Перегрузка функций
- 82. Рекурсия
- 83. Прототипы функций