【问题标题】:Should I declare an array after I read the size of it?我应该在读取数组的大小后声明一个数组吗?
【发布时间】:2018-01-20 15:35:22
【问题描述】:

我最近发现这种声明适用于我的 C++ 编译器

int h, w;
cin>>h>>w;

int a[h + 1][w + 1], f[h + 1][w + 1];

我应该使用这种类型的声明来降低空间复杂性,而不是在获取实际请求的大小之前声明数组吗?

【问题讨论】:

    标签: c++ gcc variable-length-array


    【解决方案1】:

    这些是一些编译器支持的非标准扩展。不要指望他们。使用std::vector会更好。

    int h, w;
    cin >> h >> w;
    
    std::vector<std::vector<int>> a{h + 1, std::vector<int>{w + 1}};
    std::vector<std::vector<int>> f{h + 1, std::vector<int>{w + 1}};
    

    【讨论】:

      【解决方案2】:

      Variable-length automatic arrays 允许在 中,但不允许在 中。作为 GCC 接受它们的扩展,但如果您使用 -std=c++14-pedantic 构建以下示例,您将收到警告:

      void foo(int n) {
          int bar[n];
      }
      

      警告:ISO C++ 禁止变长数组 'bar' [-Wvla]

      不推荐使用,有自己的动态数组类型,叫做std::vector

      另一个answer 展示了构造std::vectorh + 1 元素副本的一个很好的例子,其值为std::vector&lt;int&gt;(w + 1),这是另一个std::vectorw + 1 default-inserted 实例int

      【讨论】:

        【解决方案3】:

        现代 C++ 不允许在运行时确定数组的大小。正如其他答案所指定的 c99 允许它。最好的方法是使用向量。

        例如,尝试在 Microsoft Visual Studio 中编译这段代码,看看会发生什么。

        #include <iostream>
        using namespace std;
        
        int main()
        {
            int size;
            cin >> size;
            int arr[size]; // 8th line
        }
        

        错误:

        source_file.cpp(8): error C2131: expression did not evaluate to a constant
        source_file.cpp(8): note: failure was caused by non-constant arguments or reference to a non-constant symbol
        source_file.cpp(8): note: see usage of 'num'
        Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
        

        你应该使用的是向量。向量的作用是,它确定运行时的大小。你可以在里面放更多的元素,它的尺寸会变大。您可以随时删除更多元素,然后它的尺寸会变小。

        但要小心,不要将容量与大小混为一谈。这是一个示例代码,可让您了解容量的工作原理。

        #include <iostream>
        #include <vector>
        using namespace std;
        
        int main()
        {
            vector<int> v;
            cout << "Adding elements!" << endl;
            for(int i = 0; i < 10; i++)
            {
                v.push_back(6);
                cout << "Capacity: " << v.capacity() << endl;
            }
        
            cout << "Removing elements!" << endl;
            for(int i = 0; i < 10; i++)
            {
                v.pop_back();
                cout << "Capacity: " << v.capacity() << endl;
            }
        }
        

        Linux x64 输出:

        Adding elements!
        Capacity: 1
        Capacity: 2
        Capacity: 4
        Capacity: 4
        Capacity: 8
        Capacity: 8
        Capacity: 8
        Capacity: 8
        Capacity: 16
        Capacity: 16
        Removing elements!
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        Capacity: 16
        

        即使我稍后删除元素,容量也会保持在最后一个值。

        Capacity 返回当前为向量分配的存储空间大小,以元素表示。

        Size 返回向量中元素的数量。

        玩得开心,祝你好运!

        编辑:容量也会因操作系统而异。

        微软 x64 输出:

        Adding elements!
        Capacity: 1
        Capacity: 2
        Capacity: 3
        Capacity: 4
        Capacity: 6
        Capacity: 6
        Capacity: 9
        Capacity: 9
        Capacity: 9
        Capacity: 13
        Removing elements!
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        Capacity: 13
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-11
          相关资源
          最近更新 更多