Освой самостоятельно С++ за 21 день.
Шрифт:
Рис. 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 мы обращаемся к этому значению непосредственно (через переменную) и путем разыменования указателя на нее.
Использование адреса, хранящегося в указателе
При работе с указателями в большинстве случаев не приходится иметь дело со значениями адресов, записанных в указателях. В предыдущих разделах отмечалось, что после присвоения указателю адреса переменной значением указателя будет именно этот адрес. Почему бы не проверить это утверждение? Для этого можно воспользоваться программой, приведенной в листинге 8.3.
Листинг 8.3. Что же записано в указателе?
1: // Листинг 8.3. Что же хранится в указателе?
2:
3: #include <iostream.h>
4:
5:
6: int main
7: {
8: unsigned short int myAge = 5, yourAge = 10;
9: unsigned short int * pAge = &myAge; // Указатель
10: cout << "myAge:\t" << myAge << "\t yourAge:\t" << yourAge << "\n";
11: cout << "&myAge:\t" << &myAge << "\t&yourAge;\t" << &yourAge << "\n";
12: cout << "pAge;\t" << pAge << "\n";
13: cout << "*pAge:\t" << *pAge << "\n";
14: pAge = &yourAge; // переприсвоение указателя
15: cout << "myAge:\t" << myAge << "\t yourAge;\t" << yourAge << "\n";
16: cout << "&myAge:\t" << &myAge << "\t&yourAge:\t" << &yourAge << "\n";
17: cout << "pAge:\t" << pAge << "\n";
18: cout << "*pAge:\t" << *pAge << "\n";
19: cout << "&pAge:\t" << &pAge << "\n";
20: return 0;
21: }
Результат:
myAge: 5 yourAge: 10
&myAge: 0x355C &yourAge: 0x355E
pAge: 0x355C
*pAge: 5
myAge: 5 yourAge: 10
&myAge: 0x355C &yourAge: 0x355E
pAge: 0x355E
*pAge: 10
&pAge: 0x355A
(Ваши результаты могут отличаться от приведенных.)
Анализ: В строке 8 объявляются две переменные типа unsigned short — myAge и yourAge. Далее, в строке 9, объявляется указатель на этот тип (pAge). Этому указателю присваивается адрес переменной myAge.
В строках 10 и 11 значения и адреса переменных pAge и myAge выводятся на экран. Обращение к значению переменной myAge путем разыменования указателя pAge выполняется в строке 13. Перед тем как перейти к дальнейшему изучению материала, подумайте, все ли вам понятно в рассмотренном примере. Еще раз проанализируйте текст программы и результат ее выполнения.
В строке 14 указателю pAge присваивается адрес переменной yourAge. После этого на экран выводятся новые значения и адреса переменных. Проанализировав результат программы, можно убедиться, что указатель pAge действительно содержит адрес переменной youtAge, а с помощью разыменования этого указателя можно получить ее значение.
Строка 19 выводит на экран значение адреса указателя pAge. Как любая другая переменная, указатель также имеет адрес, значение которого может храниться в другом указателе. О хранении в указателе адреса другого указателя речь пойдет несколько позже.