2

为什么这种类型的声明

int nArraySize = 7;
char szName[nArraySize] = "Mollie";

返回此错误:

error: variable-sized object 'szName' may not be initialized

但是当我将'arraySize'变量声明为'const int'时它可以工作吗?

const int nArraySize = 7;
char szName[nArraySize] = "Mollie";
4

5 回答 5

3

首先必须要说的是,在C++语言中,数组声明的大小部分需要是一个整型常量表达式(ICE)。用初始化器声明的const int对象可以在 ICE 中使用。int不能在 ICE 中使用对象。这是它的正式部分。

但是,从错误消息来看,您的 C++ 编译器支持C++中的 C99 样式的可变长度数组 (VLA),作为非标准扩展。这意味着在您的编译器中,您可以使用非常量表达式来指定数组声明中的大小。然而,即使支持 VLA 本身,这些数组仍然无法初始化。C99 中的 VLA 规范禁止这样做,而这正是 C++ 编译器“继承”它们的规范的方式。

换句话说,与其他答案所述相反,您的 C++ 编译器可能会接受此代码

int nArraySize = 7;
char szName[nArraySize];

即使它在形式上是非法的 C++。它是= "Mollie"触发错误的部分。

于 2013-06-22T18:05:09.900 回答
1

因为 C++ 不支持变长数组(在C-99标准中引入,但任何版本的 C++ 中都没有)。当您声明nArraySize为非constint 时,编译器会抱怨,因为nArraySize可能会在运行时更改。如果nArraySizeconst,编译器知道它在运行时不能改变,因此数组大小szName不能是可变的(即可以在编译时推导出来)。在 C++(以及 C99 之前的 C 版本)中,数组的大小必须是可以在编译时推导出的常量。

于 2013-06-22T17:51:54.777 回答
0

该标准不允许动态大小、静态分配的数组。您可能会发现在 GCC 中您将能够做到这一点,但那是因为这是许多允许不一致行为的扩展之一。

数组定义如下:

D1 [ constant-expressionopt] attribute-specifier-seqopt

其中大小是一个整数常量表达式。标准定义了一个整数常量表达式,如下所示:

整型常量表达式是整型或无范围枚举类型的表达式,隐式转换为纯右值,其中转换后的表达式是核心常量表达式。[注:此类表达式可用作数组边界(8.3.4、5.3.4),[...] — 结束注]

int n = 10;
int x[n]; // error!

该变量n不是常量表达式,因此它不适用于这种情况。

通过将constexpr(C++11) 添加到类型中,它将可用于常量表达式。但在这种情况下const足以让它工作:

int const n = 5;

int x[n];

另一方面,动态数组采用动态大小说明符:

int n = 10;

int *x = new int[n];

但我建议使用的一个选项是std::vector动态大小缓冲区的包装器:

#include <vector>

int main()
{
    int n = 10;

    std::vector<int> x(n); // x.size() is 10
}

我希望这会有所帮助。

于 2013-06-22T18:06:12.623 回答
0

第一个是可变长度数组,它在 C 中标准化(从 C99 标准开始),但在 C++ 中没有。

C++ 需要所有数组的大小在编译时可用,而不是运行时可用。将大小声明为常量使其成为编译时常量。

于 2013-06-22T17:51:46.277 回答
0

因为程序必须在编译时知道为变量分配多少内存。如果您不设置nArraySize常量,则假定它可能会在运行时发生变化。将其设为常量可确保编译器不会更改此值。

于 2013-06-22T17:52:57.357 回答