Jak mogę zadeklarować tablicę o zmiennej wielkości (globalnie)

18

Chciałbym zrobić trzy tablice o tej samej długości. Zgodnie z dokumentacją tablice muszą być zdefiniowane jako miejsca, int myArray[10];gdzie 10 można zastąpić znaną długością (inną liczbą całkowitą) lub wypełnić tablicą {2, 3, 5, 6, 7}.

Jednak, kiedy próbowała zadeklarować wartość int arrSize = 10;, a następnie w oparciu o tablicę tej wielkości int myArray[arrSize];, pojawia się następujący: error: array bound is not an integer constant.

Czy istnieje sposób na zmienne określanie rozmiarów tablic, czy po prostu muszę je na stałe zakodować? (Nauczono mnie, że kodowanie jest złe i należy tego unikać za wszelką cenę).

użytkownik3.1415927
źródło
Miałem podobny problem i to zrobiłem. Uczę się też, więc nie mogę powiedzieć, czy to prawidłowe rozwiązanie, czy nie, ale zadziałało. Zobacz poniżej część kodu za pomocą wektorów, zajęło mi sporo czasu, aby zacząć je rozumieć i nadal nie jestem ekspertem pod żadnym względem: #include <string> #include <vector> #include <iostream> #include <algorytm> #include <string.h> using namespace std; int main () {ciąg nazwa; adres ciągu; miasto strun; kraj strunowy; ciąg odpowiedzi; wektor <wektor <ciąg>> personData; for (;;) {vector <ciąg> myTempData; cout << „wprowadź nazwę lub n, aby wyjść” << endl; getline (cin, name); if (name == "n") {bre
Misterxp

Odpowiedzi:

22

Twoje pytanie składa się z 2 części.

1 / Jak mogę zadeklarować stały rozmiar tablicy poza tablicą?

Możesz albo użyć makra

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

lub użyj stałej

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

jeśli zainicjowałeś tablicę i musisz znać jej rozmiar, możesz:

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

drugi sizeofdotyczy typu każdego elementu tablicy, tutaj int.

2 / Jak mogę uzyskać tablicę, której rozmiar jest dynamiczny (tj. Nieznany do czasu uruchomienia)?

W tym celu potrzebujesz dynamicznej alokacji, która działa na Arduino, ale generalnie nie jest to zalecane, ponieważ może to spowodować fragmentację „sterty”.

Możesz zrobić (sposób 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));
}

Lub (sposób 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];

Więcej informacji o problemach z fragmentacją sterty można znaleźć w tym pytaniu .

jfpoilpret
źródło
4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, w ten sposób możesz zmienić typ myArray bez wprowadzania błędów. Z tego samego powodu myArray = realloc(myArray, size * sizeof *myArray);. BTW, rzutowanie wartości zwracanej malloc()lub realloc()jest również bezużyteczne. 2) Sprawdzanie myArray != 0w wersji C jest bezużyteczne, co realloc(NULL, sz)jest równoważne z malloc(sz).
Edgar Bonet
const int ARRAY_SIZE = 10; int myArray [ARRAY_SIZE]; Czy naprawdę uważasz, że to możliwe ?. Dałoby to zmiennie zmodyfikowany błąd tablicy w C.
Arun Joe Cheriyan
@ArunCheriyan w CI nie wiem, ale w C ++ kompiluje się i działa idealnie. Ponieważ Arduino jest oparte na C ++, nie ma tutaj problemu.
jfpoilpret
0

Rozmiar tablicy musi być znany w czasie kompilacji. W przeciwnym razie należy dynamicznie przydzielić pamięć za pomocą:

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

gdzie x (liczba całkowita) może być ustawiona w kodzie aplikacji (możesz załadować go z eeprom, jeśli chcesz, aby było to trwałe, ale konfigurowalne ustawienie).


Jeśli jednak chcesz zadeklarować niektóre tablice tego samego rozmiaru, musisz tylko zadeklarować stałą taką jak ta:

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

Myślę, że nie zakodowanie na stałe ma sens tylko wtedy, gdy można oczekiwać, że użytkownik zechce w pewnym momencie zmienić ustawienie. Nie wiem czy tak jest.

użytkownik2973
źródło
Kodowanie rozmiarów symbolicznie zamiast dosłownie może zapewnić dwie korzyści: 1) Dobrze dobrany symbol dokumentuje lub przynajmniej sugeruje powód wyboru; oraz 2) gdy inne części programu lub modułu muszą być dostosowane do tego wyboru, wyrażenie wykorzystujące ten sam symbol może uczynić to automatycznym, co znacznie ułatwia konserwację .
JRobert
[Trochę nie na temat, ale] „użytkownik” jest dwuznaczny, ponieważ może oznaczać jedną z wielu osób. Zwykle oznacza to użytkownika końcowego, konsumenta produktu końcowego, o ile nie zaznaczono inaczej. Może to być następny programista, najbliższy konsument kodu, którym w rzeczywistości może być Ty (typowo, z własnego doświadczenia) rok lub dłużej po tym, jak zapomniałem o drobiazgowych wewnętrznych szczegółach tego kodu ). Lub projektant systemu, który umieści Twój kod jako gotowy moduł w swoim produkcie. Podejrzewam, że miałeś na myśli drugiego „użytkownika”.
JRobert,
0

Jeśli znasz maksymalną długość tablicy, po prostu zainicjuj tablicę na tę długość i użyj liczby całkowitej, aby powiedzieć programowi, ile tej tablicy ma użyć. Jeśli jest to różnica między 7,10 bajtów, to nie marnujesz tyle alokacji pamięci.

MichaelT
źródło
0

Wiem, że jestem tu trochę spóźniony, ale teoretycznie nie można utworzyć regularnych tablic przy użyciu zmiennej do zdefiniowania liczby elementów, które będzie mieć tablica, jak w:

int arrSize;
int myArray[arrSize];

Wyświetli się błąd, ponieważ program deklarując tablicę oczekuje, że wartość w nawiasach będzie stała. Istnieje jednak sposób, w jaki można utworzyć tablicę ze zmienną określającą ilość wartości, jakie będą miały te tablice poprzez dynamiczny przydział pamięci dla zestawów wartości (ta metoda została przetestowana tylko z tablicami jednowymiarowymi, nie próbowano wielowymiarowe jeszcze) i idzie mniej więcej tak:

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

Następnie wystarczy przypisać wartość do każdego elementu utworzonego w instancji myArray (który jest już teraz Array), tak jak w przypadku normalnej tablicy utworzonej jako myArray [arrSize].

NibboNSX
źródło