Como posso declarar uma matriz de tamanho variável (globalmente)

18

Eu gostaria de fazer três matrizes do mesmo comprimento. De acordo com a documentação , as matrizes devem ser definidas como int myArray[10];onde 10 pode ser substituído por um comprimento conhecido (outro número inteiro) ou preenchido com uma matriz {2, 3, 5, 6, 7}.

No entanto, quando tentou declarar um valor int arrSize = 10;e, em seguida, uma série com base nesse tamanho int myArray[arrSize];, eu recebo o seguinte: error: array bound is not an integer constant.

Existe uma maneira de determinar de forma variável os tamanhos de matriz ou eu apenas preciso codificá-los? (Foi-me ensinado que codificar é ruim e é algo a evitar a todo custo.)

user3.1415927
fonte
Eu tive um problema semelhante e fiz isso. Estou aprendendo também, então não posso dizer se é uma solução válida ou não, mas funcionou. Veja abaixo parte do código usando vetores, demorei um pouco para começar a entendê-los e ainda não sou um especialista de maneira alguma: #include <string> #include <vector> #include <iostream> #include <algorithm> #include <string.h> using namespace std; int main () {nome da string; endereço da string; cidade de cordas; país da cadeia; resposta de string; vetor <vetor <string>> personData; for (;;) {vector <string> myTempData; cout << "digite o nome ou n para sair" << endl; getline (cin, nome); if (name == "n") {bre
Misterxp 25/10

Respostas:

22

Sua pergunta tem 2 partes, na verdade.

1 / Como posso declarar o tamanho constante de uma matriz fora da matriz?

Você pode usar uma macro

#define ARRAY_SIZE 10
...
int myArray[ARRAY_SIZE];

ou use uma constante

const int ARRAY_SIZE = 10;
...
int myArray[ARRAY_SIZE];

se você inicializou a matriz e precisa saber seu tamanho, pode fazer:

int myArray[] = {1, 2, 3, 4, 5};
const int ARRAY_SIZE = sizeof(myArray) / sizeof(int);

o segundo sizeofestá no tipo de cada elemento da sua matriz, aqui int.

2 / Como posso ter uma matriz cujo tamanho seja dinâmico (isto é, desconhecido até o tempo de execução)?

Para isso, você precisará de alocação dinâmica, que funciona no Arduino, mas geralmente não é aconselhável, pois isso pode fazer com que o "heap" fique fragmentado.

Você pode fazer (maneira C):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source)
if (myArray != 0) {
    myArray = (int*) realloc(myArray, size * sizeof(int));
} else {
    myArray = (int*) malloc(size * sizeof(int));
}

Ou (maneira C ++):

// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source or through other program logic)
if (myArray != 0) {
    delete [] myArray;
}
myArray = new int [size];

Para obter mais informações sobre problemas com a fragmentação de heap, você pode consultar esta pergunta .

jfpoilpret
fonte
4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, dessa forma, você pode alterar o tipo de myArray sem introduzir bugs. Pela mesma razão myArray = realloc(myArray, size * sizeof *myArray);,. Aliás, lançar o valor de retorno de malloc()ou realloc()também é inútil. 2) A verificação myArray != 0na versão C é inútil, como realloc(NULL, sz)é equivalente a malloc(sz).
Edgar Bonet
const int ARRAY_SIZE = 10; int myArray [ARRAY_SIZE]; Você realmente acha que isso é possível? Isso daria erro leque variável modificada em C.
Arun Joe Cheriyan
@ArunCheriyan no CI não sabe, mas em C ++ ele compila e funciona perfeitamente. Como o Arduino é baseado em C ++, não há problema aqui.
Jfpoilpret
0

O tamanho da matriz deve ser conhecido em tempo de compilação. Caso contrário, você deve alocar memória dinamicamente usando:

char *chararray = malloc(sizeof(char)*x);

onde x (um número inteiro) pode ser definido no código do aplicativo (você pode carregá-lo da eeprom se desejar que seja uma configuração persistente, mas configurável).


No entanto, se você quiser apenas declarar algumas matrizes do mesmo tamanho, basta declarar o número uma constante como esta:

const int arrsize = 10;
char array1[arrsize];
int array2[arrsize];

Eu acho que não codificar as coisas só faz sentido se você razoavelmente espera que o usuário queira alterar a configuração em algum momento. Não sei se é esse o caso.

user2973
fonte
Tamanhos de código simbolicamente, em vez de literalmente, podem fornecer dois benefícios: 1) Um símbolo bem escolhido documenta, ou pelo menos sugere, o motivo da escolha; e 2) quando outras partes do programa ou módulo precisarem ser adaptadas para essa escolha, uma expressão usando o mesmo símbolo pode tornar isso automático, facilitando muito a manutenção .
JRobert # 20/15
[Um tópico pouco interessante, mas] "usuário" é ambíguo, pois pode significar uma dentre várias pessoas. Geralmente, implica o usuário final, o consumidor do produto final, se não indicado de outra forma. Pode ser o próximo programador, o consumidor imediatamente seguinte do seu código, que pode, de fato, ser você (típico, na minha própria experiência) um ano ou mais depois de ter esquecido os detalhes internos dele. Ou um designer de sistema que inclua seu código como um módulo pronto para uso em seu produto. Eu suspeito que você quis dizer o segundo "usuário".
JRobert # 20/15
0

Se você souber o comprimento máximo da matriz, basta inicializar a matriz com esse comprimento e use um número inteiro para informar ao programa quanto dessa matriz usar. Se for a diferença entre 7,10 bytes, você não estará desperdiçando tanta alocação de memória.

MichaelT
fonte
0

Eu sei que estou um pouco atrasado aqui, mas em teoria matrizes regulares não podem ser criadas usando uma variável para definir a quantidade de elementos que a matriz terá como em:

int arrSize;
int myArray[arrSize];

Isso exibirá um erro, pois ao declarar a matriz, o programa espera que o valor entre colchetes seja constante. No entanto, existe uma maneira de criar uma matriz com uma variável que define a quantidade de valores que essas matrizes terão por meio da alocação de memória dinâmica para conjuntos de valores (esse método foi testado apenas com matrizes monodimensionais, não tentei multidimensional ainda), e é mais ou menos assim:

//First you create a pointer for the memory space to be separated for the set you're creating
int* myArray;
int arrSize; //Then you define the variable that will determine the amount of elements the array is going to have, you can give it a value whenever you want as long as this int is defined before the values in myArray are set 
myArray=(int*)calloc(arrSize,sizeof(int)) //Here, you establish that the instance myArray (whose memory space has already been separated through the creation of the pointer) will be separated into arrSize amount of elements of type int with a maximum memory value (in bytes) equal to the maximum available for the int type variables

Depois disso, basta atribuir um valor para cada elemento criado na instância myArray (que já é uma matriz agora), como faria para uma matriz normal criada como myArray [arrSize].

NibboNSX
fonte