繁体   English   中英

c++ 数组 - 表达式必须有常量值

[英]c++ array - expression must have a constant value

当我尝试从我声明的变量创建数组时出现错误。

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

为什么会出现此错误:

表达式必须有一个常量值。

创建这样的数组时,它的大小必须是恒定的。 如果你想要一个动态大小的数组,你需要在堆上为它分配内存,你还需要在完成后用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++ 有这个功能。 但是,永远不要使用它,因为您的代码将变得不可跨编译器移植。

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

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

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

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

#define row 8
#define col 8

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

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

int a[10][10];

您告诉 C++ 编译器您希望在运行时在程序内存中分配 100 个连续整数。 然后编译器将为您的程序提供那么多可用内存,并且一切都很好。

但是如果你告诉编译器

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

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

TL; 博士

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 的二​​维数组,其行为与 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 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 标准,标准编译器的维护者添加到他们的编译器中。

我们不需要 const 声明。 在编译期间,编译器会自动替换该值。

这个问题围绕这个话题展开。

注意:这不是标准的编码实践,因此某些编译器可能仍会抛出错误。

当我创建这样的数组时。

int a = 8;

int b[a];

它给了我一个 C2131 和一个 E0028 错误。 这就是为什么我害怕在 C++ 中使用数组并使用向量代替。 但是当我四处挖掘时,我发现了这个简单的解决方案! 而不是使用上面的例子,使用这个。

int a = 8;

int* b = new int[a];

突然错误消失了,我的阵列完全按照预期工作。 如果你想要一个二维数组,这里是如何

int a = 8, b = 8;

int** c = new int* [a](new int[b](0));

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM