【问题标题】:How to add element to C++ array?如何将元素添加到 C++ 数组?
【发布时间】:2010-10-19 20:12:46
【问题描述】:

我想在数组中添加一个int,但问题是我现在不知道索引是什么。

int[] arr = new int[15];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;

该代码有效,因为我知道我分配给什么索引,但如果我不知道索引怎么办...

在 PHP 中,我可以只做arr[]=22;,它会自动将 22 添加到数组的下一个空索引。但是在 C++ 中我不能这样做,它给了我一个编译器错误。大家有什么建议?

【问题讨论】:

  • 实际上,“那个代码”甚至无法编译。 “int[] arr”不是您在 C/C++ 中声明数组的方式——它是“int arr[]”。但是您的代码存在更严重的问题,其他答案解决了这些问题。

标签: c++ arrays


【解决方案1】:

在 C++ 中,纯数组无法实现您所说的。对此的 C++ 解决方案是使用为您提供 std::vector 的 STL 库。

您可以通过这种方式使用vector

#include <vector>

std::vector< int > arr;

arr.push_back(1);
arr.push_back(2);
arr.push_back(3);

【讨论】:

  • 你需要“#include ”! =D
  • 值得注意 - 如果您仍需要将其作为数组传递,您可以像这样从向量中获取数组:stackoverflow.com/a/2923290/802397
【解决方案2】:

C++ 中的数组不能在运行时改变大小。为此,您应该改用vector&lt;int&gt;

vector<int> arr;
arr.push_back(1);
arr.push_back(2);

// arr.size() will be the number of elements in the vector at the moment.

如 cmets 中所述,vector 定义在 vector 标头和 std 命名空间中。要使用它,您应该:

#include &lt;vector&gt;

另外,在您的代码中使用std::vector 或添加

using std::vector; 

using namespace std;

#include &lt;vector&gt; 行之后。

【讨论】:

  • +1 -> 我同意,向量是迄今为止最简单的方法。不要忘记你需要:#include
  • 另外,在实例化之前使用 std::vector 或使用 std::vector 添加。
【解决方案3】:

您不必使用向量。如果你想坚持使用普通数组,你可以这样做:

int arr[] = new int[15];
unsigned int arr_length = 0;

现在,如果你想在数组末尾添加一个元素,你可以这样做:

if (arr_length < 15) {
  arr[arr_length++] = <number>;
} else {
  // Handle a full array.
}

它不像 PHP 等价物那样简洁优雅,但它完成了您尝试做的事情。为了让您以后可以轻松更改数组的大小,您可以使用#define。

#define ARRAY_MAX 15

int arr[] = new int[ARRAY_MAX];
unsigned int arr_length = 0;

if (arr_length < ARRAY_MAX) {
  arr[arr_length++] = <number>;
} else {
  // Handle a full array.
}

这使得将来管理阵列变得更加容易。通过将 15 更改为 100,数组大小将在整个程序中正确更改。请注意,您必须将数组设置为最大预期大小,因为一旦编译程序就无法更改它。例如,如果您有一个大小为 100 的数组,则永远不能插入 101 个元素。

如果您要使用数组末尾的元素,您可以这样做:

if (arr_length > 0) {
  int value = arr[arr_length--];
} else {
  // Handle empty array.
}

如果您希望能够从一开始就删除元素(即 FIFO),则解决方案会变得更加复杂。您还需要一个开始和结束索引。

#define ARRAY_MAX 15

int arr[] = new int[ARRAY_MAX];
unsigned int arr_length = 0;
unsigned int arr_start = 0;
unsigned int arr_end = 0;

// Insert number at end.
if (arr_length < ARRAY_MAX) {
  arr[arr_end] = <number>;
  arr_end = (arr_end + 1) % ARRAY_MAX;
  arr_length ++;
} else {
  // Handle a full array.
}

// Read number from beginning.
if (arr_length > 0) {
  int value = arr[arr_start];
  arr_start = (arr_start + 1) % ARRAY_MAX;
  arr_length --;
} else {
  // Handle an empty array.
}

// Read number from end.
if (arr_length > 0) {
  int value = arr[arr_end];
  arr_end = (arr_end + ARRAY_MAX - 1) % ARRAY_MAX;
  arr_length --;
} else {
  // Handle an empty array.
}

在这里,我们使用模数运算符 (%) 来使索引换行。例如,(99 + 1) % 100 为 0(环绕增量)。并且 (99 + 99) % 100 是 98 (环绕减量)。这可以让您避免使用 if 语句并使代码更高效。

随着您的代码变得越来越复杂,您还可以快速看到#define 的帮助。不幸的是,即使使用此解决方案,您也永远无法在数组中插入超过 100 个项目(或您设置的任何最大值)。即使数组中只存储了一项,您也会使用 100 字节的内存。

这是其他人推荐向量的主要原因。一个向量在幕后进行管理,并随着结构的扩展分配新的内存。在数据大小已知的情况下,它仍然不如数组有效,但对于大多数用途而言,性能差异并不重要。每种方法都需要权衡取舍,最好两者都知道。

【讨论】:

  • 我绝对是 C++ 的新手,但是当我尝试使用 int arr[] = new int[15]; 初始化数组 arr 的方法时,我得到了一个非常一致的 Array initializer must be an initializer list 错误。
【解决方案4】:

使用向量:

#include <vector>

void foo() {
    std::vector <int> v;
    v.push_back( 1 );       // equivalent to v[0] = 1
}

【讨论】:

    【解决方案5】:
    int arr[] = new int[15];
    

    变量arr 保存一个内存地址。在内存地址处,一行中有 15 个连续的整数。它们可以用索引 0 到 14 (含)引用。

    在 php 中我可以这样做 arr[]=22; 这将自动将 22 添加到 数组的下一个空索引。

    在处理数组时没有“下一个”的概念。
    我认为您缺少的一件重要的事情是,一旦创建了数组,数组的所有元素就已经存在。它们未初始化,但它们都已经存在。因此,您并没有在进行时“填充”数组的元素,它们已经被填充,只是使用了未初始化的值。无法测试数组中未初始化的元素。

    听起来您想使用诸如queuestackvector 之类的数据结构。

    【讨论】:

      【解决方案6】:

      我完全同意vector 在实现动态数组时的方式。但是,请记住,STL 为您提供了许多满足不同运行时要求的容器。您应该谨慎选择一个。例如:为了在后面快速插入,您可以在 vectordeque 之间进行选择。

      我几乎忘记了,强大的力量伴随着巨大的责任 :-) 由于 vectors 的大小灵活,它们经常自动重新分配以调整添加元素。所以要小心迭代器失效(是的,它也适用于指针)。但是,只要您使用 operator[] 访问各个元素,您就是安全的。

      【讨论】:

        【解决方案7】:

        我可能在这里错过了您的问题的重点,如果是这样,我深表歉意。但是,如果您不打算删除任何项目而只是添加它们,为什么不简单地将变量分配给下一个空槽呢?每次向数组添加新值时,只需将值递增以指向下一个。

        在 C++ 中更好的解决方案是使用标准库类型std::list&lt; type &gt;,它还允许数组动态增长,例如:

        #include <list>
        
        std::list<int> arr; 
        
        for (int i = 0; i < 10; i++) 
        {
            // add new value from 0 to 9 to next slot
            arr.push_back(i); 
        }
        
        // add arbitrary value to the next free slot
        arr.push_back(22);
        

        【讨论】:

          【解决方案8】:

          您可以使用变量来计算数组中的位置,因此无论何时添加新元素,您都可以将其放在正确的位置。例如:

          int a = 0;
          int arr[5] = { };
          arr[a] = 6;
          a++;
          

          【讨论】:

            【解决方案9】:

            先把你所有的数组元素初始化为null,然后找null找空槽

            【讨论】:

              【解决方案10】:

              如果您使用 C++ 编写——最好使用标准库中的数据结构,例如向量。

              C 风格的数组非常容易出错,应尽可能避免使用。

              【讨论】:

                【解决方案11】:

                因为我收到了这么多负面反馈,我意识到我的解决方案是错误的,所以我改变了它。

                int arr[20] = {1,2,3,4,5};
                int index = 5;
                
                void push(int n){
                    arr[index] = n;
                    index++;
                }
                
                push(6)
                

                新数组将包含从 1 到 6 的值,您也可以像这样创建删除函数。

                【讨论】:

                • 但是您刚刚分配了未分配的内存;那是未定义的行为。
                • @prince kushwaha 这是假设您分配的内存比您需要的多,而不是使用realloc
                • 他问的问题是如何在每次插入后跟踪数组的索引它与数组大小无关。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-03-16
                • 2015-05-11
                • 2019-04-08
                • 2014-05-26
                相关资源
                最近更新 更多