Как я могу объявить массив переменного размера (глобально)

18

Я хотел бы сделать три массива одинаковой длины. Согласно документации , массивы должны быть определены как int myArray[10];где 10 может быть заменено на известную длину (другое целое число) или заполнено массивом {2, 3, 5, 6, 7}.

Однако, когда я попытался объявить значение , int arrSize = 10;а затем массив , основанный на том , что размер int myArray[arrSize];, я получаю следующее: error: array bound is not an integer constant.

Есть ли способ по-разному определять размеры массивов, или мне просто нужно жестко их кодировать? (Меня учили жесткому программированию - это плохо и что-то, чего следует избегать любой ценой.)

user3.1415927
источник
У меня была похожая проблема, и я сделал это. Я тоже учусь, поэтому не могу сказать, является ли это правильным решением или нет, но это сработало. Смотрите ниже часть кода с использованием векторов, мне потребовалось немало времени, чтобы начать понимать их, и я до сих пор ни в коем случае не эксперт: #include <string> #include <vector> #include <iostream> #include <алгоритм> #include <string.h> using namespace std; int main () {строковое имя; адрес строки; Струнный город; струнная страна; строковый ответ; vector <vector <string >> personData; for (;;) {vector <string> myTempData; cout << "введите имя или n для выхода" << endl; getline (cin, name); if (name == "n") {
bre

Ответы:

22

Ваш вопрос состоит из 2 частей на самом деле.

1 / Как я могу объявить постоянный размер массива вне массива?

Вы можете использовать макрос

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

или использовать константу

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

если вы инициализировали массив и вам нужно знать его размер, вы можете сделать:

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

второй sizeofтип каждого элемента вашего массива здесь int.

2 / Как получить массив динамического размера (т.е. неизвестного до времени выполнения)?

Для этого вам понадобится динамическое размещение, которое работает на Arduino, но, как правило, не рекомендуется, так как это может привести к фрагментации «кучи».

Вы можете сделать (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));
}

Или (путь 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];

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

jfpoilpret
источник
4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, таким образом вы можете изменить тип myArray без внесения ошибок. По той же причине myArray = realloc(myArray, size * sizeof *myArray);. Кстати, приведение возвращаемого значения malloc()или realloc()также бесполезно. 2) Проверка myArray != 0в версии C бесполезна, realloc(NULL, sz)равно как и malloc(sz).
Эдгар Бонет
const int ARRAY_SIZE = 10; int myArray [ARRAY_SIZE]; Вы действительно думаете, что это возможно? Это привело бы к изменению ошибки массива в C.
Арун Джо Чериян
@ArunCheriyan в CI не знаю, но в C ++ он отлично компилируется и работает. Поскольку Arduino основан на C ++, здесь нет проблем.
jfpoilpret
0

Размер массива должен быть известен во время компиляции. В противном случае вы должны динамически распределять память, используя:

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

где x (целое число) может быть установлено в коде приложения (вы можете загрузить его из eeprom, если хотите, чтобы это был постоянный, но настраиваемый параметр).


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

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

Я думаю, что жесткое кодирование не имеет смысла, только если вы ожидаете, что пользователь захочет изменить настройку в какой-то момент. Я не знаю, так ли это.

user2973
источник
Кодирование размеров символически, а не буквально, может обеспечить два преимущества: 1) Хорошо выбранный символ документирует или, по крайней мере, предлагает причину выбора; и 2) когда другие части программы или модуля должны быть адаптированы к этому выбору, выражение, использующее тот же символ, может сделать это автоматическим, значительно упрощая обслуживание .
JRobert
[Немного не по теме, но] «пользователь» неоднозначен, поскольку может означать одного из множества людей. Обычно подразумевается конечный пользователь, потребитель конечного продукта, если не указано иное. Это может быть следующий программист, непосредственно следующий потребитель вашего кода, который, на самом деле, может быть вами (типично, по моему собственному опыту) через год или более после того, как я забыл о мельчайших внутренних подробностях этого). Или системный дизайнер, который включает ваш код как готовый модуль в свой продукт. Я подозреваю, что вы имели в виду второго "пользователя".
JRobert
0

Если вы знаете максимальную длину массива, просто инициализируйте массив этой длины и используйте целое число, чтобы сообщить программе, какой объем этого массива использовать. Если это разница между 7,10 байтами, то вы не тратите столько памяти.

MichaelT
источник
0

Я знаю, что немного опоздал, но теоретически обычные массивы не могут быть созданы с использованием переменной, чтобы определить количество элементов, которые массив будет иметь, как в:

int arrSize;
int myArray[arrSize];

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

//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

После этого все, что осталось сделать, - это присвоить значение каждому элементу, созданному в экземпляре myArray (который уже является массивом), как это было бы для обычного массива, созданного как myArray [arrSize].

NibboNSX
источник