Як я можу оголосити масив змінного розміру (в усьому світі)


18

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

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

Чи є спосіб змінювати розміри масивів чи мені просто потрібно їх жорстко кодувати? (Мене навчали, що жорстке кодування - це погано, і чогось уникати будь-якою ціною.)


У мене була подібна проблема і робила це. Я теж вчуся, тому не можу сказати, чи це вірне рішення чи ні, але воно працювало Дивіться нижче частину коду за допомогою векторів, мені знадобилося зовсім небагато, щоб почати їх розуміти, і я все ще не фахівець: #include <string> #include <vector> #include <iostream> #include <algorithm> #include <string.h> з використанням простору імен std; int main () {ім'я рядка; рядкова адреса; струнне місто; країна струн; відповідь рядка; вектор <вектор <рядок>> personData; для (;;) {вектор <string> myTempData; cout << "введіть ім'я або n для виходу" << endl; getline (cin, ім'я); 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];

Детальніше про проблеми з фрагментацією купи можна звернутися до цього питання .


4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];таким чином ви можете змінити тип myArray, не вводячи помилок. З тієї ж причини myArray = realloc(myArray, size * sizeof *myArray);. BTW, відкидаючи повернене значення malloc()або також realloc()є марним. 2) Перевірка myArray != 0у версії С марна, як 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];

Я думаю, що не жорстке кодування речей має сенс, лише якщо ви обгрунтовано очікуєте, що користувач захоче змінити налаштування в якийсь момент. Я не знаю, чи це так.


Кодування розмірів символічно замість буквально може забезпечити дві переваги: ​​1) вдало підібрані символьні документи або, принаймні, підказують причину вибору; і 2) коли інші частини програми чи модуля необхідно пристосувати до цього вибору, вираз із використанням того ж символу може зробити це автоматичним, що значно спрощує обслуговування .
Дж. Роберт

[Трохи поза темою, але] "користувач" неоднозначний, оскільки це може означати одного з кількох людей. Зазвичай це означає кінцевого споживача, споживача кінцевого продукту, якщо не зазначено інше. Це може бути наступний програміст, негайно наступний споживач вашого коду, який насправді може бути ти (типово, на мій власний досвід) рік і більше після того, як я забув про солоно-крихкі внутрішні деталі його). Або системний дизайнер, який включає ваш код як готовий модуль до свого продукту. Я підозрюю, що ви мали на увазі другого "користувача".
Дж. Роберт

0

Якщо ви знаєте максимальну довжину масиву, просто ініціалізуйте масив до цієї довжини та використовуйте ціле число, щоб повідомити програмі, яку частину масиву використовувати. Якщо це різниця між 7,10 байтами, то ви не витрачаєте стільки виділення пам'яті.


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].

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.