Чтение онлайн

на главную - закладки

Жанры

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

Указатель на массив или массив указателей

Рассмотрим следующие три объявления:

1: Cat Family0ne[500];

2: CAT >> FamilyTwo[500];

3: CAT * FamilyThree = new CAT[500];

В первом случае объявляется массив FamilyOne, содержащий 500 объектов типа CAT. Во втором случае — массив FamilyTwo, содержащий 500 указателей на объекты класса CAT, и в третьем случае — указатель FamilyThree, ссылающийся на массив из 500 объектов класса CAT.

В зависимости от того, какое объявление используется в программе, принципиально меняются

способы управления массивом. Как ни странно, но указатель FamilyThree по сути своей гораздо ближе к массиву FamilyOne, но принципиально отличается от массива указателей FamilyTwo.

Чтобы разобраться в этом, следует внимательно рассмотреть, что содержат в себе все эти переменные. Указатель на массив FamilyThree содержит адрес первого элемента массива, но ведь это именно то, что содержит имя массива FamilyOne.

Имена массивов и указателей

В C++ имя массива представляет собой константный указатель на первый элемент массива. Другими словами, в объявлении

CAT Family[50];

создается указатель Family на адрес первого элемента массива &Family[0].

В программе допускается использование имен массивов как константных указателей и наоборот. Таким образом, выражению Family + 4 соответствует обращение к пятому элементу массива Family[4].

Компилятор выполняет с именами массивов те же математические действия сложения, инкремента и декремента, что и с указателями. В результате операция Family + 4 будет означать не прибавление четырех байтов к текущему адресу, а сдвиг на четыре объекта. Если размер одного объекта равен четырем байтам, то к адресу в имени массива будут добавлены не 4, а 16 байт. Если в нашем примере каждый объект класса CAT содержит четыре переменные-члена типа long по четыре байта каждая и две переменные-члена типа short по два байта каждая, то размер одного элемента массива будет равен 20 байт и операция Family + 4 сдвинет адрес в имени указателя на 80 байт.

Объявление массива в динамической области памяти и его использование показано в листинге 12.7.

Листинг 12.7. Создание массива с использованием ключевого слова new

1: // Листинг 12.7. Массив в динамической области памяти

2:

3: #include <iostream.h>

4:

5: class CAT

6: {

7: public:

8: CAT { itsAge = 1; itsWeight=5; }

9: ~CAT;

10: int GetAge const { return itsAge; }

11: int GetWeight const { return itsWeight; }

12: void SetAge(int age) { itsAge = age; }

13:

14: private:

15: int itsAgo;

16: int itsWeight;

17: };

18:

19: CAT::~CAT

20: {

21: // cout << "Destructor called!\n";

22: }

23:

24: int main

25: {

26: CAT * Family = new CAT[500];

27: int i;

28:

29: for (i = 0; i < 500; i++)

30: {

31: Family[i].SetAge(2*i +1);

32: }

33:

34: for (i = 0; i < 500; i++)

35: {

36: cout << "Cat #" << i+1 << ": ";

37: cout << Family[i].GetAge << endl;

38: }

39:

40: delete [] Family;

41:

42: return 0;

43: }

Результат:

Cat #1: 1

Cat #2: 3

Cat #3: 5

...

Cat #499: 997

Cat #500: 999

Анализ:

В строке 26 объявляется массив Family для пятисот объектов класса CAT. Благодаря использованию выражения new CAT[500] весь массив сохраняется в области динамической памяти.

Удаление массива из области динамической памяти

Куда деваются при удалении массива все эти объекты класса CAT, показанные в предыдущем разделе? Не происходит ли здесь утечка памяти? Удаление массива Family с помощью оператора delete[ ] (не забудьте установить квадратные скобки) освобождает все ячейки памяти, отведенные для него. Компилятор достаточно сообразительный, чтобы удалить из памяти все объекты удаляемого массива и освободить динамическую память для нового использования.

Чтобы убедиться в этом, измените размер массива в предыдущей программе с 500 на 10 в строках 26, 29 и 34. Затем разблокируйте выражение в строке 21 с оператором cout и запустите программу. Когда будет выполнена строка 43, последует десять вызовов деструктора для удаления каждого объекта класса CAT в массиве Family.

Создавая какой-либо объект в области динамической памяти с помощью ключевого слова new, всегда удаляйте его из памяти с помощью оператора delete, если этот объект больше не используется в программе. В случае создания массива в области динамического обмена выражением new <class>[size] удалять его из памяти нужно оператором delete[]. Квадратные скобки указывают, что удаляется весь массив.

Если вы забудете установить квадратные скобки, то из памяти будет удален только первый объект массива. В этом можно убедиться, если в нашем примере программы удалить квадратные скобки в строке 38. Если уже были внесены изменения в строку 21, как указывалось выше, то при выполнении программы на экране отобразится вызов только одного деструктора объекта, который удалит первый объект массива. Поздравляем вас! Вы потеряли огромный блок памяти для дальнейшего использования программой.

Рекомендуется:Помните, что для обращения к массиву из n элементов используются индексы от 0 до n-1. Используйте свойства математических операций с указателями для управления доступом к элементам массива.

Не рекомендуется:Не записывайте данные за пределы массива. Не путайте массив указателей с указателем на массив.

Массивы символов

Строка текста представляет собой набор символов. Все строки, которые до сих пор использовались нами в программах, представляли собой безымянные строковые константы, используемые в выражениях с оператором cout, такие как:

cout << "hello world.\n";

Поделиться:
Популярные книги

Попаданка в деле, или Ваш любимый доктор

Марей Соня
1. Попаданка в деле, или Ваш любимый доктор
Фантастика:
фэнтези
5.50
рейтинг книги
Попаданка в деле, или Ваш любимый доктор

Своя правда

Шебалин Дмитрий Васильевич
2. Чужие интересы
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Своя правда

Барон ненавидит правила

Ренгач Евгений
8. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Барон ненавидит правила

Дружба народов

Сухов Лео
5. Антикризисный Актив
Фантастика:
героическая фантастика
попаданцы
5.00
рейтинг книги
Дружба народов

Скандальный развод, или Хозяйка владений "Драконье сердце"

Милославская Анастасия
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Скандальный развод, или Хозяйка владений Драконье сердце

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Неудержимый. Книга XIX

Боярский Андрей
19. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIX

Волков. Гимназия №6

Пылаев Валерий
1. Волков
Фантастика:
попаданцы
альтернативная история
аниме
7.00
рейтинг книги
Волков. Гимназия №6

Буря соперничества

Мазуров Дмитрий
4. Громовая поступь
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Буря соперничества

Кровь на клинке

Трофимов Ерофей
3. Шатун
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Кровь на клинке

Ну, здравствуй, перестройка!

Иванов Дмитрий
4. Девяностые
Фантастика:
попаданцы
альтернативная история
6.83
рейтинг книги
Ну, здравствуй, перестройка!

Небо в огне. Штурмовик из будущего

Политов Дмитрий Валерьевич
Военно-историческая фантастика
Фантастика:
боевая фантастика
7.42
рейтинг книги
Небо в огне. Штурмовик из будущего

Последняя жена Синей Бороды

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Последняя жена Синей Бороды

На границе империй. Том 9. Часть 3

INDIGO
16. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 3