Pergunta

quando declarar o array bidimensional

int random[height][width];

e, em seguida, usá-lo em uma função

void populate(int random[height][width], int x, int y)

dá o erro tipo de variável-tamanho declarado fora de qualquer função. Eu sei que eu estou fazendo algo errado, e que é algo pequeno. Eu só tenho uma memória ruim ...

Foi útil?

Solução

Vou intensificar agora e dizer-lhe que arrays multidimensionais não valem o esforço cerebral em C ou C ++. Você é muito melhor fora de usar matrizes unidimensional (ou, ainda melhor, contentores normais) e escrever uma função de indexação:

inline int index (int x, int y)
{
  return x + y * width;
}

Agora, para o seu problema. C ++ não suporta C99 matrizes de comprimento variável. O compilador deve saber, em tempo de compilação, o tamanho da matriz. A seguir, por exemplo, não vai funcionar.

int dim = 4;
int ar[dim];

Se dim foram const, ele iria trabalhar porque o compilador seria capaz de dizer exatamente como ar ampla deveria ser (porque o valor da dim não mudaria). Este é provavelmente o problema que você está encontrando.

Se você quer ser capaz de alterar o tamanho em tempo de compilação, você precisa fazer algo mais difícil, como escrever uma referência templated. Você não pode usar um ponteiro para arrays multidimensionais por causa da maneira como eles são dispostos em C / C ++. Um exemplo templated pode parecer o seguinte aberração:

template <int Width, int Height>
void populate(int (&(&random)[Width])[Height], int x, int y);

Esta é feio.

Para executar-tempo, você vai precisar usar new para alocar dados ou usar um tipo de recipiente.

Outras dicas

Não é possível definir a matriz com dimensões não constantes (largura, altura) do lado de fora da função, que é - não no quadro da pilha, porque as dimensões não são conhecidos em tempo de compilação. Você teria constantes uso ou alocar dinamicamente (quer na pilha ou no quadro de pilha).

Quando uma matriz é passado directamente como parâmetro para uma função (passar por valor) ele decai para um ponteiro para o primeiro elemento da matriz. Mesmo se você pode ler claramente na assinatura as dimensões da matriz, essas dimensões são ignorados pelo compilador. Esse comportamento é compatível com C.

Usando C ++, você pode passar a matriz por referência e que não seria mais um problema.

int extract_value( int (&a)[10][10], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[10][10] = {};
   a[5][5] = 1;
   std::cout << extract_value( a, 5, 5 ) << std::endl;
   int b[5][5];
//   extract_value( b, 2, 2 ); // error: the function takes an array of 10x10
}

O parâmetro de função devem corresponder exatamente, isto é, ele só tem uma matriz de 10x10 elementos. Você pode tomar livrar dessa restrição por templates a função dos tamanhos de matriz. Uma vez que você está nisso também o tipo:

template <typename T, int Rows, int Cols>
T extract_value( T (&a)[Rows][Cols], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[5][7] = {};
   extract_value( a, 3, 4 );
   int b[8][2] = {};
   extract_value( b, 7, 1 ); // correct, the compiler matches sizes
   double c[4][4] = {};
   extract_value( c, 2, 2 ); // different types are allowed
}

Esta solução ainda é complicado em que os tamanhos devem ser constantes tempo de compilação, e a matriz deve ser pilha alocada. A solução para esta é a definição de uma classe que tem memória dinâmica num tampão (linear) e tem uma conversão a partir do sistema de coordenadas N-1 para a matriz tridimensional para obter valores, como foi sugerido antes. Você pode obter algumas dicas sobre como fazê-lo neste FAQ sobre a sobrecarga de operador que fornece uma implementação de uma matriz 2D. Depois de ter que implementado, você pode apenas usar isso como parâmetro para funções / métodos.

A minha recomendação seria seguir este último caminho:. Encapsular a matriz N-dimensional em uma classe que fornece conversões em um vetor 1D (o C ++ FAQ Lite usa um ponteiro bruto, prefiro contêineres STL)

Vou ilustrar com um exemplo:

// globals

const int ARRAY_SIZE = 16 struct ArrayType_t arrayType[ARRAY_SIZE];

Mesmo que ARRAY_SIZE é declarada como int constante o valor da TI não é inicializado em tempo de compilação e, portanto, o compilador não sabe o tamanho da matriz e está dando esse erro. No entanto, se você fizer isso como um hash definir #define ARRAY_SIZE 16 struct ArrayType_t arrayType[ARRAY_SIZE] ===> Isso funciona porque ARRAY_SIZE é definido pelo tempo de compilação e compilador pode saber o tamanho da matriz em tempo de compilação.

Você pode usar algo como isto:

void populate(int height, int width, int **random)
{
    //here you can work from random[0][0] to random[height][width]
}

então você pode usá-lo como este:

int main()
{
    int height=10;
    int width=20;
    int **myarray = new int*[height];
    for( int i=0; i< height; i++ ) myarray[i] = new int[width];
    populate( height, width, myarray);
}

Mas, é claro, você terá que tomar cuidado para de estouro de buffer

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