3D массив C ++ с использованием оператора int [] - PullRequest
13 голосов
/ 11 октября 2010

Я новичок в C / C ++ и ломаю голову, но все еще не знаю, как создать такую ​​"структуру", как это

alt text

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

Я начал так, но застрял там

  int x=5,y=4,z=3;
  int ***sec=new int **[x];

Было бы достаточно знать, как сделать его для статического размера y иz;

Пожалуйста, я был бы признателен за помощь.

Заранее спасибо.

Ответы [ 7 ]

21 голосов
/ 11 октября 2010

Чтобы динамически создать трехмерный массив целых чисел, лучше сначала понять 1D и 2D массив.

1D массив : Вы можете сделать это очень легко с помощью

const int MAX_SIZE=128;
int *arr1D = new int[MAX_SIZE];

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

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 Array : это то, что вы хотитеделать.Здесь вы можете попробовать обе схемы, использованные в вышеупомянутых двух случаях.Применяйте ту же логику, что и 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;
       }
   }
}
11 голосов
/ 11 октября 2010
// 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;

(в конце концов, это тег c ++)

РЕДАКТИРОВАТЬ в ответ на вопрос Джо

привет снова Джо =) конечно. вот пример:

#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;
}
1 голос
/ 11 октября 2010

То, что вы пытаетесь сделать, не является идиоматическим в C ++. Конечно, вы можете использовать для этого int***pointer, но это настоятельно не рекомендуется. В C ++ у нас есть лучшие способы туда добраться.

vector<vector<vector<int> > > foo (5,vector<vector<int> >(4, vector<int>(3)));

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

Но если вам нужен просто "прямоугольный" 3D-массив, в котором все элементы последовательно хранятся в одном блоке памяти, вы можете использовать boost :: multiarray .

1 голос
/ 11 октября 2010

Комплексные ответы.

Если вы действительно пишете это на C ++ (не грубо на C), я думаю, вам следует еще раз взглянуть на эту сложную структуру данных. Редакция ИМО с учетом того, что вы пытаетесь сделать, была бы лучше.

1 голос
/ 11 октября 2010

Вы можете попробовать:

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;
0 голосов
/ 11 октября 2010

ОК, давайте начнем

int ***sec = new int**[x]; 

sec теперь массив int ** s длины x, поэтому сейчас я просто сосредоточусь на том, чтобы сделать нулевой элемент тем, что вы хотите

sec[0] = new int*[y];

Теперь sec [0] указывает на массив int * s длины y, теперь просто нужно получить последний бит дерева, поэтому

sec[0][0] = new int[z];

И, наконец, получить его в форме на диаграмме

sec[0][0][z-1] = 0;

Это похоже на домашнее задание, убедитесь, что вы действительно понимаете ответ и почему он работает.

0 голосов
/ 11 октября 2010

Если это фактические массивы, с которыми у вас возникли проблемы, посмотрите здесь: Объявление указателя на многомерный массив и выделение массива

Не совсем точно, что вы хотите, но вы можете захотетьчитать о связанных списках.

...