简体   繁体   English

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

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

I get an error when I try to create an array from the variables I declared.当我尝试从我声明的变量创建数组时出现错误。

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

Why do I get this error:为什么会出现此错误:

expression must have a constant value.表达式必须有一个常量值。

When creating an array like that, its size must be constant.创建这样的数组时,它的大小必须是恒定的。 If you want a dynamically sized array, you need to allocate memory for it on the heap and you'll also need to free it with delete when you're done:如果你想要一个动态大小的数组,你需要在堆上为它分配内存,你还需要在完成后用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;

If you want a fixed size, then they must be declared const:如果您想要固定大小,则必须将它们声明为 const:

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

Also,还,

int [row][col];

doesn't even provide a variable name.甚至不提供变量名。

The standard requires the array length to be a value that is computable at compile time so that the compiler is able to allocate enough space on the stack.该标准要求数组长度是一个在编译时可计算的值,以便编译器能够在堆栈上分配足够的空间。 In your case, you are trying to set the array length to a value that is unknown at compile time.在您的情况下,您试图将数组长度设置为编译时未知的值。 Yes, i know that it seems obvious that it should be known to the compiler, but this is not the case here.是的,我知道编译器应该知道它似乎很明显,但这里的情况并非如此。 The compiler cannot make any assumptions about the contents of non-constant variables.编译器不能对非常量变量的内容做出任何假设。 So go with:所以去吧:

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

UPD: some compilers will actually allow you to pull this off. UPD:一些编译器实际上会允许你把它拉下来。 IIRC, g++ has this feature. IIRC,g++ 有这个功能。 However, never use it because your code will become un-portable across compilers.但是,永远不要使用它,因为您的代码将变得不可跨编译器移植。

C++ doesn't allow non-constant values for the size of an array. C++ 不允许数组大小的非常量值。 That's just the way it was designed.这就是它的设计方式。

C99 allows the size of an array to be a variable, but I'm not sure it is allowed for two dimensions. C99 允许数组的大小是一个变量,但我不确定它是否允许用于二维。 Some C++ compilers (gcc) will allow this as an extension, but you may need to turn on a compiler option to allow it.某些 C++ 编译器 (gcc) 将允许将其作为扩展,但您可能需要打开编译器选项以允许它。

And I almost missed it - you need to declare a variable name, not just the array dimensions.我几乎错过了 - 你需要声明一个变量名,而不仅仅是数组维度。

You can use #define as an alternative solution, which do not introduce vector and malloc, and you are still using the same syntax when defining an array.您可以使用 #define 作为替代解决方案,它不会引入 vector 和 malloc,并且您在定义数组时仍然使用相同的语法。

#define row 8
#define col 8

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

When you declare a variable as here当你在这里声明一个变量时

int a[10][10];

you are telling the C++ compiler that you want 100 consecutive integers allocated in the program's memory at runtime.您告诉 C++ 编译器您希望在运行时在程序内存中分配 100 个连续整数。 The compiler will then provide for your program to have that much memory available and all is well with the world.然后编译器将为您的程序提供那么多可用内存,并且一切都很好。

If however you tell the compiler但是如果你告诉编译器

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

the compiler has no way of knowing how much memory you are actually going to need at run time without doing a lot of very complex analysis to track down every last place where the values of x and y changed [if any].编译器无法知道您在运行时实际需要多少内存,而无需进行大量非常复杂的分析来追踪 x 和 y 的值发生变化的每个最后位置 [如果有的话]。 Rather than support such variable size arrays, C++ and C strongly suggest if not outright demand that you use malloc() to manually allocate the space you want. C++ 和 C 不支持这种可变大小的数组,强烈建议您使用 malloc() 手动分配所需的空间。

TL;DR 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 is now a 2D array of size 5x5 and will behave the same as int a[5][5]. a 现在是大小为 5x5 的二​​维数组,其行为与 int a[5][5] 相同。 Because you have manually allocated memory, C++ and C demand that you delete it by hand too...因为您手动分配了内存,C++ 和 C 也要求您手动删除它...

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

one could also use a fixed lengths vector and access it with indexing还可以使用固定长度的向量并通过索引访问它

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()];
}

Using the GCC compiler(which I did locally) and an online compiler( link ), a code similar to the one in the question runs provided a variable name.使用 GCC 编译器(我在本地完成)和在线编译器(链接),与问题中运行的代码类似的代码提供了一个变量名称。

#include<iostream>

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

Output: 3输出: 3

Though I quote cplusplus.com ,虽然我引用cplusplus.com

NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression since arrays are blocks of static memory whose size must be determined at compile-time before the program runs.注意:方括号 [] 中的元素字段表示数组中元素的数量,必须是一个常量表达式,因为数组是静态内存块,其大小必须在程序运行前的编译时确定。

It seems like the present compilers have been changed in this regard.目前的编译器似乎在这方面有所改变。 This is a C99 standard which the maintainers of the standard compilers added to their compilers.这是一个 C99 标准,标准编译器的维护者添加到他们的编译器中。

We need not have a const declaration.我们不需要 const 声明。 During compilation, the compiler automatically substitutes the value.在编译期间,编译器会自动替换该值。

This question goes around the topic.这个问题围绕这个话题展开。

NOTE: This is not the standard coding practice, so some compilers might still throw an error.注意:这不是标准的编码实践,因此某些编译器可能仍会抛出错误。

when I create an array like this.当我创建这样的数组时。

int a = 8;

int b[a];

it gave me a C2131 and an E0028 error.它给了我一个 C2131 和一个 E0028 错误。 that's why I was scared to use arrays in c++ and used vectors instead.这就是为什么我害怕在 C++ 中使用数组并使用向量代替。 but when I dug around, I found this easy solution!但是当我四处挖掘时,我发现了这个简单的解决方案! instead of using the above example, use this.而不是使用上面的例子,使用这个。

int a = 8;

int* b = new int[a];

suddenly the error goes away and my array worked exactly how it was supposed to be.突然错误消失了,我的阵列完全按照预期工作。 incase you wanted a two-dimensional array, here is how如果你想要一个二维数组,这里是如何

int a = 8, b = 8;

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

No it doesn't need to be constant, the reason why his code above is wrong is because he needs to include a variable name before the declaration.不,它不需要是常量,他上面的代码错误的原因是因为他需要在声明之前包含一个变量名。

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

In Xcode that will compile and run without any issues, in M$ C++ compiler in .NET it won't compile, it will complain that you cannot use a non const literal to initialize array, the size needs to be known at compile time在编译和运行没有任何问题的 Xcode 中,在 .NET 中的 M$ C++ 编译器中它不会编译,它会抱怨你不能使用非 const 文字来初始化数组,需要在编译时知道大小

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

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