3D-массив С++ с использованием оператора int []
Я новичок в C/С++, и я взломал голову, но до сих пор не знаю, как создать "структуру", подобную этой
![alt text]()
Он должен быть трехмерным динамическим массивом с помощью указателей.
Я начал так, но застрял там
int x=5,y=4,z=3;
int ***sec=new int **[x];
Достаточно было бы знать, как сделать это для статического размера y и z;
Пожалуйста, я был бы признателен, что вы мне поможете.
Спасибо заранее.
Ответы
Ответ 1
Чтобы создать динамически 3D массив целых чисел, лучше сначала понять 1D и 2D-массив.
1D массив: вы можете сделать это очень легко
const int MAX_SIZE=128;
int *arr1D = new int[MAX_SIZE];
Здесь мы создаем int-pointer, который укажет на кусок памяти, где целые числа могут быть сохранены.
2D-массив. Вы можете использовать решение выше 1D-массива для создания 2D-массива. Сначала создайте указатель, который должен указывать на блок памяти, где хранятся только другие целые указатели, которые в конечном счете указывают на фактические данные. Поскольку наш первый указатель указывает на массив указателей, поэтому он будет вызываться как указатель на указатель (двойной указатель).
const int HEIGHT=20;
const int WIDTH=20;
int **arr2D = new int*[WIDTH]; //create an array of int pointers (int*), that will point to
//data as described in 1D array.
for(int i = 0;i < WIDTH; i++){
arr2D[i] = new int[HEIGHT];
}
3D-массив. Это то, что вы хотите сделать. Здесь вы можете попробовать как схему, используемую в двух предыдущих случаях. Примените ту же логику, что и 2D-массив. Диаграмма, о которой идет речь, объясняет все. Первый массив будет указателем на указатель на указатель (int *** - поскольку он указывает на двойные указатели). Решение выглядит следующим образом:
const int X=20;
const int Y=20;
const int z=20;
int ***arr3D = new int**[X];
for(int i =0; i<X; i++){
arr3D[i] = new int*[Y];
for(int j =0; j<Y; j++){
arr3D[i][j] = new int[Z];
for(int k = 0; k<Z;k++){
arr3D[i][j][k] = 0;
}
}
}
Ответ 2
// one-liner
typedef std::vector<std::vector<std::vector<int> > > ThreeDimensions;
// expanded
typedef std::vector<int> OneDimension;
typedef std::vector<OneDimension> TwoDimensions;
typedef std::vector<TwoDimension> ThreeDimensions;
(в конце концов, это помечено как С++)
EDIT в ответ на вопрос Джо
привет снова Джо =) уверен. вот пример:
#include <vector>
#include <iostream>
int main(int argc, char* const argv[]) {
/* one-liner */
typedef std::vector<std::vector<std::vector<int> > >ThreeDimensions;
/* expanded */
typedef std::vector<int>OneDimension;
typedef std::vector<OneDimension>TwoDimensions;
typedef std::vector<TwoDimensions>ThreeDimensions;
/*
create 3 * 10 * 25 array filled with '12'
*/
const size_t NElements1(25);
const size_t NElements2(10);
const size_t NElements3(3);
const int InitialValueForAllEntries(12);
ThreeDimensions three_dim(NElements3, TwoDimensions(NElements2, OneDimension(NElements1, InitialValueForAllEntries)));
/* the easiest way to assign a value is to use the subscript operator */
three_dim[0][0][0] = 11;
/* now read the value: */
std::cout << "It should be 11: " << three_dim[0][0][0] << "\n";
/* every other value should be 12: */
std::cout << "It should be 12: " << three_dim[0][1][0] << "\n";
/* get a reference to a 2d vector: */
TwoDimensions& two_dim(three_dim[1]);
/* assignment */
two_dim[2][4] = -1;
/* read it: */
std::cout << "It should be -1: " << two_dim[2][4] << "\n";
/* get a reference to a 1d vector: */
OneDimension& one_dim(two_dim[2]);
/* read it (this is two_dim[2][4], aka three_dim[1][2][4]): */
std::cout << "It should be -1: " << one_dim[4] << "\n";
/* you can also use at(size_t): */
std::cout << "It should be 12: " << one_dim.at(5) << "\n";
return 0;
}
Ответ 3
Вы можете попробовать:
for(int i=0;i<x;i++) {
sec[i] = new int *[y];
for(int j=0;j<y;j++) {
sec[i][j] = new int [z];
}
}
И как только вы закончите использовать эту память, вы можете освободить ее как:
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
delete [] sec[i][j];
}
delete [] sec[i];
}
delete [] sec;
Ответ 4
Комплексные ответы.
Если вы действительно пишете это на С++ (не грубо C), я думаю, вам стоит взглянуть на эту сложную структуру данных. Редизайн IMO, учитывая то, что вы пытаетесь сделать, будет лучше.
Ответ 5
То, что вы пытаетесь сделать, не является идиоматическим в С++. Конечно, для этого вы можете использовать int***pointer
, но это настоятельно не рекомендуется. В С++ у нас есть лучшие способы добраться туда.
vector<vector<vector<int> > > foo (5,vector<vector<int> >(4, vector<int>(3)));
Это приведет к чему-то, с расположением памяти, аналогичным тому, что вы просили. Он поддерживает динамическое изменение размера и внутренние векторы, чтобы иметь разные размеры, как на картинке. Кроме того, вам не нужно беспокоиться о ручном распределении/удалении любого из них. Кроме того, векторы знают свой размер, поэтому вам не нужно его где-то помнить.
Но если вы просто хотите "прямоугольный" 3D-массив, где все элементы последовательно хранятся в одном блоке памяти, вы можете использовать boost:: multiarray.
Ответ 6
OK давайте начнем ваши начинания
int ***sec = new int**[x];
sec теперь является массивом int ** s длины x, поэтому теперь я собираюсь сосредоточиться на том, чтобы сделать элемент zeroeth тем, что вы хотите
sec[0] = new int*[y];
Теперь sec [0] указывает на массив int * s длины y, теперь просто нужно получить последний бит дерева, поэтому
sec[0][0] = new int[z];
И наконец, чтобы получить его в форме на диаграмме
sec[0][0][z-1] = 0;
Это похоже на вопрос о домашнем задании, убедитесь, что вы действительно понимаете ответ и почему он работает.
Ответ 7
Если это реальные массивы, у вас возникли проблемы с просмотром здесь: Объявление указателя на многомерный массив и выделение массива
Не уверен, что именно вы хотите, но вы можете прочитать о связанных списках.