ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 10) онлайн
Доступ к переменной по указателю
Предположим, что мы не знаем имени переменной, но знаем ее адрес. Можем ли мы получить доступ к значению этой переменной? (Возможно, мы потеряли список имен переменных.)
Существует специальная запись, предназначенная для доступа к значению переменной, используя ее адрес вместо имени. В программе PTRACC показано, как это можно сделать:
// ptracc.cpp
// доступ к переменной через указатель
#include <iostream>
using namespace std;
int main ( )
{
int var1 = 11; // две переменные
int var2 = 22;
int* ptr; // указатель на целое
ptr = &var1; // помещаем в ptr адрес переменной var1
cout << *ptr << endl; // показываем содержимое переменной через указатель
ptr = &var2; // помещаем в ptr адрес переменной var2
cout << *ptr << endl; // показываем содержимое переменной через указатель
return 0;
}
Эта программа очень похожа на PTRVAR, за исключением того, что вместо вы- вода на дисплей адресов, хранящихся в переменной ptr, мы выводим значения, хранящиеся по адресу, на который указывает ptr. Результат работы программы будет следующим:
11 22
Выражение *ptr, дважды встречающееся в нашей программе, позволяет нам получить значения переменных var1 и var2.
Звездочка, стоящая перед именем переменной, как в выражении *ptr, называ- ется операцией разыменования. Эта запись означает: взять значение переменной, на которую указывает указатель. Таким образом, выражение *ptr представляет собой значение переменной, на которую указывает указатель ptr. Если ptr указы- вает на переменную var1, то значением выражения *ptr будет 11. На рис. 10.4 показано, как работает операция разыменования.
Указатели можно использовать не только для получения значения перемен- ной, на которую он указывает, но и для выполнения действий с этими перемен- ными. Программа PTRTO использует указатель для присвоения значения одной переменной, а затем другой:
// ptrto.cpp
// еще один пример доступа через указатель
#include <iostream>
using namespace std;
int main ( )
{
int var1, var2; // две переменные
int* ptr; // указатель на целое
ptr = &var1; // пусть ptr указывает на var1
*ptr = 37; // то же самое, что var1 = 37;
var2 = *ptr; // то же самое, что var2 = var1;
cout << var2 << endl; // убедимся, что var2 равно 37
return 0;
}
Запомните, что звездочка, используемая в операции разыменования, — это не то же самое, что звездочка, используемая при объявлении указателя. Операция
разыменования предшествует имени переменной и означает значение, находя- щееся в переменной, на которую указывает указатель. Звездочка же в объявле- нии указателя означает указатель на.
int* ptr; // обьявление: указатель на int
*ptr = 37; // разыменование: значение переменной, адресованной через ptr

Рис. 10.4. Доступ к переменным через указатели
Доступ к значению переменной, хранящейся по адресу, с использованием операции разыменования называется непрямым доступом или разыменованием указателя.
Рассмотрим небольшие примеры того, что мы изучили:
int v; // определим переменную v типа int
int* р; // определим переменную типа указатель на int
р = &v; // присвоим переменной р значение адреса переменной v
v = 3; // присвоим v значение 3
*р = 3; // сделаем то же самое, но через указатель
В последних двух строках показано различие между прямым доступом, когда мы обращаемся к переменной, используя ее имя, и непрямым доступом, когда мы обращаемся к той же переменной, но уже используя ее адрес.
Пока в примерах программ мы не обнаружили преимущества использования указателей для доступа к переменным, поскольку мы всегда можем применить прямой доступ. Важность указателей становится очевидной в том случае, когда мы не имеем прямого доступа к переменной. Мы увидим это позже.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
