Tại sao tôi nhận được lỗi "Đối tượng có kích thước thay đổi có thể không được khởi tạo" với mã sau?
int boardAux[length][length] = {{0}};
enum {length = 0xF } ; int boardAux[length][length] = {0};
Tại sao tôi nhận được lỗi "Đối tượng có kích thước thay đổi có thể không được khởi tạo" với mã sau?
int boardAux[length][length] = {{0}};
enum {length = 0xF } ; int boardAux[length][length] = {0};
Câu trả lời:
Tôi giả định rằng bạn đang sử dụng trình biên dịch C99 (với hỗ trợ cho các mảng có kích thước động). Vấn đề trong mã của bạn là tại thời điểm khi trình biên dịch nhìn thấy khai báo biến của bạn, nó không thể biết có bao nhiêu phần tử trong mảng (tôi cũng giả định ở đây, do lỗi trình biên dịch length
không phải là hằng số thời gian biên dịch).
Bạn phải khởi tạo mảng đó theo cách thủ công:
int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );
printf( "%d", boardAux[1][2] )
biên dịch tốt. Trình biên dịch biết kích thước và biết phần tử (1,2) -th nằm ở vị trí nào trong bộ nhớ. Nếu bạn sử dụng phân bổ động mảng là uni-chiều và bạn phải thực hiện các toán tự hỏi:printf("%d", boardAux[ 1*length + 2 ])
memset
cuộc gọi. Tôi vừa sửa lại.
length
là static
? Trong C ++ 14, nó hoạt động tốt.
Bạn nhận được lỗi này vì trong ngôn ngữ C, bạn không được phép sử dụng bộ khởi tạo với mảng có độ dài thay đổi. Về cơ bản, thông báo lỗi bạn đang nhận được đã nói lên tất cả.
6.7.8 Khởi tạo
...
3 Kiểu thực thể được khởi tạo phải là một mảng có kích thước không xác định hoặc một kiểu đối tượng không phải là kiểu mảng có độ dài thay đổi.
Điều này gây ra lỗi:
int len;
scanf("%d",&len);
char str[len]="";
Điều này cũng gây ra lỗi:
int len=5;
char str[len]="";
Nhưng điều này hoạt động tốt:
int len=5;
char str[len]; //so the problem lies with assignment not declaration
Bạn cần đặt giá trị theo cách sau:
str[0]='a';
str[1]='b'; //like that; and not like str="ab";
Sau khi khai báo mảng
int boardAux[length][length];
cách đơn giản nhất để gán các giá trị ban đầu bằng 0 là sử dụng vòng lặp for, ngay cả khi nó có thể hơi dài dòng
int i, j;
for (i = 0; i<length; i++)
{
for (j = 0; j<length; j++)
boardAux[i][j] = 0;
}
memset
đơn giản hơn và nhanh hơn.
Câu hỏi đã được trả lời nhưng tôi muốn chỉ ra một giải pháp khác nhanh chóng và hoạt động nếu độ dài không được thay đổi trong thời gian chạy. Sử dụng macro #define trước main () để xác định độ dài và trong main () quá trình khởi tạo của bạn sẽ hoạt động:
#define length 10
int main()
{
int boardAux[length][length] = {{0}};
}
Macro được chạy trước khi biên dịch thực sự và độ dài sẽ là một hằng số thời gian biên dịch (như David Rodríguez đã đề cập trong câu trả lời của mình). Nó thực sự sẽ thay thế độ dài bằng 10 trước khi biên dịch.
Đơn giản chỉ cần khai báo độ dài là một khuyết điểm, nếu không thì bạn nên cấp phát bộ nhớ động
int size=5;
int ar[size ]={O};
/* This operation gives an error -
variable sized array may not be
initialised. Then just try this.
*/
int size=5,i;
int ar[size];
for(i=0;i<size;i++)
{
ar[i]=0;
}
Đối với khai báo và khởi tạo riêng biệt C ++ như thế này ..
int a[n][m] ;
a[n][m]= {0};
Bạn không thể làm điều đó. Trình biên dịch C không thể làm một điều phức tạp như vậy trên ngăn xếp.
Bạn phải sử dụng heap và phân bổ động.
Những gì bạn thực sự cần làm:
Sử dụng * access (boardAux, x, y, size) = 42 để tương tác với ma trận.