Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры программирование.doc
Скачиваний:
7
Добавлен:
17.04.2019
Размер:
257.54 Кб
Скачать

14. Указатели и ссылки. Ссылочные переменные.

Ссылки в С++

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

структура объявления ссылок:

/*тип*/ &/*имя ссылки*/ = /*имя переменной*/;

При объявлении ссылки перед её именем ставится символ амперсанда "&", сама же ссылка должна быть проинициализирована именем переменной, на которую она ссылается. Тип данных, на который указывает ссылка, может быть любым, но должен совпадать с объектом, на который ссылается, то есть с типом данных ссылочной переменной. Для удобства, будем называть переменную, на которую ссылается ссылка "ссылочной переменной". Любое изменение значения содержащегося в ссылке повлечёт за собой изменение этого значения в переменной, на которую ссылается ссылка. Разработаем программу, в которой объявим ссылку на объект типа int.

#include "stdafx.h"

#include <iostream>

using namespace std;

int main(int argc, char* argv[])

{ int value = 15;

int &reference = value; // объявление и инициализация ссылки значением переменной value

cout << "value = " << value << endl;

cout << "reference = " << reference << endl;

reference+=15; // изменяем значение переменной value посредством изменения значения в ссылке

cout << "value = " << value << endl; // смотрим, что получилось, как будет видно дальше значение поменялось как в ссылке,

cout << "reference = " << reference << endl; // так и в ссылочной переменной

system("pause");

return 0;}

В строке 10 объявлена ссылка reference типа int на переменную value. В строке 13 суммируется значение переменной value с числом 15, черезссылку reference. Результат работы программы (см. Рисунок 1).

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

Ссылки, как правило, в большинстве случаев используют в функциях как ссылки-параметры или ссылки-аргументы. Напомню, что в языке программирования С++ в функции передаются данные по значению и по ссылке. Так вот, когда происходит передача по значению, те данные, которые необходимо передать, нужно сначала скопировать, а когда передаётся большой объём данных, то только на передачу затрачивается большое количество времени и ресурсов. В таком случае необходимо использовать передачу по ссылке, в этом случае данные копировать нет необходимости, так как к ним обеспечен прямой доступ, но нарушают безопасность данных, хранимых в ссылочных переменных, так как открывают прямой доступ к этим данным. Хотя далее мы рассмотрим, как обеспечить целостность данных и скорость их передачи. Для этого, разработаем программу, в которой создадим три функции, аргументы в которых будут передаваться по значению и по ссылке. Вдобавок ко всему этому ещё и передачу через указатель осуществим. Частенько возникает путаница между указателями и ссылками, на первый взгляд и ссылки и указатели работают одинаково, но разница все, же есть и весьма значительная.

#include "stdafx.h"

#include <iostream>

using namespace std;

int sum_by_value(int );// суммирование по значению

int sum_by_reference(int &);// суммирование по ссылке

int sum_by_pointer(int *); // суммирование по указателю

int _tmain(int argc, _TCHAR* argv[])

{

int value = 10;

cout << "sum_by_value = " << sum_by_value(value) << endl;

cout << "value = " << value << endl; // значение переменной осталось неизменным

cout << "sum_by_reference = " << sum_by_reference(value) << endl;

cout << "value = " << value << endl; // значение переменной изменилось

cout << "sum_by_pointer = " << sum_by_pointer(&value) << endl;

cout << "value = " << value << endl; // значение переменной изменилось ещё раз

system("pause");

return 0;

}

int sum_by_value(int value)// функция принимающая аргумент по значению

{ value += value;

return value;}

int sum_by_reference(int &reference) // функция принимающая аргумент по ссылке

{ reference += reference;

return reference;}

int sum_by_pointer(int *ptrvalue)// функция принимающая аргумент через указатель

{ *ptrvalue += *ptrvalue;// арифметика с указателем

return *ptrvalue;}

Начальное значение осталось неизменным в случае передачи по значению, тогда как передача по ссылке и через указатель изменили значение передаваемой переменной. Таким образом, нет необходимости использовать глобальные переменные при необходимости изменения значения передаваемой переменной, нужно воспользоваться ссылкой или указателем. В случае использования указателя строка 16 нельзя забывать про операцию взятия адреса, так как аргументом является указатель. В случае со ссылкой, достаточно указать только имя переменной и всё строка 14.

В чём же разница между указателями и ссылками? Основное назначение указателя – это организация динамических объектов, то есть размер, которых может меняться (увеличиваться или уменьшаться). Тогда как ссылки предназначены для организации прямого доступа к тому, или иному объекту. Главное отличие состоит во внутреннем механизме работы. Указатели ссылаются на участок в памяти, используя его адрес. А ссылки ссылаются на объект, по его имени (тоже своего рода адрес). Если нет необходимости изменить передаваемое значение в ссылочной переменной, но нужно выиграть в скорости, используйте спецификатор const в объявлении параметров функций. Только так и можно защитить данные от случайного их изменения или полной потере.

int sum_by_reference(const int &reference) // функция принимающая аргумент по ссылке

// квалификатор const не даёт изменить передаваемый аргумент внутри функции