【问题标题】:How to find the size of an array as an int如何以int形式查找数组的大小
【发布时间】:2014-09-02 18:13:03
【问题描述】:

如果答案非常明显,我深表歉意。 我编写了这个从数组初始化向量的小 sn-p 代码

int arr[] = {1,2,3,4,5};
  vector<int> vec = {begin(arr), end(arr)};
  for (int i = 0; i < 5; ++i)
        cout << vec[i];

代码运行良好,唯一困扰我的是必须知道数组大小。 for的第二个参数,

i < 5;

只是看起来有点太简单了,而且在更大的代码中没有那么准确。有什么方法可以让代码将数组中的元素数推断为整数并使用它而不是自己说明实际的元素数?在使用大多数数组或向量时,我往往会觉得这很烦人。我确信写一些可以为我推断答案的东西会是一个更好的习惯,因为我确信这可能会导致需要用户输入的错误计算,并且他们输入的元素数量没有限制。

【问题讨论】:

  • vector 有一个功能。 std::array 也是如此,您应该使用它而不是内置数组。 vector 还允许您使用初始化列表,因此该数组无论如何都是毫无意义的。而且您通常会使用 ranged-for 循环或算法,因此知道大小对此也毫无意义。
  • @chris: std::array 要求您指定大小(或者您应该实现make_array)。
  • @Jarod42,内置数组也是如此。
  • @chris:不,就像 OP 的示例 int arr[] = {1, 2, 3, 4, 5} 一样,您没有(明确)指定大小为 5
  • @Jarod42,你从来没有明确说过。您仍然通过初始化列表提供大小,就像使用 make_array 一样。

标签: c++ arrays vector integer


【解决方案1】:

要获取int arr[]的大小,可以使用sizeof(arr) / sizeof(*arr)

要使用数组中的值初始化vector&lt;int&gt;,您可以使用:

int arr[] = {1,2,3,4,5};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(*arr) );

要迭代向量的所有值,您可以使用(size() 会为您提供向量的大小):

for (size_t i = 0; i < vec.size(); ++i)
    cout << vec[i];

p.s.在 C++11 中,你甚至可以使用range-based for loop

for (auto elem : vec)
    std::cout << elem;

【讨论】:

  • -1 表示单个小尼特的总和。表达式sizeof(arr) / sizeof(arr[0]) 是(1)非常冗长和(2)类型不安全,因为它接受一个指针为arr,然后产生错误的结果。与 OP 的代码相比,向量的初始化是不必要的冗长和复杂的。 for 循环可能会产生有符号/无符号警告,这是不好的。
【解决方案2】:

遍历向量而不对其大小进行硬编码:

for (int i = 0; i < vec.size(); ++i)
   cout << vec[i];

for ( vector<int>::iterator it = vec.begin(); it != vec.end(); ++it )
   cout << *it;

如果你使用的是 C++11,

for ( auto item : vec )
   cout < item;

【讨论】:

    【解决方案3】:
    • 获取数组的大小:

      template <typename T, std::size_t N>
      constexpr std::size_t array_size(const T(&)[N]) { return N; }
      
    • std::vector已经有一个成员方法size()

    【讨论】:

      【解决方案4】:

      代码的第一部分,

      int arr[] = {1,2,3,4,5};
      vector<int> vec = {begin(arr), end(arr)}; 
      

      没问题,假设beginendstd::beginstd::end


      下面的循环,

      for (int i = 0; i < 5; ++i)
          cout << vec[i];
      

      在三个方面不好:

      • 错误的循环,应该使用基于范围的for

      • 硬编码大小,应使用vec.size() 或等效值。

      • 循环体不使用大括号容易导致维护问题。

      修正为普通C++03for循环:

      for (int i = 0; i < (int)vec.size(); ++i)
      {
          cout << vec[i];
      }
      

      演员表是为了抑制有关有符号/无符号不匹配的警告,否则很可能会产生这种情况。

      顺便提一下,对于int 类型,维护没有问题,可能会更改此强制转换的含义,或者含义与预期不同。

      不过,在巧妙地自动搜索 C 风格的演员表时,它可能会产生误报。我个人通过使用函数count_of 来避免它。因此,如果我出于某种原因选择了 C++03 for 循环,我会写类似

      for( int i = 0; i < count_of( vec ); ++i )
      {
          cout << vec[i];
      }
      

      但您可以简单地使用基于 C++11 范围的 for,如下所示:

      for( auto const value : vec )
      {
          cout << value;
      }
      

      如果您确实需要容器的有符号整数大小(可能是原始数组),请考虑利用 std::beginstd::end

      #include <stddef.h>  // ptrdiff_t
      #Include <iterator>  // std::begin, std::end
      
      using Size = ptrdiff_t;
      
      template< class Container >
      auto count_of( Container& c )
          -> Size
      { return std::end( c ) - std::begin( c ); }
      

      我不确定是否值得专注于原始数组,但如果您需要 constexpr,那么您需要这样做,例如

      template< class Item, Size n >
      auto constexpr count_of( Item (&a)[n] )
          -> Size
      { return n; }
      

      免责声明:编译器未触及任何代码。

      【讨论】:

        【解决方案5】:

        为了完整性:这个问题是创建std::array 的目的。 (C++11)

        // This is statically allocated, unlike vector 
        // which uses dynamic allocated memory.
        std::array<int, 5> arr = {1, 2, 3, 4, 5}; 
        
        // Different iterations methods:
        for ( auto & elem : arr ) {
            cout << elem << endl;
        }
        
        for ( int i = 0; i < arr.size(); i++) {
            cout << arr[i] << endl;
        }
        
        for ( auto it = arr.begin(); it != arr.end(); ++it) {
            cout << *it << endl;
        }
        

        【讨论】:

          猜你喜欢
          • 2021-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-26
          • 2018-04-07
          • 2015-02-03
          • 1970-01-01
          相关资源
          最近更新 更多