C + + 数组表达式必须具有常量值

当我尝试用我声明的变量创建一个数组时,我得到了一个错误。

int row = 8;
int col= 8;
int [row][col];

为什么我会得到这个错误:

表达式必须具有常数值。

263823 次浏览

C + + 不允许数组大小的非常数值,这就是它的设计方式。

C99允许数组的大小是一个变量,但我不确定它是否允许两个维度。一些 C + + 编译器(gcc)允许将其作为扩展,但是您可能需要打开一个编译器选项来允许它。

我差点错过了-你需要声明一个变量名,而不仅仅是数组的维度。

创建这样的数组时,它的大小必须是常数。如果你想要一个动态大小的数组,你需要在堆上为它分配内存,当你完成的时候你还需要用 delete释放它:

//allocate the array
int** arr = new int*[row];
for(int i = 0; i < row; i++)
arr[i] = new int[col];


// use the array


//deallocate the array
for(int i = 0; i < row; i++)
delete[] arr[i];
delete[] arr;

如果您想要一个固定的大小,那么它们必须声明为 const:

const int row = 8;
const int col = 8;
int arr[row][col];

还有,

int [row][col];

甚至没有提供变量名。

该标准要求数组长度为编译时可计算的值,以便编译器能够在堆栈上分配足够的空间。在您的示例中,试图将数组长度设置为编译时未知的值。是的,我知道编译器显然应该知道这一点,但这里的情况并非如此。编译器不能对非常数变量的内容作任何假设。那就这样吧:

const int row = 8;
const int col= 8;
int a[row][col];

UPD: 一些编译器实际上允许您完成这个任务。IIRC,g + + 具有这个特性。但是,永远不要使用它,因为您的代码在编译器之间将变得不可移植。

当您在这里声明一个变量时

int a[10][10];

你是在告诉 C + + 编译器,你需要在运行时在程序内存中分配100个连续的整数。然后,编译器将为您的程序提供这么多的可用内存,一切都很顺利。

如果你告诉编译器

int x = 9001;
int y = 5;
int a[x][y];

编译器无法知道在运行时实际需要多少内存,除非进行大量非常复杂的分析来跟踪 x 和 y 值变化的每个最后位置[如果有的话]。与其支持这种可变大小的数组,C + + 和 C 强烈建议您使用 malloc ()手动分配所需的空间。

DR

int x = 5;
int y = 5;
int **a = malloc(x*sizeof(int*));
for(int i = 0; i < y; i++) {
a[i] = malloc(sizeof(int*)*y);
}

A 现在是一个大小为5x5的2D 数组,其行为与 int a [5][5]相同。因为您已经手动分配了内存,C + + 和 C 要求您也手动删除它..。

for(int i = 0; i < x; i++) {
free(a[i]); // delete the 2nd dimension array
}
free(a); // delete a itself

不,它不需要是常量,他上面的代码之所以是错误的,是因为他需要在声明之前包含一个变量名。

int row = 8;
int col= 8;
int x[row][col];

在 Xcode,编译和运行没有任何问题,在 M $c + + 编译器在。NET 它不会编译,它会抱怨你不能使用非常数字初始化数组,大小需要在编译时知道

您可以使用 # Definition 作为替代解决方案,它不引入 Vector 和 malloc,并且在定义数组时仍然使用相同的语法。

#define row 8
#define col 8


int main()
{
int array_name[row][col];
}

也可以使用固定长度的向量并通过索引访问它

int Lcs(string a, string b)
{
int x = a.size() + 1;
int y = b.size() + 1;


vector<vector<int>> L(x, vector<int>(y));


for (int i = 1; i < x; i++)
{
for (int j = 1; j < y; j++)
{
L[i][j] = a[i - 1] == b[j - 1] ?
L[i - 1][j - 1] + 1 :
max(L[i - 1][j], L[i][j - 1]);
}
}


return L[a.size()][b.size()];
}

通过使用 GCC 编译器(我在本地使用的)和在线编译器(链接) ,类似于问题中的代码运行时提供了一个变量名。

#include<iostream>


int main(){
int r= 2, c=3;
int arr[r][c];
arr[0][1]= 3;
std::cout<<arr[0][1];
}

输出: 3

虽然我引用了 Cplusplus.com,

注意: 方括号[]中的元素字段表示数组中元素的数量,必须是常量表达式,因为数组是静态内存块,其大小必须在程序运行之前在编译时确定。

在这方面,目前的编译器似乎已经发生了变化。这是一个 C99标准,标准编译器的维护者将它添加到他们的编译器中。

我们不需要常量声明。在编译过程中,编译器会自动替换这个值。

这个问题绕过了这个话题。

注意: 这不是标准的编码实践,所以一些编译器仍然可能抛出一个错误。