Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Указатели, адреса и переменные
Чтобы овладеть навыками программирования на 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 мы обращаемся к этому значению непосредственно (через переменную) и путем разыменования указателя на нее.
Использование адреса, хранящегося в указателе
При работе с указателями в большинстве случаев не приходится иметь дело со значениями адресов, записанных в указателях. В предыдущих разделах отмечалось, что после присвоения указателю адреса переменной значением указателя будет именно этот адрес. Почему бы не проверить это утверждение? Для этого можно воспользоваться программой, приведенной в листинге 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. Как любая другая переменная, указатель также имеет адрес, значение которого может храниться в другом указателе. О хранении в указателе адреса другого указателя речь пойдет несколько позже.
Рекомендуется: Используйте оператор разыменовывания (*) для получения доступа к данным, сохраненным по адресу, содержащемуся в указателе. Инициализируйте указатель нулевым значением при объявлении, если заранее не известно, для указания на какую переменную он будет использоваться. Помните о разнице между адресом в указателе и значением переменной, на которую ссылается этот указатель.
Использование указателей Чтобы объявить указатель, запишите вначале тип переменной или объекта, на который будет ссылаться этот указатель, затем поместите символ звездочки (*), а за ним — имя нового указателя, например: unsigned short int * pPointer =0; Чтобы присвоить указателю адрес переменной, установите перед именем переменной оператор адреса (&), как в следующем примере: unsigned short int theVariable = 5; unsigned short int * pPointer = & theVariable; Чтобы разыменовать указатель, установите перед его именем оператор разыменовывания (*): unsigned short int theValue = *pPointer
Для чего нужны указатели
В предыдущих разделах мы детально рассмотрели процедуру присвоения указателю адреса другой переменной. Однако на практике такое использование указателей встречается достаточно редко. К тому же, зачем задействовать еще и указатель, если значение уже хранится в другой переменной? Рассмотренные выше примеры приведены только для демонстрации механизма работы указателей. Теперь, после описания синтаксиса, используемого в C++ для работы с указателями, можно переходить к более профессиональному их применению. Наиболее часто указатели применяются в следующих случаях: • для размещения данных в свободных областях памяти и доступа к ним; • для доступа к переменным и функциям классов; • для передачи параметров в функции по ссылке. Оставшаяся часть главы посвящена динамическому управлению данными и операциям с переменными и функциями классов.
|
||||||
Последнее изменение этой страницы: 2016-12-10; просмотров: 507; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.218.127.141 (0.008 с.) |