Как сделать трехмерный массив

Обновлено: 08.07.2024

Ответы на вопросы создания многомерных массивов есть в просторах интернета. Ответы на вопросы о создании трёхмерных, четырёхмерных и более многомерных массивов выступают в качестве притесняемого меньшинства. На самом деле трёхмерные и более мерные массивы не так уж и нужны. Они не очень удобны, их сложно обрабатывать.

Можно использовать или чистый трёхмерный массив, или эмулировать трёхмерный массив с помощью указательных переменных. Алгоритм эмуляции указателями многомерных массивов в принципе один и тот же: сначала выделяется память основной указательной переменной, указывающей на массив. Для каждой внутренней указательной переменной выделяется собственная память. И пока указатели указывают на указатели — так и выделяется память каждому указателю.

  • Любой многомерный массив — это массив массивов.

Поскольку трёхмерный массив — это массив двумерных массивов, а любой двумерный массив легко представлять в виде таблицы, вы видите на экране массив таблиц. Если у вас консольное окно узкое, то вывод произойдёт не очень красиво, нужно будет изменить ширину в свойствах окна консоли. Если у вас Borland C++3.1 или что-то похожее, то вы не сможете в полной мере насладиться красивым видом массива таблиц. При первых попытках запусков программ, создаваемых из показанных кодов, не задавайте слишком большие числа, иначе в третьем, например, варианте, у вас вывод на экран может происходить больше суток, если так получится, что суммарно ячеек будет нужно слишком много.

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

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

Благодаря использованию свойств указателей мы получили возможность задавать, сколько таблиц должен хранить наш массив. Для этого мы использовали добавление одной звёздочки.

  • То, что написано ниже — это для саморазвития. Будете делать на практике, оторвут уши и руки.

В случае добавления ещё одной звёздочки можно будет и задавать количество таблиц, и хранить таблицы с разным числом строк:

Операция new должна разобраться, какая из размерностей динамическая и что здесь есть указатель. Из-за синтаксической особенности типа массива приходится выделывать такие страшные штуки, которые были проделаны при выделении памяти. Тут сложности с тем, что могут быть массивы указателей, указатели на массивы указателей, массивы указателей на указатели, массивы указателей, указывающих на массивы и много ещё чего, а компилятор должен точно знать, чего мы от него хотим.

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

Если использовать все три звёздочки, то можно задавать и количество строк для каждой таблицы, и количество колонок для каждой строки таблицы. Но я немного в упрощённом варианте покажу. В моём случае для каждой конкретной таблицы будет задаваться определённое число строк и определённое для конкретной таблицы число колонок:

Основная возможная сложность, которая идёт за осознанием природы указателей и массивов — может быть в том, что нужно дополнительно отслеживать, сколько в таблице вообще строк и сколько колонок в каждой отдельной строке таблицы. Поскольку у меня немного упрощённый вариант, я отслеживаю количество колонок не для каждой отдельной строки, а только для конкретной таблицы. Но развить можно таким образом, чтобы у каждой строки было своё число колонок, тогда таблицы мало будут похожи на таблицы.

Но ещё раз напоминаю, что делать таких вещей совсем не нужно (если только для спортивного интереса в самом глубоком бомбоубежище, чтобы никто вас не застал за этим грязным делишком). Эти примеры даны вам больше для того, чтобы вы получили некоторое представление о работе указателей и массивов, получили некоторое представление о трёхмерном массиве, который задаётся с помощью указателей, чтобы поняли в чём сложности работы с указательными переменными и поняли некоторые другие вещи. Даже когда вы поймёте, как эти примеры работают, почему они работают, и когда сможете сами писать такие же коды, писать таким образом ни в коем случае не нужно: если есть большое желание решить задачу, требующую похожих поведений, и хочется использовать именно показанный в этой статье способ, вам нужно переосмыслить вариант решения, наверняка найдётся что-то проще, читабельней и понятнее всем, чем то, что показывал я сейчас.

Эта статья не затрагивает массивы двухуровневых указателей и двумерные массивы указателей, но эти массивы тоже возможно трактовать как трёхмерные и использовать их при определённых нуждах, но как и ранее, указателей имеет смысл избегать, особенно многоуровневых указательных сущностей. В подавляющем большинстве случаев вам может хватить или обычного трёхмерного массива, размерности которому задаются сразу в исходном коде программы, или одноуровневого указателя на двухмерный массив, чтобы можно было сообщать в ходе работы программы, какой нужна первая (слева) мерность трёхмерному массиву. Всё остальное от лукавого.

Я в книге нашел два способа выделения памяти для динамических массивов и использовал вот этот int (*a)[6][5]= new int [3][6][5];

Правда там был пример для двухмерного дин. массива, но методом тыка я переделал под трехмерный.

Так вот по условию задачи мне нужно увеличить индексация начального элемента на 1 (из [0][0][0] сделать [1][1][1]).
Для одномерного массива я писал бы а+=1, но тут эта строка меняет лишь номер матрицы (из [0][0][0] делает [1][0][0]).
Кто знаком с такой конструкцией и принято ли ею пользоваться ?

Это указатель на начало массива двумерных массивов [6][5], т.е. это как массив из массивов [6][5].(только оно не массив, а указатель на набор массивов [6][5]. Это важно).
int (*a)[6][5] = new int[3] -> здесь а становится массивом с тремя значениями, каждое из которых массив фиксированного размера [6][5].
a[0] — массив[6][5], a[1] — массив[6][5], a[2] — массив [6][5]

Индексное выражение также может иметь несколько индексов, как показано ниже:

Индексные выражения связываются в направлении слева направо. Сначала вычисляется левое индексное выражение, expression1[expression2]. Адрес, получающийся в результате сложения expression1 и expression2, формирует выражение указателя. Затем к этому выражению указателя добавляется выражение expression3, чтобы образовать новое выражение указателя. Эти операции повторяются до тех пор, пока не будет добавлено последнее индексное выражение. После вычисления последнего индексного выражения выполняется оператор косвенного обращения (*), если конечное значение указателя не указывает на тип массива (см. примеры ниже).

Выражения с несколькими индексами ссылаются на элементы "многомерных массивов". Многомерный массив — это массив, элементы которого являются массивами. Например, первый элемент трехмерного массива является двумерным массивом.

Примеры

В следующих примерах массив с именем prop объявляется с тремя элементами, каждый из которых представляет собой массив 4x6, содержащий значения типа int .

Ссылка на массив prop выглядит следующим образом:

В приведенном выше примере показано, как ссылаться на второй отдельный элемент int массива prop . Массивы хранятся по строкам, поэтому последний индекс изменяется быстрее; выражение prop[0][0][2] ссылается на следующий (третий) элемент массива и т. д.

Этот оператор представляет собой более сложную ссылку на отдельный элемент массива prop . Выражение вычисляется следующим образом.

Первый индекс, 2 , умножается на размер массива int 4x6 и добавляется к значению указателя prop . Результат указывает на третий массив 4x6 массива prop .

Второй индекс, 1 , умножается на размер 6-элементного массива int и добавляется к адресу, представленному значением prop[2] .

Каждый элемент 6-элементного массива является значением типа int , поэтому конечный индекс, 3 , перед добавлением к выражению int умножается на размер prop[2][1] . Результирующий указатель указывает на четвертый элемент 6-элементного массива.

Оператор косвенного обращения применяется к значению указателя. Результат — элемент int , расположенный по этому адресу.

Ниже приведены два примера, в которых оператор косвенного обращения не применяется.

В первом из показанных операторов выражение prop[2][1] представляет собой допустимую ссылку на трехмерный массив prop ; эта ссылка относится к 6-элементному массиву (объявленному выше). Поскольку значение указателя указывает на массив, оператор косвенного обращения не применяется.

Аналогично результат выражения prop[2] во втором операторе ipp = prop[2]; представляет значение указателя, указывающее на двумерный массив.


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

Зубчатые массивы создаются в два этапа:

  • Сначала создается шаблон с фиксированным количеством строк по следующему синтаксису тип[][] имя = new тип[размер][];
  • Затем для каждой строки создается одномерный массив того же типа с заданным количеством элементов

В зубчатом двумерном массиве имеется два свойства Length. Если это свойство применить к самому массиву, то оно означает количество строк. Если его применить к отдельной строке, то оно будет означать длину этой строки.

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

2. Какая общая форма объявления многомерного массива?

Общая форма объявления многомерного массива следующая:

  • тип – непосредственно тип элементов массива;
  • размер1 , размер2 , размерN – размерность каждого измерения массива. Значение N означает, что массив N -мерный.

3. Пример объявления и использования двумерного массива вещественных чисел размером 3×4

В примере объявляется двумерный массив вещественных чисел, которые имеют тип float

4. Пример объявления и использования трехмерного массива целых чисел размером 3×4×5

5. Как выглядит общая форма инициализации многомерного массива?

Инициализация массива позволяет записать значения в ячейки массива в момент его объявления в программе.

Общая форма инициализации многомерного массива имеет следующий вид:

  • тип – тип элементов массива;
  • значение – значение, которыми инициализируются элементы массива.

6. Пример инициализации двумерного массива размером 5×3. Элементы массива имеют тип char

7. Пример инициализации трехмерного массива целых чисел размером 2×3×4

8. Что такое ступенчатый массив? Какая общая форма объявления ступенчатого массива?

Двумерные массивы могут быть двух видов:

  • прямоугольный массив в виде таблицы;
  • ступенчатый массив. В этом массиве количество элементов каждой строки (массива) может отличаться. Ступенчатый массив еще называют массивом массивов.

Общая форма объявления ступенчатого массива:

  • тип – тип элементов массива;
  • размер – количество строк в массиве.

9. Пример объявления и использования ступенчатого массива

Как видно из примера, доступ к элементам ступенчатого массива происходит иначе чем в прямоугольном массиве.

10. В каких случаях целесообразно использовать ступенчатые массивы?

Ступенчатые массивы являются эффективными в случаях, если у двумерных прямоугольных массивов есть много элементов, которые вообще не используются. Это позволяет сэкономить память за счет выделения только необходимого объема памяти (количества элементов) для каждой строки ступенчатого массива.

На рисунке 1 отображено преимущество применения ступенчатых массивов в сравнении с прямоугольными. Продемонстрирована возможная экономия памяти в случае, когда данные представляются прямоугольным массивом в котором все элементы некоторых строк (0, 2, 3, 4) не используются.

Способ 1. Объявление прямоугольного массива с именем M .

Способ 2. Объявление ступенчатого массива.

Рис. 1. Пример экономии памяти с помощью ступенчатого массива из 5 строк в сравнении с прямоугольным массивом размером 5×100

11. Каким образом реализовать массив двумерных массивов? Пример

В примере реализуется массив двумерных массивов с именем M . Массив имеет 10 строк. В каждой строке формируется двумерный массив размером 3×4.

Читайте также: