Инструменты пользователя

Инструменты сайта


reference

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

reference [2010/10/14 04:01] (текущий)
Строка 1: Строка 1:
 +====== Ссылка ======
 +**Ссылка** в программировании — это объект,​ указывающий на определенные данные,​ но не хранящий их. Получение объекта по ссылке называется разыменованием. Концептуально ссылка является указателем,​ но может иметь ряд отличий. Использование указателей в качестве альтернативного способа доступа к переменным таит в себе опасность - если был изменен адрес, хранящийся в указателе,​ то этот указатель больше не ссылается на нужное значение. Язык C предлагает альтернативу для более безопасного доступа к переменным через указатели.Объявив ссылочную переменную,​ можно создать объект,​ который,​ как указатель,​ ссылается на другое значение,​ но, в отличие от указателя,​ постоянно привязан к этому значению. Таким образом,​ ссылка на значение всегда ссылается на это значение. ​
  
 +Ссылку можно объявить следующим образом:​ <​file>​
 +<имя типа>&​ <имя ссылки>​ = <​выражение>;​
 +                или
 +<имя типа>&​ <имя ссылки>​(<​выражение>​);​
 +</​file>​
 +Раз ссылка является другим именем уже существующего объекта,​ то в качестве инициализирующего объекта должно выступать имя некоторого объекта,​ уже расположенного в памяти. Значением ссылки после выполнения соответствующего определения с инициализацией становится адрес этого объекта.
 +  * **Ограничения на ссылки**. В языке С++ существуют ограничения на работу со ссылками. Например,​ ссылки не могут связываться с другими ссылками. Иначе, говоря,​ **ссылка не имеет адреса**. Кроме того, невозможно создать указатель на ссылку. К битовому полю также нельзя обратиться с помощью ссылки. Независимые ссылки должны быть инициализированы в момент своего объявления. Нулевой ссылки не существует.
 +
 +Раз ссылка является другим именем уже существующего объекта,​ то в качестве инициализирующего объекта должно выступать имя некоторого объекта,​ уже расположенного в памяти. Значением ссылки после выполнения соответствующего определения с инициализацией становится адрес этого объекта. Проиллюстрируем это на конкретном примере: ​
 +
 +<​file>​
 +#include "​iostream"​
 +using namespace std;
 +void main()
 +{
 +   int ivar = 1234;   //​Переменной присвоено значение.
 +   int *iptr = &ivar; //​Указателю присвоен адрес ivar.
 +   int &iref = ivar;  //​Ссылка ассоциирована с ivar.
 +   int *p = &​iref; ​   //​Указателю присвоен адрес iref.
 +
 +   cout << "ivar = " << ivar << "​\n";​
 +   cout << "*iptr = " << *iptr <<"​\n";​
 +   cout << "iref = " << iref << "​\n";​
 +   cout << "*p = " << *p << "​\n";​
 +}
 +</​file>​
 +
 +Результат работы программы:​
 +<​file>​
 +ivar = 1234
 +*iptr = 1234
 +iref = 1234
 +*p = 1234
 +</​file>​
 +Комментарии к программе.Здесь объявляются четыре переменные. Переменнаяivar инициализирована значением 1234. Указателю на целое *iptr присвоен адресivar. Переменная iref объявлена как ссылочная. Эта переменная в качестве своего значения принимает адрес расположения в памяти переменной ivar. Оператор:​ cout << "iref = " << iref << "​\n";​
 + 
 +выводит на экран значение переменной ivar. Это объясняется тем, что iref - ссылка на местоположение ivar в памяти. ​
 +
 +Последнее объявление int *p = &iref; создает еще один указатель,​ которому присваивается адрес, хранящийся в iref. Строки:​
 +<​file>​
 +int *iptr = &​ivar; ​
 +          и
 +int *p = &iref;
 +</​file>​
 + 
 +дают одинаковый результат. В них создаются указатели,​ ссылающиеся на ivar. На рисунке проиллюстрирована взаимосвязь переменных из приведенной программы:​
 +{{:​ris47_1.jpg|}}
 +
 +<note warning>​При использовании ссылок следует помнить одно правило:​ однажды инициализировав ссылку ей нельзя присвоить другое значение! </​note>​
 +
 +
 +
 +====== Ссылки в качестве результатов функций ======
 +Здесь мы рассмотрим использование ссылок в качестве результатов функций. Далее представлен ряд редакторов,​ рекомендуемых для использования и их основные возможности. Функции могут возвращать ссылки на объекты при условии,​ что эти объекты существуют,​ когда функция неактивна. Таким образом,​ функции не могут возвращать ссылки на локальные автоматические переменные. Например,​ для функции,​ объявленной как:
 +<​file>​
 +double &rf(int p);
 +</​file> ​
 +необходим аргумент целого типа, и она возвращает ссылку на объект double, предположительно объявленный где-то в другом месте. Проиллюстрируем сказанное конкретными примерами.
 +  * **Пример 1**. Заполнение двумерного массива одинаковыми числами.
 +<​file>​
 +#include "​iostream"​
 +
 +using namespace std;
 +int a[10][2];
 +void main ()
 +{
 + int & rf(int index); //​Прототип функции.
 + int b;
 + cout << "​Заполнение двумерного массива. ";
 + cout << "​Первый столбец заполняется обычным способом,​ ";
 + cout << "а второй - через функцию.\n";​
 + for (int i=0;​i<​10;​i++)
 + {
 +   cout << i+1 << "-й элемент:​ ";
 +   cin >> b;
 +   a[i][0] = b;
 +   rf(i) = b;
 + }
 + cout << "​Вывод двумерного массива.\n";​
 + cout << "1-й столбец ​  2-й столбец"​ << "​\n";​
 + for (i=0;​i<​10;​i++)
 + cout << a[i][0] << "​\t\t"​ << rf(i) << "​\n";​
 +}
 +
 +int &rf(int index)
 +{
 +  return a[index][1];​ //​Возврат ссылки на элемент массива.
 +}
 +</​file>​
 +Здесь объявляется глобальный двумерный массив a, состоящий из целых чисел. В начале функции main() содержится прототип ссылочной функции rf(), которая возвращает ссылку на целое значение второго столбца массива a, которое однозначно идентифицируется параметром-индексом index. Так как функция rf() возвращает ссылку на целое значение,​ то имя функции может оказаться слева от оператора присваивания,​ что продемонстрировано в строке:​
 +<​file>​
 +rf(i) = b;
 +</​file>​
reference.txt · Последние изменения: 2010/10/14 04:01 (внешнее изменение)