运行时C ++数组初始化问题

时间:2018-09-22 03:22:34

标签: c++ c

为什么我们不能在全局区域中使用非常量大小来初始化数组大小。...在main()之外...

//outside main - global
int val=5;
int arr[val];

int main()
{

}

这会导致错误

7:12: error: array bound is not an integer constant before ']' token
 In function 'int main()':

但是,如果我将相同的代码移到函数主体/主体中,错误就会消失。...

没有错误,可以编译...

int main()
{
   int val=5;
   int arr[val];
}

这也可以在函数体内正常工作

void fn(int val)
{
    int arr[val];
}

int main()
{

fn(5);

}

困惑,如何仅在main外部无法初始化移动数组的大小?

2 个答案:

答案 0 :(得分:3)

第一个示例,在文件范围内

int val=5;
int arr[val];

int main()

在C和C ++上都是非法的。必须先定义(创建)文件作用域中的变量,然后才能继续使用它们,直到程序结束为止-这也意味着一旦创建,就无法调整数组的大小。对于数组,这意味着(除其他事项外)必须在编译时知道它们的维数。使用变量作为数组维会违反在编译时就知道静态大小的需求-例如,val的值可以在运行时更改(例如,在main()中) ),将在arr之后创建。

第二个例子

void fn(int val)
{
     int arr[val];
}

在C中是合法的(从1999年开始),因为arr具有自动(非静态)存储期限。它将在输入函数主体时创建,并在函数返回时不再存在。这称为“可变长度数组”或VLA,因为元素的数量由运行时变量的值(val)确定。

1999 C标准之前也不支持VLA。

在C ++中,VLA是非法的。期。但是,某些C ++编译器确实支持诸如非标准扩展之类的功能。在C ++中,出于各种原因,首选使用标准容器(例如std::vector<int>),而不是使用数组,包括能够在运行时调整其大小。

答案 1 :(得分:2)

对于函数内部的数组:

您依赖GCC扩展名,如果添加-pedantic,则会收到以下警告:

  

警告:ISO C ++禁止使用可变长度数组'arr'[-Wvla]

因此C ++不支持可变长度数组,建议的替代方法是std :: vector。

对于数组外部函数:

您需要在int之前添加const。是的,我知道编译器理论上可以确定val永远不会更改,但是出于某种原因(没人认为要将其添加到标准中,或者有充分的理由不这样做),您需要添加const。