为何选择此类声明
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";
答案 0 :(得分:3)
首先必须说的是,在C ++语言中,数组声明的大小部分必须是一个积分常量表达式(ICE)。使用初始化程序声明的const int
对象可以在ICE中使用。 {I}中不能使用int
对象。这是它的正式部分。
但是,根据错误消息判断,C ++编译器在C ++中支持 C99样式的可变长度数组(VLA),作为非标准扩展。这意味着在您的编译器中,您可以使用非常量表达式来指定数组声明中的大小。然而,即使支持VLA本身,仍然无法初始化此类阵列。这在C99中的VLA规范中是禁止的,这正是它们的规范被C ++编译器“继承”的原因。
换句话说,与其他答案所述相反,您的C ++编译器可能会接受此代码
int nArraySize = 7;
char szName[nArraySize];
即使它是正式非法的C ++。触发错误的是= "Mollie"
部分。
答案 1 :(得分:1)
因为C ++不支持variable-length arrays(在C-99标准中引入,但在任何版本的C ++中不)。当您将nArraySize
声明为非const
int时,编译器会抱怨,因为nArraySize
可能会在运行时更改。如果nArraySize
是const
,则编译器知道它不能在运行时更改,因此szName
的数组大小不能变量(即可以在编译时推断)。在C ++(以及C99之前的C版本)中,数组的大小必须是可以在编译时推导出的常量。
答案 2 :(得分:0)
第一个是variable length array,它在C中标准化(自C99标准以来),但在C ++中则没有。
C ++需要所有数组在编译时中提供其大小,而不是运行时。将大小声明为常量使其成为编译时常量。
答案 3 :(得分:0)
因为程序必须在编译时知道要为变量分配多少内存。如果不使nArraySize
常量,则假定它在运行时可能会发生变化。在使编译器保持不变的同时,编译器不会更改此值。
答案 4 :(得分:0)
标准不允许动态调整大小的静态分配数组。您可能会发现在GCC中您可以执行此操作,但这是因为这是允许不符合行为的许多扩展之一。
数组的定义如下:
D1 [ constant-expression
<子>opt
子>] attribute-specifier-seq
<子>opt
子>
其中大小是整数常量表达式。标准定义了一个整数常量表达式,如下所示:
整数常量表达式是整数或未整数枚举类型的表达式,隐式转换为prvalue,其中转换后的表达式是核心常量表达式。 [注:这样的表达方式 可以用作数组边界(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];
另一方面, dynamic 数组采用动态大小说明符:
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
}
我希望这会有所帮助。