10. Выполните задания 5, 6 и 8, используя класс vector
, а не массив, и функцию print_vector()
вместо функции print_array()
.
Вторая часть задания посвящена указателям и их связи с массивами. Используйте функцию print_array()
из последнего задания.
1. Разместите в свободной памяти переменную типа int
, инициализируйте ее число 7 и присвойте ее адрес указателю p1
.
2. Выведите на печать значения указателя p1
и переменной типа int
, на которую он ссылается.
3. Разместите в свободной памяти массив, состоящий из семи чисел типа int
; инициализируйте его числами 1, 2, 4, 8 и т.д.; присвойте адрес массива указателю p2
.
4. Выведите на печать значение указателя p2
и массив, на который он ссылается.
5. Объявите указатель типа int*
с именем p3
и инициализируйте его значением указателя p2
.
6. Присвойте указатель p1
указателю p2
.
7. Присвойте указатель p3
указателю p2
.
8. Выведите на печать значения указателей p1
и p2
, а также то, на что они ссылаются.
9. Освободите всю память, которую использовали.
10. Разместите в свободной памяти массив, состоящий из десяти чисел типа int
; инициализируйте их числами 1, 2, 4, 8 и т.д.; присвойте его адрес указателю p1
.
11. Разместите в свободной памяти массив, состоящий из десяти чисел типа int
, присвойте его адрес указателю p2
.
12. Скопируйте значения из массива, на который ссылается указатель p1
, в массив, на который ссылается указатель p2
.
13. Повторите задания 10–12, используя класс vector
, а не массив.
Контрольные вопросы
1. Зачем нужны структуры данных с переменным количеством элементов?
2. Назовите четыре вида памяти, используемой в обычных программах.
3. Что такое свободная память? Как еще ее называют? Какие операторы работают со свободной памятью?
4. Что такое оператор разыменования и зачем он нужен?
5. Что такое адрес? Как язык С++ манипулирует с адресами?
6. Какую информацию об объекте несет указатель, который на него ссылается? Какую полезную информацию он теряет?
7. На что может ссылаться указатель?
8. Что такое утечка памяти?
9. Что такое ресурс?
10. Как инициализировать указатель?
11. Что такое нулевой указатель? Зачем он нужен?
12. Когда нужен указатель (а не ссылка или именованный объект)?
13. Что такое деструктор? Когда он нужен?
14. Зачем нужен виртуальный деструктор?
15. Как вызываются деструкторы членов класса?
16. Что такое приведение типов? Когда оно необходимо?
17. Как получить доступ к члену класса с помощью указателя?
18. Что такое двусвязный список?
19. Что собой представляет переменная this
и когда она нужна?
Термины
Упражнения
1. Какой формат вывода значений указателя в вашей реализации языка? Подсказка: не читайте документацию.
2. Сколько байтов занимают типы int
, double
и bool
? Ответьте на вопрос, не используя оператор sizeof
.
3. Напишите функцию void to_lower(char* s)
, заменяющую все прописные символы в строке s
в стиле языка С на их строчные эквиваленты. Например, строка “Hello, World!
” примет вид “hello, world!
”. Не используйте стандартные библиотечные функции. Строка в стиле языка С представляет собой массив символов, который завершается нулем, поэтому если вы обнаружите символ 0
, то это значит, что вы находитесь в конце массива.
4. Напишите функцию char* strdup(const char*)
, копирующую строку в стиле языка C в свободную память одновременно с ее выделением. Не используйте стандартные библиотечные функции.
5. Напишите функцию char* findx(const char* s,const char* x)
, находящую первое вхождение строки x
в стиле языка C в строку s
.
6. В этой главе ничего не говорилось о том, что произойдет, если, используя оператор new
, вы выйдете за пределы памяти. Это называется
7. Напишите программу, считывающую символы из потока cin
в массив, расположенный в свободной памяти. Читайте отдельные символы, пока не будет введен знак восклицания (!
). Не используйте класс std::string
. Не беспокойтесь об исчерпании памяти.
8. Выполните упр. 7 еще раз, но теперь считывайте символы в строку std::string
, а не в свободную память (класс string
знает, как использовать свободную память). 9. Как увеличивается стек: вверх (в сторону старших адресов) или вниз (в сторону младших адресов)? В каком направлении возрастает занятая память изначально (т.е. пока вы не выполнили оператор delete
)? Напишите программу, позволяющую выяснить это.