- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Освой самостоятельно за 21 день - Джесс Либерти
Шрифт:
Интервал:
Закладка:
Оператор разыменовывания
Оператор косвенного обращения (или оператор разыменования) позволяет получить значение, хранящееся по адресу, записанному в указателе.
В отличие от указателя, при обращении к обычной переменной осуществляется доступ непосредственно к ее значению. Например, чтобы объявить новую переменную типа 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 << "nn";
14: cout << "*pAge = 7n";
15: *pAge = 7; // присваиваем myAge значение 7
16: cout << "*pAge: " << *pAge << "n";
17: cout << "myAge: " << myAge << "nn";
18: cout << "myAge = 9n";
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;