如何向C++数组中添加元素?

97

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

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++中,我不能这样做,它会给我一个编译器错误。你们有什么建议吗?


17
实际上,“那些代码”甚至不能编译。在C/C++中,声明数组的方式不是“int[] arr”,而应该是“int arr[]”。但是您的代码有更严重的问题,其他答案已经提到了这些问题。 - j_random_hacker
11个回答

125

C++ 中的纯数组无法实现您所说的功能。C++ 中解决这个问题的方法是使用STL库,它提供了 std::vector

您可以按照以下方式使用 vector

#include <vector>

std::vector< int > arr;

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

13
你需要使用 "#include <vector>" 头文件!=D - Eduardo Lucio
1
值得注意的是 - 如果您需要将其作为数组传递,可以像这样从向量中获取数组:https://dev59.com/m3A85IYBdhLWcg3wJf8Z#2923290 - netpoetica

83

C++中的数组无法在运行时更改大小。为此,您应该使用vector<int>

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.

如评论中所述,vector 定义在 vector 头文件和 std 命名空间中。 使用它时,您应该:

#include <vector>

同时,在代码中使用 std::vector 或添加

using std::vector; 
或者
using namespace std;

#include <vector>这行代码之后。


1
+1 -> 我同意,向量绝对是做这件事情最简单的方法。不要忘记你需要:#include <vector> - Jon Cage
2
此外,在实例化之前使用std::vector或添加using std::vector。 - Bastien Léonard

25

你不必使用向量。如果你想继续使用普通数组,可以像这样做:

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字节的内存。

这就是为什么其他人推荐使用向量的主要原因。向量在后台进行管理,并在结构体扩展时分配新的内存。在数据大小已知的情况下,它仍然不如数组高效,但对于大多数情况下,性能差异将不重要。每种方法都有权衡,最好了解两种方法。


2
我对C++确实是个新手,但当我尝试使用你的int arr[] = new int[15];数组初始化方法时,经常会出现“数组初始化器必须是初始化列表”的错误。 - Yu Chen

14
使用向量:
#include <vector>

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

13
int arr[] = new int[15];

变量arr保存了一个内存地址。在这个内存地址上,有15个连续的整数。它们可以用0到14的索引来引用。
在php中,我只需要做这个arr[]=22;,这将自动将22添加到数组的下一个空索引。
处理数组时没有“下一个”的概念。我认为你遗漏了一个重要的事情,即一旦创建了数组,所有数组元素都已经存在。它们未初始化,但它们确实已经存在。因此,您不是在填充数组元素,而是它们已经被填充,只是未初始化。无法测试数组中未初始化的元素。
听起来你想使用数据结构,比如queuestackvector

6
我完全赞同在实现动态数组时采用向量方式。但是,请记住STL为您提供了许多容器,以满足不同的运行时需求。您应该仔细选择。例如:对于快速插入到末尾,您可以在vector和deque之间进行选择。
我差点忘了,伴随着强大的能力而来的是巨大的责任 :-) 由于向量大小是灵活的,它们经常自动重新分配以调整添加元素。因此,请注意迭代器失效(是的,它也适用于指针)。但是,只要您使用operator[]来访问单个元素,就是安全的。

3

我可能没有理解你的问题,如果是这样,我很抱歉。但是,如果你不会删除任何项目,只会添加它们,为什么不简单地将变量分配给下一个空插槽?每次向数组中添加新值时,只需递增该值以指向下一个值。

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

#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);

3

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

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

2

首先将数组的所有元素初始化为null,然后查找null以找到空槽位。


1

如果你在写C++代码,最好使用标准库中的数据结构,例如vector。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接