Pergunta

Como faço para declarar uma matriz 2d usando new?

Como, por uma matriz "normal" Eu faria:

int* ary = new int[Size]

e

int** ary = new int[sizeY][sizeX]

a) não trabalho / compilação e b) não realizar o que:

int ary[sizeY][sizeX] 

faz.

Foi útil?

Solução

array A dinâmica 2D é basicamente um conjunto de ponteiros para matrizes . Você pode inicializar-lo usando um loop, assim:

int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
    a[i] = new int[colCount];

A descrição acima, para colCount= 5 e rowCount = 4, deve produzir a seguinte:

enter descrição da imagem aqui

Outras dicas

int** ary = new int[sizeY][sizeX]

deve ser:

int **ary = new int*[sizeY];
for(int i = 0; i < sizeY; ++i) {
    ary[i] = new int[sizeX];
}

e, em seguida, limpar seria:

for(int i = 0; i < sizeY; ++i) {
    delete [] ary[i];
}
delete [] ary;

EDIT: como Dietrich Epp apontou nos comentários esta não é exatamente uma solução peso leve. Uma abordagem alternativa seria a utilização de um grande bloco de memória:

int *ary = new int[sizeX*sizeY];

// ary[i][j] is then rewritten as
ary[i*sizeY+j]

este populares resposta lhe dará a sua sintaxe indexação desejado, é duplamente ineficiente: grande e lento tanto no espaço e tempo. Há uma maneira melhor.

Por que essa resposta é grande e lenta

A solução proposta é a de criar uma matriz dinâmica de ponteiros, em seguida, inicializando cada ponteiro para a sua própria matriz dinâmica, independente. O vantagem desta abordagem é que ele dá-lhe a sintaxe de indexação que você está acostumado, por isso, se você quiser encontrar o valor da matriz na posição x, y, você diz:

int val = matrix[ x ][ y ];

Isto funciona porque matriz [x] retorna um ponteiro para uma matriz, que é depois indexado com [y]. Dividi-lo:

int* row = matrix[ x ];
int  val = row[ y ];

Conveniente, sim? Nós gostamos nosso [x] [y] sintaxe.

Mas a solução tem um grande desvantagem , o que é que é gordura e lento.

Por quê?

A razão que é gordura e lento é realmente o mesmo. Cada "linha" na matriz é uma matriz dinâmica alocada separadamente. Fazendo uma alocação de pilha é caro, tanto em tempo e espaço. O alocador leva tempo para efectuar a atribuição, às vezes correndo algoritmos O (n) para fazê-lo. E o alocador "almofadas" cada uma de suas matrizes fileira com bytes extras para contabilidade e alinhamento. Que os custos de espaço extra ... bem ... o espaço extra. O desalocador irá também levar tempo extra quando você vai para desalocar a matriz, meticulosamente livre-ing-se cada alocação linha individual. fica-me a suar só de pensar nisso.

Há uma outra razão é lento. Estas atribuições separadas tendem a viver em partes descontínuas de memória. Uma linha pode ser no endereço 1.000, outra no endereço 100.000 você começa a idéia. Isto significa que quando você está atravessando a matriz, você está saltando através da memória como uma pessoa selvagem. Isso tende a resultar em perdas de cache que muito abrandar o seu tempo de processamento.

Então, se você absoluto deve ter seu bonito [x] [y] sintaxe indexação, use essa solução. Se você quer rapidez e pequenez (e se você não se preocupam com aqueles, por que você está trabalhando em C ++?), Você precisa de uma solução diferente.

uma solução diferente

A melhor solução é alocar sua matriz inteira como uma única matriz dinâmica, então use (ligeiramente) matemática indexação inteligente de sua preferência para células de acesso. A matemática indexação é apenas muito ligeiramente inteligente; nah, não é inteligente em tudo: é óbvio

.
class Matrix
{
    ...
    size_t index( int x, int y ) const { return x + m_width * y; }
};

Dada esta função index() (que eu estou imaginando é um membro de uma classe, porque ele precisa saber o m_width de sua matriz), você pode acessar células dentro de sua matriz matriz. A matriz matriz é alocado como esta:

array = new int[ width * height ];

Então, o equivalente a isso na solução lento, gordura:

array[ x ][ y ]

... é isso na solução rápida, pequena:

array[ index( x, y )]

triste, eu sei. Mas você vai se acostumar com isso. E o seu CPU vai agradecer.

Em C ++ 11 é possível:

auto array = new double[M][N]; 

Desta forma, a memória não é inicializado. Para inicializar-lo fazer isso em vez disso:

auto array = new double[M][N]();

Exemplo de programa (compilação com "g ++ -std = C ++ 11"):

#include <iostream>
#include <utility>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;

int main()
{
    const auto M = 2;
    const auto N = 2;

    // allocate (no initializatoin)
    auto array = new double[M][N];

    // pollute the memory
    array[0][0] = 2;
    array[1][0] = 3;
    array[0][1] = 4;
    array[1][1] = 5;

    // re-allocate, probably will fetch the same memory block (not portable)
    delete[] array;
    array = new double[M][N];

    // show that memory is not initialized
    for(int r = 0; r < M; r++)
    {
        for(int c = 0; c < N; c++)
            cout << array[r][c] << " ";
        cout << endl;
    }
    cout << endl;

    delete[] array;

    // the proper way to zero-initialize the array
    array = new double[M][N]();

    // show the memory is initialized
    for(int r = 0; r < M; r++)
    {
        for(int c = 0; c < N; c++)
            cout << array[r][c] << " ";
        cout << endl;
    }

    int info;
    cout << abi::__cxa_demangle(typeid(array).name(),0,0,&info) << endl;

    return 0;
}

Output:

2 4 
3 5 

0 0 
0 0 
double (*) [2]

Eu presumo que com seu exemplo array estático que você quer uma matriz retangular, e não com uma denteada. Você pode usar o seguinte:

int *ary = new int[sizeX * sizeY];

Em seguida, você pode acessar elementos como:

ary[y*sizeX + x]

Não se esqueça de usar delete [] em ary.

Existem duas técnicas gerais que eu recomendaria para isso em C ++ 11 e acima, um para dimensões de tempo de compilação e um para tempo de execução. Ambas as respostas supor que você quer uniforme, matrizes bidimensionais (não os irregulares).

Compilar dimensões de tempo

Use um std::array de std::array e depois new uso para colocá-lo na pilha:

// the alias helps cut down on the noise:
using grid = std::array<std::array<int, sizeX>, sizeY>;
grid * ary = new grid;

Novamente, isso só funciona se os tamanhos das dimensões são conhecidos em tempo de compilação.

Executar dimensões de tempo

A melhor maneira de conseguir uma matriz dimensional 2 com tamanhos conhecidos apenas em tempo de execução é envolvê-lo em uma classe. A classe irá alocar uma matriz 1-D e em seguida, operator [] sobrecarregar para proporcionar a indexação para a primeira dimensão. Isso funciona porque em C ++ uma matriz 2D é da maior linha:

 matriz mostrado na forma lógica e forma unidimensional

(Tomado de http: // eli .thegreenplace.net / 2015 / memória de layout de-multi-dimensionais-matrizes / )

Uma seqüência contígua de memória é boa por razões de desempenho e também é fácil de limpar. Aqui está um exemplo de classe que omite uma série de métodos úteis, mas mostra a idéia básica:

#include <memory>

class Grid {
  size_t _rows;
  size_t _columns;
  std::unique_ptr<int[]> data;

public:
  Grid(size_t rows, size_t columns)
      : _rows{rows},
        _columns{columns},
        data{std::make_unique<int[]>(rows * columns)} {}

  size_t rows() const { return _rows; }

  size_t columns() const { return _columns; }

  int *operator[](size_t row) { return row * _columns + data.get(); }

  int &operator()(size_t row, size_t column) {
    return data[row * _columns + column];
  }
}

Por isso, criar uma matriz com entradas std::make_unique<int[]>(rows * columns). Nós sobrecarga operator [] qual índice vontade a linha para nós. Ele retorna um int * que aponta para o início da linha, que pode então ser desreferenciado como normal para a coluna. Note-se que make_unique primeiros navios em C ++ 14, mas você pode polyfill-lo em C ++ 11, se necessário.

Também é comum para estes tipos de estruturas para operator() sobrecarga assim:

  int &operator()(size_t row, size_t column) {
    return data[row * _columns + column];
  }

Tecnicamente eu não usei new aqui, mas é trivial para se deslocar de std::unique_ptr<int[]> para int * e uso new / delete.

Esta questão foi me incomodando. - É um problema bastante comum que uma boa solução já deve existir, algo melhor do que o vetor de vetores ou rolar seus próprios indexação array

Quando algo deve existir em C ++, mas não, o primeiro lugar para olhar é boost.org . Lá encontrei o impulso Multidimensional matriz Biblioteca, multi_array . Ela inclui ainda uma classe multi_array_ref que pode ser usado para embrulhar o seu próprio unidimensional tampão matriz.

Por que não usar STL: vector? Tão fácil, e você não precisa excluir o vector.

int rows = 100;
int cols = 200;
vector< vector<int> > f(rows, vector<int>(cols));
f[rows - 1][cols - 1] = 0; // use it like arrays

Fonte: Como Criar 2, 3 (ou várias) Arrays Dimensional em C / C ++?

array Um 2D é basicamente uma matriz 1D de ponteiros, onde cada ponteiro está apontando para uma matriz 1D, que irá armazenar os dados reais.

Aqui N é linha e M é a coluna.

alocação dinâmica

int** ary = new int*[N];
  for(int i = 0; i < N; i++)
      ary[i] = new int[M];

preenchimento

for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
      ary[i][j] = i;

print

for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
      std::cout << ary[i][j] << "\n";

livre

for(int i = 0; i < N; i++)
    delete [] ary[i];
delete [] ary;

Como alocar uma matriz multidimensional contígua no GNU C ++? Há uma extensão GNU que permite a sintaxe "standard" para o trabalho.

Parece que o problema vem de novo operador []. Certifique-se de usar o operador novo em vez disso:

double (* in)[n][n] = new (double[m][n][n]);  // GNU extension

E isso é tudo: você recebe um array multidimensional C-compatível ...

typedef é seu amigo

Depois de ir para trás e olhar para muitas das outras respostas, descobri que uma explicação mais profunda está em ordem, como muitas das outras respostas, quer sofrer de problemas de desempenho ou forçá-lo a usar incomum ou onerosa sintaxe para declarar a matriz, ou acesso os elementos da matriz (ou de todos os anteriores).

Em primeiro lugar, esta resposta assume que você sabe as dimensões da matriz em tempo de compilação. Se o fizer, então esta é a melhor solução, uma vez que será tanto dar o melhor desempenho e permite que você use sintaxe de matriz padrão para acessar os elementos do array .

A razão que esta dá o melhor desempenho é porque ele aloca todas as matrizes como um bloco contíguo de memória o que significa que é provável que têm menos acidentes de página e localidade melhor espacial. Alocar num ciclo pode fazer com que as matrizes individuais para acabar espalhadas em várias páginas não-contíguas através do espaço de memória virtual como o ciclo de atribuição poderia ser interrompido (possivelmente várias vezes) por outros segmentos ou processos, ou simplesmente devido ao critério do enchimento alocador em, blocos de memória vazios pequenos que acontece de ter disponível.

Os outros benefícios são uma sintaxe de declaração simples e sintaxe de acesso a matriz padrão.

Em C ++ usando novo:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

typedef double (array5k_t)[5000];

array5k_t *array5k = new array5k_t[5000];

array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);

return 0;
}

Ou estilo C usando calloc:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

typedef double (*array5k_t)[5000];

array5k_t array5k = calloc(5000, sizeof(double)*5000);

array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);

return 0;
}

Este problema tem me incomodado por 15 anos, e todas as soluções fornecidas não foram satisfatórias para mim. Como você cria uma matriz multidimensional dinâmica de forma contígua na memória? Hoje eu finalmente encontrei a resposta. Usando o código a seguir, você pode fazer exatamente isso:

#include <iostream>

int main(int argc, char** argv)
{
    if (argc != 3)
    {
        std::cerr << "You have to specify the two array dimensions" << std::endl;
        return -1;
    }

    int sizeX, sizeY;

    sizeX = std::stoi(argv[1]);
    sizeY = std::stoi(argv[2]);

    if (sizeX <= 0)
    {
        std::cerr << "Invalid dimension x" << std::endl;
        return -1;
    }
    if (sizeY <= 0)
    {
        std::cerr << "Invalid dimension y" << std::endl;
        return -1;
    }

    /******** Create a two dimensional dynamic array in continuous memory ******
     *
     * - Define the pointer holding the array
     * - Allocate memory for the array (linear)
     * - Allocate memory for the pointers inside the array
     * - Assign the pointers inside the array the corresponding addresses
     *   in the linear array
     **************************************************************************/

    // The resulting array
    unsigned int** array2d;

    // Linear memory allocation
    unsigned int* temp = new unsigned int[sizeX * sizeY];

    // These are the important steps:
    // Allocate the pointers inside the array,
    // which will be used to index the linear memory
    array2d = new unsigned int*[sizeY];

    // Let the pointers inside the array point to the correct memory addresses
    for (int i = 0; i < sizeY; ++i)
    {
        array2d[i] = (temp + i * sizeX);
    }



    // Fill the array with ascending numbers
    for (int y = 0; y < sizeY; ++y)
    {
        for (int x = 0; x < sizeX; ++x)
        {
            array2d[y][x] = x + y * sizeX;
        }
    }



    // Code for testing
    // Print the addresses
    for (int y = 0; y < sizeY; ++y)
    {
        for (int x = 0; x < sizeX; ++x)
        {
            std::cout << std::hex << &(array2d[y][x]) << ' ';
        }
    }
    std::cout << "\n\n";

    // Print the array
    for (int y = 0; y < sizeY; ++y)
    {
        std::cout << std::hex << &(array2d[y][0]) << std::dec;
        std::cout << ": ";
        for (int x = 0; x < sizeX; ++x)
        {
            std::cout << array2d[y][x] << ' ';
        }
        std::cout << std::endl;
    }



    // Free memory
    delete[] array2d[0];
    delete[] array2d;
    array2d = nullptr;

    return 0;
}

Quando você chama o programa com os valores sizeX = 20 e sizeY = 15, a saída será a seguinte:

0x603010 0x603014 0x603018 0x60301c 0x603020 0x603024 0x603028 0x60302c 0x603030 0x603034 0x603038 0x60303c 0x603040 0x603044 0x603048 0x60304c 0x603050 0x603054 0x603058 0x60305c 0x603060 0x603064 0x603068 0x60306c 0x603070 0x603074 0x603078 0x60307c 0x603080 0x603084 0x603088 0x60308c 0x603090 0x603094 0x603098 0x60309c 0x6030a0 0x6030a4 0x6030a8 0x6030ac 0x6030b0 0x6030b4 0x6030b8 0x6030bc 0x6030c0 0x6030c4 0x6030c8 0x6030cc 0x6030d0 0x6030d4 0x6030d8 0x6030dc 0x6030e0 0x6030e4 0x6030e8 0x6030ec 0x6030f0 0x6030f4 0x6030f8 0x6030fc 0x603100 0x603104 0x603108 0x60310c 0x603110 0x603114 0x603118 0x60311c 0x603120 0x603124 0x603128 0x60312c 0x603130 0x603134 0x603138 0x60313c 0x603140 0x603144 0x603148 0x60314c 0x603150 0x603154 0x603158 0x60315c 0x603160 0x603164 0x603168 0x60316c 0x603170 0x603174 0x603178 0x60317c 0x603180 0x603184 0x603188 0x60318c 0x603190 0x603194 0x603198 0x60319c 0x6031a0 0x6031a4 0x6031a8 0x6031ac 0x6031b0 0x6031b4 0x6031b8 0x6031bc 0x6031c0 0x6031c4 0x6031c8 0x6031cc 0x6031d0 0x6031d4 0x6031d8 0x6031dc 0x6031e0 0x6031e4 0x6031e8 0x6031ec 0x6031f0 0x6031f4 0x6031f8 0x6031fc 0x603200 0x603204 0x603208 0x60320c 0x603210 0x603214 0x603218 0x60321c 0x603220 0x603224 0x603228 0x60322c 0x603230 0x603234 0x603238 0x60323c 0x603240 0x603244 0x603248 0x60324c 0x603250 0x603254 0x603258 0x60325c 0x603260 0x603264 0x603268 0x60326c 0x603270 0x603274 0x603278 0x60327c 0x603280 0x603284 0x603288 0x60328c 0x603290 0x603294 0x603298 0x60329c 0x6032a0 0x6032a4 0x6032a8 0x6032ac 0x6032b0 0x6032b4 0x6032b8 0x6032bc 0x6032c0 0x6032c4 0x6032c8 0x6032cc 0x6032d0 0x6032d4 0x6032d8 0x6032dc 0x6032e0 0x6032e4 0x6032e8 0x6032ec 0x6032f0 0x6032f4 0x6032f8 0x6032fc 0x603300 0x603304 0x603308 0x60330c 0x603310 0x603314 0x603318 0x60331c 0x603320 0x603324 0x603328 0x60332c 0x603330 0x603334 0x603338 0x60333c 0x603340 0x603344 0x603348 0x60334c 0x603350 0x603354 0x603358 0x60335c 0x603360 0x603364 0x603368 0x60336c 0x603370 0x603374 0x603378 0x60337c 0x603380 0x603384 0x603388 0x60338c 0x603390 0x603394 0x603398 0x60339c 0x6033a0 0x6033a4 0x6033a8 0x6033ac 0x6033b0 0x6033b4 0x6033b8 0x6033bc 0x6033c0 0x6033c4 0x6033c8 0x6033cc 0x6033d0 0x6033d4 0x6033d8 0x6033dc 0x6033e0 0x6033e4 0x6033e8 0x6033ec 0x6033f0 0x6033f4 0x6033f8 0x6033fc 0x603400 0x603404 0x603408 0x60340c 0x603410 0x603414 0x603418 0x60341c 0x603420 0x603424 0x603428 0x60342c 0x603430 0x603434 0x603438 0x60343c 0x603440 0x603444 0x603448 0x60344c 0x603450 0x603454 0x603458 0x60345c 0x603460 0x603464 0x603468 0x60346c 0x603470 0x603474 0x603478 0x60347c 0x603480 0x603484 0x603488 0x60348c 0x603490 0x603494 0x603498 0x60349c 0x6034a0 0x6034a4 0x6034a8 0x6034ac 0x6034b0 0x6034b4 0x6034b8 0x6034bc 

0x603010: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
0x603060: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 
0x6030b0: 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 
0x603100: 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 
0x603150: 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 
0x6031a0: 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 
0x6031f0: 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 
0x603240: 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 
0x603290: 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 
0x6032e0: 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 
0x603330: 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 
0x603380: 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 
0x6033d0: 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 
0x603420: 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 
0x603470: 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

Como você pode ver, as mentiras de matriz multidimensional de forma contígua na memória, e não dois endereços de memória são sobrepostos. Mesmo a rotina para libertar a matriz é mais simples do que a forma padrão de alocar dinamicamente memória para cada coluna única (ou linha, dependendo de como você vê a matriz). Uma vez que a matriz consiste basicamente de dois conjuntos lineares, apenas estes dois têm de ser (e pode ser) libertado.

Este método pode ser estendido por mais de duas dimensões com o mesmo conceito. Eu não vou fazê-lo aqui, mas quando você começa a idéia por trás dele, é uma tarefa simples.

Espero que este código irá ajudá-lo tanto quanto ele me ajudou.

Tente fazer isso:

int **ary = new int[sizeY];
for (int i = 0; i < sizeY; i++)
    ary[i] = new int[sizeX];

O objectivo desta resposta é não acrescentar nada de novo que os outros não já capa, mas para estender a resposta de @ Kevin Loney.

Você pode usar a declaração leve:

int *ary = new int[SizeX*SizeY]

e sintaxe acesso será:

ary[i*SizeY+j]     // ary[i][j]

mas isso é complicado para a maioria, e pode levar a confusão. Assim, você pode definir uma macro da seguinte forma:

#define ary(i, j)   ary[(i)*SizeY + (j)]

Agora você pode acessar a matriz usando o ary(i, j) // means ary[i][j] sintaxe muito similar. Isto tem a vantagem de ser simples e bonito, e, ao mesmo tempo, usando expressões no lugar dos índices também é mais simples e menos confuso.

Para acessar, digamos, ary [2 + 5] [3 + 8], você pode escrever ary(2+5, 3+8) em vez do complexo-olhando ary[(2+5)*SizeY + (3+8)] ou seja, ele salva parênteses e ajuda a legibilidade.

Advertências:

  • Embora a sintaxe é muito semelhante, não é o mesmo.
  • No caso de você passar a matriz para outras funções, SizeY tem que ser passado com o mesmo nome (ou em vez ser declarado como uma variável global).

Ou, se você precisa usar a matriz em múltiplas funções, então você pode adicionar SizeY também como outro parâmetro na definição macro assim:

#define ary(i, j, SizeY)  ary[(i)*(SizeY)+(j)]

Você começa a idéia. Claro, isso torna-se muito tempo para ser útil, mas ainda pode evitar a confusão de + e *.

Isto não é recomendado definitivamente, e ele vai ser condenado como má prática pela maioria dos usuários experientes, mas eu não pude resistir compartilhá-lo por causa de sua elegância.

P.S .: Eu testei isso, e as mesmas obras de sintaxe (tanto como um lvalue e um rvalue) em g ++ 14 e g ++ 11 compiladores.

Aqui, tenho duas opções. O primeiro mostra o conceito de uma variedade de matrizes ou ponteiro de ponteiros. Eu prefiro o segundo porque os endereços são contíguos, como você pode ver na imagem.

enter descrição da imagem aqui

#include <iostream>

using namespace std;


int main(){

    int **arr_01,**arr_02,i,j,rows=4,cols=5;

    //Implementation 1
    arr_01=new int*[rows];

    for(int i=0;i<rows;i++)
        arr_01[i]=new int[cols];

    for(i=0;i<rows;i++){
        for(j=0;j<cols;j++)
            cout << arr_01[i]+j << " " ;
        cout << endl;
    }


    for(int i=0;i<rows;i++)
        delete[] arr_01[i];
    delete[] arr_01;


    cout << endl;
    //Implementation 2
    arr_02=new int*[rows];
    arr_02[0]=new int[rows*cols];
    for(int i=1;i<rows;i++)
        arr_02[i]=arr_02[0]+cols*i;

    for(int i=0;i<rows;i++){
        for(int j=0;j<cols;j++)
            cout << arr_02[i]+j << " " ;
        cout << endl;
    }

    delete[] arr_02[0];
    delete[] arr_02;


    return 0;
}

Se o seu projeto é CLI (Runtime Suporte ao Idioma Comum) , então:

Você pode usar a classe array, não aquele que você começa quando você escreve:

#include <array>
using namespace std;

Em outras palavras, não a classe conjunto não gerenciado você começa quando usando o namespace std e quando incluindo o cabeçalho matriz, não a classe conjunto não gerenciado definida no namespace std e no cabeçalho matriz, mas a matriz classe gerenciada do CLI .

com esta classe, você pode criar uma matriz de qualquer classificação que você deseja.

O código a seguir abaixo cria nova matriz bidimensional de 2 linhas e 3 colunas e do tipo int, e eu nomeá-lo "arr":

array<int, 2>^ arr = gcnew array<int, 2>(2, 3);

Agora você pode acessar elementos na matriz, por nomeá-la e escrever único quadrado parênteses [], e dentro deles, adicione a linha e coluna, e separá-los com o , vírgula.

O seguinte código abaixo acesso um elemento na linha 2 e 1 coluna da matriz já criado no código anterior acima:

arr[0, 1]

apenas por escrito esta linha é ler o valor nessa célula, ou seja, obter o valor nesta célula, mas se você adicionar o sinal de igual =, você está prestes a escrever o valor na célula, ou seja, definir o valor dessa célula. Você também pode usar o + =, - =, * = e / = operadores Claro que, para apenas números (int, float, double, __int16, __int32, __int64 e etc), mas se você sabe que já

.

Se o seu projecto é não CLI, então você pode usar a classe conjunto não gerenciado do namespace std, se você #include <array>, é claro, mas o problema é que esta classe de matriz é diferente do que o CLI matriz. Cria um array deste tipo é mesmo como o CLI, exceto que você terá que remover o sinal ^ ea palavra-chave gcnew. Mas, infelizmente, o segundo parâmetro int nas <> parênteses especifica o comprimento (ou seja, tamanho) da matriz, não a sua classificação!

Não há nenhuma maneira de especificar classificação neste tipo de matriz, classificação é característica da variedade CLI somente. .

comporta matriz std como matriz normal em C ++, que você define com o ponteiro, por exemplo int* e depois: new int[size], ou sem ponteiro: int arr[size], mas ao contrário da matriz normal do c ++, array std fornece funções que você pode usar com os elementos do array, como preenchimento, início, fim, tamanho e etc, mas matriz normal fornece nada .

Mas gama ainda std são uma matriz unidimensional, como as matrizes normais c ++. Mas, graças às soluções que os outros caras sugerem sobre como você pode fazer o c normais ++ uma variedade dimensional para array bidimensional, podemos adaptar as mesmas idéias a variedade std, por exemplo, de acordo com a ideia de Mehrdad Afshari, podemos escrever o seguinte código:

array<array<int, 3>, 2> array2d = array<array<int, 3>, 2>();

Esta linha de código cria uma "matriz Jugged" , que é uma uma matriz dimensional, que cada uma das suas células é ou pontos a outra uma matriz dimensional.

Se todos um matrizes dimensionais em um array de uma dimensão são iguais em seu comprimento / tamanho, então você pode tratar a variável array2d como uma matriz real, bidimensional, mais você pode usar os métodos especiais para linhas ou colunas tratar, depende de como você vê-lo em mente, na matriz 2D, que suportes de matriz std.

Você também pode usar a solução de Kevin Loney:

int *ary = new int[sizeX*sizeY];

// ary[i][j] is then rewritten as
ary[i*sizeY+j]

mas se você usar variedade std, o código deve olhar diferente:

array<int, sizeX*sizeY> ary = array<int, sizeX*sizeY>();
ary.at(i*sizeY+j);

E ainda tem as funções únicas da matriz de std.

Note que você ainda pode acessar os elementos do array std usando os parênteses [], e você não tem que chamar a função at. Você também pode definir e atribuir nova variável int que irá calcular e manter o número total de elementos na matriz std, e usar o seu valor, em vez derepetindo sizeX*sizeY

Você pode definir sua própria classe genérica array bidimensional, e definir o construtor da classe Array bidimensional para receber dois inteiros para especificar o número de linhas e colunas na nova matriz bidimensional, e definir conseguir função que recebe dois parâmetros de número inteiro que o acesso de um elemento na matriz bidimensional e retorna o seu valor, e função conjunto que recebe três parâmetros, que os dois primeiros são números inteiros que especificam a linha e coluna na matriz bidimensional, e o terceiro parâmetro é a nova valor do elemento. Seu tipo depende do tipo que você escolheu na classe genérica.

Você será capaz de implementar tudo isso usando array qualquer o c normais ++ (ponteiros ou sem) ou a matriz std e uma das ideias que outras pessoas uso sugeriu, e torná-lo fácil de usar como a matriz cli, ou como o array bidimensional que pode definir, atribuir e uso em C #.

Comece por definir a matriz usando ponteiros (linha 1):

int** a = new int* [x];     //x is the number of rows
for(int i = 0; i < x; i++)
    a[i] = new int[y];     //y is the number of columns

Eu te deixou com uma solução que funciona melhor para mim, em certos casos. Especialmente quando se sabe [o tamanho de?] Uma dimensão da matriz. Muito útil para uma série de caracteres, por exemplo, se necessita uma gama de tamanho de matrizes de carvão animal variando [20].

int  size = 1492;
char (*array)[20];

array = new char[size][20];
...
strcpy(array[5], "hola!");
...
delete [] array;

A chave é os parênteses na declaração de matriz.

Eu usei esse não elegante, mas rápido, fácil e funcionamento do sistema. Eu não vejo por que não trabalho porque a única maneira para o sistema para permitir criar uma matriz grande tamanho e de acesso peças é sem cortá-lo em partes:

#define DIM 3
#define WORMS 50000 //gusanos

void halla_centros_V000(double CENW[][DIM])
{
    CENW[i][j]=...
    ...
}


int main()
{
    double *CENW_MEM=new double[WORMS*DIM];
    double (*CENW)[DIM];
    CENW=(double (*)[3]) &CENW_MEM[0];
    halla_centros_V000(CENW);
    delete[] CENW_MEM;
}

A seguir exemplo pode ajudar,

int main(void)
{
    double **a2d = new double*[5]; 
    /* initializing Number of rows, in this case 5 rows) */
    for (int i = 0; i < 5; i++)
    {
        a2d[i] = new double[3]; /* initializing Number of columns, in this case 3 columns */
    }

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            a2d[i][j] = 1; /* Assigning value 1 to all elements */
        }
    }

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            cout << a2d[i][j] << endl;  /* Printing all elements to verify all elements have been correctly assigned or not */
        }
    }

    for (int i = 0; i < 5; i++)
        delete[] a2d[i];

    delete[] a2d;


    return 0;
}

declarando matriz 2D de forma dinâmica:

    #include<iostream>
    using namespace std;
    int main()
    {
        int x = 3, y = 3;

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

        for(int i = 0; i<y; i++)
        {
            ptr[i] = new int[y];
        }
        srand(time(0));

        for(int j = 0; j<x; j++)
        {
            for(int k = 0; k<y; k++)
            {
                int a = rand()%10;
                ptr[j][k] = a;
                cout<<ptr[j][k]<<" ";
            }
            cout<<endl;
        }
    }

Agora, no código acima tomamos um ponteiro de casal e atribuiu-lhe uma memória dinâmica e deu um valor de colunas. Aqui a memória alocada é apenas para as colunas, agora para as linhas que só precisa de um loop e atribuir o valor para cada linha de uma memória dinâmica. Agora podemos usar o ponteiro apenas a maneira como usamos uma matriz 2D. No exemplo acima, então atribuído números aleatórios para a nossa matriz 2D (ponteiro) .Seu tudo sobre DMA de matriz 2D.

Estou usando este ao criar matriz dinâmica. Se você tem uma classe ou um struct. E isso funciona. Exemplo:

struct Sprite {
    int x;
};

int main () {
   int num = 50;
   Sprite **spritearray;//a pointer to a pointer to an object from the Sprite class
   spritearray = new Sprite *[num];
   for (int n = 0; n < num; n++) {
       spritearray[n] = new Sprite;
       spritearray->x = n * 3;
  }

   //delete from random position
    for (int n = 0; n < num; n++) {
        if (spritearray[n]->x < 0) {
      delete spritearray[n];
      spritearray[n] = NULL;
        }
    }

   //delete the array
    for (int n = 0; n < num; n++) {
      if (spritearray[n] != NULL){
         delete spritearray[n];
         spritearray[n] = NULL;
      }
    }
    delete []spritearray;
    spritearray = NULL;

   return 0;
  } 

Este não é o único em muitos detalhes, mas bastante simplificada.

int *arrayPointer = new int[4][5][6]; // ** LEGAL**
int *arrayPointer = new int[m][5][6]; // ** LEGAL** m will be calculated at run time
int *arrayPointer = new int[3][5][]; // ** ILLEGAL **, No index can be empty 
int *arrayPointer = new int[][5][6]; // ** ILLEGAL **, No index can be empty

Lembre-se:

1. APENAS O PRIMEIRO índice pode ser um tempo de execução variável. OUTROS índices precisam ser constante

2. NO índice pode ser deixado vazio.

Como mencionado em outras respostas, chamada

delete arrayPointer;

para desalocar memória associado com a matriz quando você é feito com a matriz.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top