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

时间:2012-02-09 22:18:49

标签: c++ arrays

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

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

为什么我会收到此错误:

  

表达式必须具有常量值。

8 个答案:

答案 0 :(得分:44)

创建这样的数组时,其大小必须是常量。如果你想要一个动态大小的数组,你需要在堆上为它分配内存,你还需要在完成后用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];

甚至不提供变量名称。

答案 1 :(得分:15)

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

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

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

答案 2 :(得分:14)

标准要求数组长度是在编译时可计算的值,以便编译器能够在堆栈上分配足够的空间。在您的情况下,您尝试将数组长度设置为编译时未知的值。是的,我知道很明显它应该为编译器所知,但这不是这里的情况。编译器不能对非常量变量的内容做任何假设。所以请跟:

const int row = 8;
const int col= 8;
int a[row][col];
UPD:一些编译器实际上允许你关闭它。 IIRC,g ++有这个功能。但是,永远不要使用它,因为您的代码将在编译器之间变得无法移植。

答案 3 :(得分:8)

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

#define row 8
#define col 8

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

答案 4 :(得分:5)

当您将变量声明为

int a[10][10];

您告诉C ++编译器您希望在运行时在程序的内存中分配100个连续的整数。然后,编译器将为您的程序提供可用的内存,并且所有内容都适用于全世界。

但是,如果你告诉编译器

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

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

<强> TL; 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

答案 5 :(得分:0)

您还可以使用固定长度的向量并通过索引对其进行访问,但这比使用指针要节省空间

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

答案 6 :(得分:0)

使用GCC编译器(我在本地完成)和在线编译器(link),类似于问题中运行的代码提供了变量名。

#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

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

似乎在这方面当前的编译器已更改。这是C99标准,标准编译器的维护者已将其添加到其编译器中。

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

This问题围绕主题。

注意:这不是标准的编码做法,因此某些编译器可能仍会引发错误。

答案 7 :(得分:-3)

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

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

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