Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Использование указателя как средства хранения адреса



 

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

Допустим, что переменная howOld имеет тип int. Чтобы объявить указатель pAge для хранения адреса этой переменной, наберите следующий фрагмент кода:

int *pAge = 0;

Этой строкой переменная pAge объявляется указателем на тип int. Это означает, что pAge будет содержать адрес значения типа int.

Отметим, что pAge ничем не отличается от любой другой переменной. При объявлении переменной целочисленного типа (например, int) мы указываем на то, что в ней будет храниться целое число. Когда же переменная объявляется указателем на какой-либо тип, это означает, что она будет хранить адрес переменной данного типа. Таким образом, указатели являются просто отдельным типом переменных.

В данном примере переменная pAge инициализируется нулевым значением. Указатели, значения которых равны 0, называют пустыми. После объявления указателю обязательно должно присваиваться какое-либо значение. Если заранее неизвестно, какой адрес должен храниться в указателе, ему присваивается значение 0. Неинициализированные указатели в дальнейшем могут стать причиной больших неприятностей.

Поскольку при объявлении указателю pAge было присвоено значение 0, далее ему нужно присвоить адрес какой-либо переменной, например howOld. Как это сделать, показано ниже:

 

unsigned short int howOld = 50; // объявляем переменную

unsigned short int *pAge = 0; // объявляем указатель

pAge = & howOld; // Присвоение указателю pAge адреса переменной

howOld

 

Рис. 8.2. Схема сохранения переменной в памяти

 

В первой строке объявлена переменная howOld типа unsigned short int и ей присвоено значение 50. Во второй строке объявлен указатель pAge на тип unsigned short int, которому присвоено значение 0. Символ " звездочка" (*), стоящий после наименования типа, указывает на то, что описанная переменная является указателем.

В последней строке указателю pAge присваивается адрес переменной howOld. На это указывает оператор адреса (& ) перед именем переменной howOld. Если бы этого оператора не было, присваивался бы не адрес, а значение переменной, которое также может являться корректным адресом.

В нашем случае значением указателя pAge будет адрес переменной howOld, значение которой равно 50. Две последние строки рассмотренного фрагмента программы можно объединить в одну:

 

unsigned short int howOld = 50; // объявляем переменную

unsigned short int * pAge = & how01d; // объявляем указатель на переменную howOld

 

Теперь указатель pAge содержит адрес переменной howOld. С помощью этого указателя можно получить и значение переменной, на которую он указывает. В нашем примере это значение равно 50. Обращение к значению how01d посредством указателя pAge называется операцией разыменования или косвенного обращения, поскольку осуществляется неявное обращение к переменной how01d, адрес которой содержится в указателе. Далее вы узнаете, как с помощью разыменовывания возвращать значения переменных.

Косвенное обращение подразумевает получение значения переменной, адрес которой содержится в указателе, а оператор разыменования позволяет извлечь это значение.

 

Имена указателей

 

Поскольку указатели являются обычными переменными, называть их можно любыми корректными для переменных именами. Для выделения указателей среди других переменных многие программисты используют перед их именами символ " p" (от англ. pointer), например pAge или pNumber.

 

Оператор разыменовывания

 

Оператор косвенного обращения (или оператор разыменования) позволяет получить значение, хранящееся по адресу, записанному в указателе.

В отличие от указателя, при обращении к обычной переменной осуществляется доступ непосредственно к ее значению. Например, чтобы объявить новую переменную типа unsigned short int, а затем присвоить ей значение другой переменной, можно написать следующее:

 

unsigned short int yourAge;

yourAge = howOld;

 

При косвенном доступе будет получено значение, хранящееся по указанному адресу. Чтобы присвоить новой переменной yourAge значение how01d, используя указатель pAge, содержащий ее адрес, напишите следующее:

 

unsigned short int yourAge;

yourAge = *pAge;

 

Оператор разыменования (*) перед переменной pAge может рассматриваться как " значение, хранящееся по адресу". Таким образом, вся операция присваивания означает: " получить значение, хранящееся по адресу, записанному в pAge, и присвоить его переменной yourAge".

 

Примечание: Оператор разыменования можно использовать с указателями двумя разными способами: для объявления указателя и для его разыменовывания. В случае объявления указателя символ звездочки сигнализирует компилятору, что это не простая переменная, а указатель, например:

unsigned short < < pAge = 0; // объявляется указатель

// на переменную типа unsigned short

В случае разыменовывания указателя символ звездочки означает, что операция должна производиться не над самим адресом, а над значением, сохраненным по адресу, который хранится в указателе:

*pAge = 5; //присваивает значение 5 переменной по адресу в указателе pAge

Также не путайте оператор разыменовывания с оператором умножения (*). Компилятор по контексту определяет, какой именно оператор используется в данном случае.

 

Указатели, адреса и переменные

 

Чтобы овладеть навыками программирования на C++, вам в первую очередь необходимо понимать, в чем различие между указателем, адресом, хранящимся в указателе, и значением, записанным по адресу, хранящемуся в указателе. В противном случае это может привести к ряду серьезных ошибок при написании программ.

Рассмотрим еще один фрагмент программы:

 

int theVariable = 5;

int * pPointer = & theVariable;

 

В первой строке объявляется переменная целого типа theVariable. Затем ей присваивается значение 5. В следующей строке объявляется указатель на тип int, которому присваивается адрес переменной theVariable. Переменная pPointer является указателем и содержит адрес переменной theVariable. Значение, хранящееся по адресу, записанному в pPointer, равно 5. На рис. 8.3 схематически показана структура этих переменных.

 

Рис. 8.3. Схема распределения памяти

 

Обращение к данным через указатели

 

После того как указателю присвоен адрес какой-либо переменной, его можно использовать для работы со значением этой переменной. В листинге 8.2 показан пример обращения к значению локальной переменной через указатель на нее.

Листинг 8.2. Обращение к данным через указатели

1: // Листинг 8.2. Использование указателей

2:

3: #include< iostream.h>

4:

5: typedef unsigned short int USHORT;

6: int main()

7: {

8: USHORT myAge; // переменная

9: USHORT * pAge = 0; // указатель

10: myAge = 5;

11: cout < < " myAge: " < < myAge < < " \n";

12: pAge = & myAge; // заносим в pAge адрзс myAge

13: cout < < " *pAge: " < < *pAge < < " \n\n";

14: cout < < " *pAge = 7\n";

15: *pAge = 7; // присваиваем myAge значение 7

16: cout < < " *pAge: " < < *pAge < < " \n";

17: cout < < " myAge: " < < myAge < < " \n\n";

18: cout < < " myAge = 9\n";

19: myAge = 9;

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

21: cout < < " *pAge: " < < *pAge < < " \n";

22:

23: return 0;

24: }

 

Результат:

myAge: 5

*pAge: 5

 

*pAge: = 7

*pAge: 7

myAge: 7

 

myAge = 9

myAge: 9

*pAge: 9

 

Анализ: В программе объявлены две переменные: myAge типа unsigned short и pAge, являющаяся указателем на этот тип. В строке 10 переменной pAge присваивается значение 5, а в строке 11 это значение выводится на экран.

Затем в строке 12 указателю pAge присваивается адрес переменной myAge. С помощью операции разыменования значение, записанное по адресу, хранящемуся в указателе pAge, выводится на экран (строка 13). Как видим, полученный результат совпадает со значением переменной myAge. В строке 15 переменной, адрес которой записан в pAge, присваивается значение 7. После выполнения такой операции переменная myAge будет содержать значение 7. Убедиться в этом можно после вывода этих значений (строки 16, 17).

В строке 19 значение myAge опять изменяется. Теперь этой переменной присваивается число 9. Затем в строках 20 и 21 мы обращаемся к этому значению непосредственно (через переменную) и путем разыменования указателя на нее.

 


Поделиться:



Популярное:

Последнее изменение этой страницы: 2017-03-08; Просмотров: 610; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.027 с.)
Главная | Случайная страница | Обратная связь