3

我已经开始学习c++了。我读到数组的大小只能在运行之前设置,而动态数组可以在运行时设置。所以我期待这会失败,但它没有:

#include <iostream>

int main() {
    using namespace std;
    int size;
    cout << "enter array size:";
    cin >> size;
    int i, score[size], max; //array size set to variable doesn't fail
    cout << endl << "enter scores:\n";
    cin >> score[0];
    max = score[0];
    for (i = 1; i < size; i++)
    {
        cin >> score[i];
        if (score[i] > max)
    max = score[i];
    }
    cout << "the highest score is " << max << endl;
    return 0;
}

这是最近 C++ 编译器的新特性吗?是否意识到我需要一个动态数组并创建它?

4

3 回答 3

5

可能您正在使用 GCC 编译器,它有一个名为Arrays of Variable Length的扩展。

std::vector是 C++ 中真正的动态数组。

要在 GCC 中选择此标准,请使用选项 -std=c++11; 要获得标准所需的所有诊断,您还应该指定 -pedantic(或 -pedantic-errors,如果您希望它们是错误而不是警告)。

于 2013-07-30T12:46:13.973 回答
3

在所有当前和过去的标准中,该代码格式不正确。可变长度数组是 C99 功能而不是 C++ 功能,尽管一些编译器确实将其作为扩展提供。在即将发布的标准(预计是 C++14,目前正在审查中)中,采用了其他名称的类似功能(语义略有不同),因此预计将来会成为标准。

请注意,一般来说,即排除运行时绑定的数组(正如它们在即将发布的标准中命名的那样),数组的大小是对象的静态类型的一部分,并且在编译时是已知的。在 VLA 或运行时绑定数组的情况下,大小在编译时是未知的,因此类型在某种程度上是类型中的第二类公民。这意味着您不能将 VLA/ARB 与模板一起使用(因为模板的代码生成取决于类型,其中包括大小,这在编译时是未知的)。

同理还有其他限制,sizeof不是VLA的编译时操作,甚至ARB也不允许,这些形式的数组只能用于具有自动存储持续时间的对象(即在堆栈中),你不能取数组的地址(虽然你可以取第一个成员的地址),...

另一个需要考虑的重要一点是,该标准不保证 ARB 的内存将在堆栈上分配,并允许实现调用全局分配函数,尽管目的是编译器会赶上并提供来自堆。

于 2013-07-30T13:07:17.560 回答
0

当心!未定义的整数根本不保证是任何值。一些编译器将默认为 0,而其他编译器将使用内存中已经存在的任何垃圾位。出于这个原因,Visual Studio 甚至不让我编译。在设置 size 变量之前,单步执行代码以查看为 score 分配的内存。编译时可能的大小是垃圾内存中的随机整数,这意味着每次执行时它都会改变!

AC 样式数组需要知道要分配多少连续内存。这允许直接索引和其他优化。正如其他人所建议的那样,std::vector是 C++ 中的标准动态容器,它在后台使用数组。

于 2013-07-30T13:01:02.430 回答