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


74

我想将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 ++中我无法做到这一点,它给了我一个编译器错误。你们有什么建议?


12
实际上,“那个代码”甚至不会编译。“ int [] arr”不是在C / C ++中声明数组的方式,而是“ int arr []”。但是您的代码有更严重的问题,其他答案可以解决。
j_random_hacker

Answers:


82

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

您可以通过vector以下方式使用:

std::vector< int > arr;

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

10
您将需要“ #include <vector>”!= D
Eduardo Lucio

值得一提的是,您可以像这样从向量中获取数组,如果您仍然需要将其作为数组传递:stackoverflow.com/a/2923290/802397
netpoetica

73

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.

如注释中所述,vectorvector标头和std名称空间中定义。要使用它,您应该:

#include <vector>

而且,可以std::vector在您的代码中使用或添加

using std::vector; 

要么

using namespace std;

#include <vector>线。


1
+1->我同意,向量是迄今为止最简单的方法。别忘了您需要:#include <vector>
Jon Cage

2
另外,在实例化之前使用std :: vector或使用std :: vector进行添加。
BastienLéonard'09 -4-16

19

您不必使用向量。如果您想使用普通数组,可以执行以下操作:

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 ++的新手,但是Array initializer must be an initializer list当您尝试int arr[] = new int[15];使用初始化数组的方法时,我得到一个相当一致的错误arr
Yu Chen

13

使用向量:

#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(含0)的索引进行引用。

在php中,我只能执行arr [] = 22; 这将自动将22添加到数组的下一个空索引。

处理数组时,没有“下一个”的概念。
我认为您缺少的重要一件事是,一旦创建数组,该数组的所有元素都已经存在。它们尚未初始化,但它们确实已经存在。因此,您不会在执行过程中“填充”数组的元素,它们已经被填充,只是带有未初始化的值。无法测试数组中未初始化的元素。

听起来好像您想使用队列堆栈向量之类的数据结构。


6

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

而且我几乎忘记了,强大的功能会带来巨大的责任:-)由于vectors大小灵活,它们通常会自动重新分配以适应添加元素,因此请注意迭代器无效(是的,它也适用于指针)。但是,只要您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);

2

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


1

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

C型数组很容易出错,应尽可能避免使用。


1

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

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

-2

由于我收到了很多负面反馈,因此我意识到我的解决方案是错误的,因此我进行了更改。

int arr[20] = {1,2,3,4,5};
int index = 5;

void push(int n){
    arr[index] = n;
    index++;
}

push(6)

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


2
但是,您只是分配给了未分配的内存。那是不确定的行为。
Toby Speight

@prince kushwaha假设您分配的内存超出了您的需要,而不是使用realloc
Sapphire_Brick,

他问的问题是,每次插入后如何跟踪数组的索引与数组大小无关。
库什瓦哈亲王20年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.