Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Инициализация многомерного массива

Поиск

 

Многомерный массив также можно инициализировать одновременно с объявлением. При этом следует учитывать, что сначала весь цикл значений проходит индекс, указанный последним, после чего изменяется предпоследний индекс. Таким образом, если есть массив

int theArray[5][3]:

то первые три значения будут записаны в массив theArray[0], вторые три значения — в массив theArray[1] и т.д.

Указанный массив можно инициализировать следующей строкой:

int theArray[5][3] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

Чтобы не запутаться в числах, значения можно сгруппировать с помошью дополнительных фигурных скобок, например:

int theArray[5][3] = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15}};

Компилятор проигнорирует все внутренние фигурные скобки. Все значения должны быть разделены запятыми независимо от того, используете вы дополнительные фигурные скобки или нет. Весь список значений должен быть заключен во внешние фигурные скобки, и после закрывающей скобки обязательно устанавливается символ точки с запятой.

Пример создания двухмерного массива показан в листинге 12.5. Первый ряд двухмерного массива содержит целые числа от 0 до 4, а второй — удвоенные значения соответствующих элементов первого ряда.

Листинг 12.5. Создание многомерного массива

1: #include <iostream.h>

2: int main()

3: {

4: int SomeArray[5][2] = { { 0,0}, { 1,2}, { 2,4}, { 3,6}, { 4,8} }

5: for (int t = 0; i<5; i++)

6: for (int j=0; j<2; j++)

7: {

8: cout << "SomeArray[" << i << "][" << j << "]: ";

9: cout << SomeArray[i][j]<< endl;

10: }

11:

12: return 0;

13: }

 

Реультат:

SomeArray[0][0]: 0 ' '' " SomeArray[0][1]: 0 SomeArray[1][0]: 1 SomeArray[1][1]: 2 SomeArray[2][0]: 2 SomeArray[2][1]: 4 SomeArray[3][0]: 3 SomeArray[3][1]: 6 SomeArray[4][0]: 4 SomeArray[4][1]: 8

 

Анализ: В строке 4 объявляется двухмерный массив. Первый ряд содержит пять целочисленных значений, а второй ряд представлен двумя значениями. В результате создается конструкция из десяти элементов (5x2), как показано на рис. 12.4.

 

Рис. 12.4. Массив 5x2

 

Данные вводятся в массив попарно, хотя их можно было записать одной строкой. Затем осуществляется вывод данных с помощью двух вложенных циклов for. Внешний цикл последовательно генерирует индексы первого ряда, а внутренний — индексы второго ряда. В такой последовательности данные выводятся на экран: сначала идет элемент SomeArray[0][0], затем элемент SomeArray[0][1]. Приращение индекса первого ряда происходит после того, как индекс второго ряда становится равным 1, после чего вновь дважды выполняется внутренний цикл.

 

Несколько слов о памяти

 

При объявлении массива компилятору точно указывается, сколько объектов планируется в нем сохранить. Компилятор зарезервирует память для всех объектов массива, даже если далее в программе они не будут заданы. Если вы заранее точно знаете, сколько элементов должен хранить массив, то никаких проблем не возникнет. Например, шахматная доска всегда имеет только 64 клетки, а от кошки можно ожидать, что она не родит более 10 котят. Если же изначально неизвестно, сколько элементов будет в массиве, то для решения этой проблемы нужно использовать более гибкие средства управления памятью.

В этой книге рассматриваются только некоторые дополнительные средства программирования, такие как массивы указателей, массивы с резервированием памяти в области динамического обмена и ряд других возможностей. Больше информации о средствах программирования, открывающих дополнительные возможности, можно прочитать в моей книге C++ Unleashed, выпущенной издательством Sams Publishing. И вообще, всегда следует помнить, что каким бы хорошим программистом вы ни были, всегда остается то, чему следовало бы научиться, и всегда есть источники, откуда можно почерпнуть новую свежую информацию.

 

Массивы указателей

 

Все массивы, рассмотренные нами до сих пор, хранили значения своих элементов в стеках памяти. Использование стековой памяти связано с рядом ограничений, которых можно избежать, если обратиться к более гибкой области динамической памяти. Это можно сделать, если сначала сохранить все объекты массива в области динамической памяти, а затем собрать в массиве указатели на эти объекты. Этот подход значительно сократит потребление программой стековой памяти компьютера. В листинге 12.6 показан тот же массив, с которым мы работали в листинге 12.4, но теперь все его объекты сохранены в области динамической памяти. Чтобы показать возросшую эффективность использования памяти программой, в этом примере размер массива был увеличен с 5 до 500 и его название изменено с Litter (помет) на Family (семья).

Листинг 12.6. Сохранение массива в области динамической памяти

1: // Листинг 12.6. Массив указателей на обьекты 2:

3: #include <iostream.h>

4:

5: class CAT

6: {

7: public:

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

9: ~CAT() { } // destructor

10: int GetAge() const { return itsAge; }

11: int GetWeight() const { return itsWeight: }

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

13:

14: private:

15: int itsAge;

16: int itsWeight;

17: };

18:

19: int main()

20: {

21: CAT * Family[500];

22: int i;

23: CAT * pCat;

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

25: {

26: pCat = new CAT;

27: pCat->SetAge(2*i +1);

28: Family[i] = pCat;

29: }

30:

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

32: {

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

34: cout << Family[i]->GetAge() << endl;

35: }

36: return 0;

37: }

 

Результат:

Cat #1: 1

Cat #2: 3

Cat #3: 5

...

Cat #499: 997

Cat #500: 999

 

Анализ: Объявление класса CAT в строках 5—17 идентично объявлению этого клас- • ca в листинге 12.4. Но, в отличие от предыдущего листинга, в строке 21

объявляется массив Family, в котором можно сохранить 500 указателей на объекты класса CAT.

В цикле инициализации (строки 24-29) в области динамической памяти создается 500 новых объектов класса CAT, каждому из которых присваивается значение переменной itsAge, равное удвоенному значению индекса плюс один. Таким образом, первому объекту класса CAT присваивается значение 1, второму — 3, третьему — 5 и т.д. В этом же цикле каждому элементу массива присваивается указатель на вновь созданный объект.

Поскольку тип массива был объявлен как CAT*, в нем сохраняются именно указатели, а не их разыменованные значения.

Следующий цикл (строки 31—35) выводит на экран все значения объектов, на которые делаются ссылки в массиве. Обращение к указателю выполняется с помощью индекса: Family[i]. После того как элемент массива установлен, следует вызов метода GetAge().

В данном примере программы все элементы массива сохраняются в стековой памяти. Но в этот раз элементами являются указатели, тогда как сами объекты хранятся в области динамического обмена.

 



Поделиться:


Последнее изменение этой страницы: 2016-12-10; просмотров: 591; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.222.163.134 (0.01 с.)