Làm cách nào tôi có thể khai báo một mảng có kích thước thay đổi (Toàn cầu)


18

Tôi muốn tạo ba mảng có cùng độ dài. Theo tài liệu , Mảng phải được định nghĩa là int myArray[10];trong đó 10 có thể được thay thế cho một độ dài đã biết (một số nguyên khác) hoặc chứa đầy một mảng {2, 3, 5, 6, 7}.

Tuy nhiên, khi tôi cố gắng khai báo một giá trị int arrSize = 10;và sau đó là một mảng dựa trên kích thước đó int myArray[arrSize];, tôi nhận được như sau : error: array bound is not an integer constant.

Có cách nào để xác định kích thước mảng không, hay tôi chỉ cần mã hóa chúng? (Tôi đã được dạy hardcoding là xấu và cần phải tránh bằng mọi giá.)


Tôi đã có một vấn đề tương tự và đã làm điều này. Tôi cũng đang học nên không thể nói đó có phải là giải pháp hợp lệ hay không nhưng nó đã có hiệu quả. Xem phần bên dưới của mã bằng cách sử dụng vectơ, tôi đã mất khá nhiều thời gian để bắt đầu hiểu chúng và tôi vẫn không phải là chuyên gia: #include <string> #include <vector> #include <iostream> #include <Thuật toán> #include <string.h> bằng cách sử dụng không gian tên std; int main () {tên chuỗi; địa chỉ chuỗi; chuỗi thị trấn; chuỗi quốc gia; chuỗi trả lời; vectơ <vector <chuỗi >> personData; for (;;) {vector <chuỗi> myTempData; cout << "nhập tên hoặc n để thoát" << endl; getline (cin, tên); if (name == "n") {bre
Misterxp

Câu trả lời:


22

Câu hỏi của bạn có 2 phần thực sự.

1 / Làm thế nào tôi có thể khai báo kích thước không đổi của một mảng bên ngoài mảng?

Bạn có thể sử dụng macro

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

hoặc sử dụng hằng số

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

Nếu bạn đã khởi tạo mảng và bạn cần biết kích thước của nó thì bạn có thể làm:

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

thứ hai sizeoflà về loại từng phần tử của mảng của bạn, ở đây int.

2 / Làm thế nào tôi có thể có một mảng có kích thước động (nghĩa là không biết đến thời gian chạy)?

Cho rằng bạn sẽ cần phân bổ động, hoạt động trên Arduino, nhưng thường không được khuyến khích vì điều này có thể khiến "đống" bị phân mảnh.

Bạn có thể làm (cách 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));
}

Hoặc (cách 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];

Để biết thêm về các vấn đề với phân mảnh heap, bạn có thể tham khảo câu hỏi này .


4
1) ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, bằng cách này bạn có thể thay đổi loại myArray mà không cần đưa ra lỗi. Vì lý do tương tự , myArray = realloc(myArray, size * sizeof *myArray);. BTW, đúc giá trị trả về của malloc()hoặc realloc()cũng vô dụng. 2) Kiểm tra myArray != 0trong phiên bản C là vô ích, realloc(NULL, sz)tương đương với malloc(sz).
Edgar Bonet

const int ARRAY_SIZE = 10; int myArray [ARRAY_SIZE]; Bạn có thực sự nghĩ rằng nó có thể? Điều này sẽ gây ra lỗi mảng được sửa đổi trong C.
Arun Joe Cheriyan

@ArunCheriyan trong CI không biết, nhưng trong C ++, nó biên dịch và chạy hoàn hảo. Vì Arduino dựa trên C ++, nên không có vấn đề gì ở đây.
jfpoilpret

0

Kích thước của mảng phải được biết tại thời điểm biên dịch. Nếu không, bạn nên phân bổ bộ nhớ một cách linh hoạt bằng cách sử dụng:

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

trong đó x (một số nguyên) có thể được đặt trong mã ứng dụng (bạn có thể tải nó từ eeprom nếu bạn muốn nó là một cài đặt liên tục nhưng có thể định cấu hình).


Tuy nhiên, nếu bạn chỉ muốn khai báo một số mảng có cùng kích thước, bạn chỉ cần khai báo một số như thế này:

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

Tôi nghĩ rằng không phải mã hóa mọi thứ chỉ có ý nghĩa nếu bạn mong muốn người dùng muốn thay đổi cài đặt một cách hợp lý tại một số điểm. Tôi không biết nếu đó là trường hợp.


Kích thước mã hóa một cách tượng trưng thay vì theo nghĩa đen có thể cung cấp hai lợi ích: 1) Một tài liệu ký hiệu được chọn tốt, hoặc ít nhất là gợi ý, lý do cho sự lựa chọn; và 2) khi các phần khác của chương trình hoặc mô-đun cần được điều chỉnh theo lựa chọn đó, một biểu thức sử dụng cùng một biểu tượng có thể làm cho điều đó tự động, giúp bảo trì dễ dàng hơn nhiều .
JRobert

[Hơi lạc đề, nhưng] "người dùng" không rõ ràng vì nó có thể có nghĩa là một trong số nhiều người. Nó thường ngụ ý người dùng cuối, người tiêu dùng sản phẩm cuối cùng, nếu không có quy định khác. Đó có thể là lập trình viên tiếp theo, người tiêu dùng tiếp theo của mã của bạn, trên thực tế, có thể là bạn (điển hình, theo kinh nghiệm của riêng tôi) một năm hoặc hơn sau khi tôi quên các chi tiết nội bộ khó chịu của nó). Hoặc một nhà thiết kế hệ thống bao gồm mã của bạn dưới dạng mô-đun sẵn sàng hoạt động trong sản phẩm của anh ấy / cô ấy. Tôi nghi ngờ bạn có nghĩa là "người dùng" thứ hai.
JRobert

0

Nếu bạn biết độ dài tối đa của mảng, chỉ cần khởi tạo mảng theo độ dài đó và sử dụng một số nguyên để cho chương trình biết mức độ sử dụng của mảng đó. Nếu đó là sự khác biệt giữa 7,10 byte thì bạn không lãng phí việc phân bổ bộ nhớ nhiều như vậy.


0

Tôi biết tôi đến hơi muộn ở đây, nhưng về lý thuyết, các mảng thông thường không thể được tạo bằng cách sử dụng một biến để xác định số lượng phần tử mà mảng sẽ có như trong:

int arrSize;
int myArray[arrSize];

Điều này sẽ hiển thị một lỗi vì khi khai báo mảng, chương trình dự kiến ​​giá trị giữa các dấu ngoặc là một hằng số. Tuy nhiên, có một cách mà bạn có thể tạo một mảng với một biến xác định lượng giá trị mà mảng này sẽ có thông qua cấp phát bộ nhớ động cho các bộ giá trị (phương pháp này đã được thử nghiệm chỉ với các mảng đơn chiều, chưa thử đa chiều chưa), và nó diễn ra như thế này:

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

Sau này, tất cả những gì còn lại phải làm là gán một giá trị cho mọi phần tử được tạo trong thể hiện myArray (hiện đã là Mảng) như bạn làm với một mảng bình thường được tạo là myArray [ArraySize].

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.