我不明白如何在C ++中创建和使用动态数组

时间:2014-09-02 15:01:09

标签: c++ arrays

好的,我有;

int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];

第3行应该创建一个包含5个元素的数组吗?或者用数字5填充第一个元素?

第4行填充第一个元素,如何填写其余元素?

没有第4行,第5行读取&#34; -842150451&#34;。

我不明白发生了什么,我尝试使用用户指定的x和y值创建二维数组,然后逐个填充每个元素并使用数值指定由用户。我上面的代码是尝试首先使用1维数组进行尝试。

6 个答案:

答案 0 :(得分:11)

创建动态(可调整大小)int数组的默认C ++方式是:

std::vector<int> grid;

当标准库已经为您封装时,不要使用不安全的指针和手动动态分配。

要创建5个元素的向量,请执行以下操作:

std::vector<int> grid(5);

然后,您可以使用[]访问其各个元素:

grid[0] = 34;
grid[1] = 42;

您可以在后面添加新元素:

// grid.size() is 5
grid.push_back(-42);
// grid.size() now returns 6

咨询reference docs,查看std::vector上的所有可用操作。

答案 1 :(得分:9)

  

第3行应该创建一个包含5个元素的数组吗?

是。它不会初始化它们,这就是为什么你会看到一个奇怪的值。

  

或者用数字5填充第一个元素?

带圆括号的

new int(grid_x)会创建单个对象,而不是数组,并指定初始值。

无法使用new 分配数组,并且使用(非零)值初始化它们。您必须在分配后分配值。

  

第4行填充第一个元素,如何填写其余元素?

您可以使用下标运算符 []来访问元素:

grid[0] = 34;  // Equivalent to: *(grid)   = 34
grid[1] = 42;  // Equivalent to: *(grid+1) = 42
// ...
grid[4] = 77;  // That's the last one: 5 elements from 0 to 4.

但是,你通常不想像这样处理原始指针;当你完成它时,必须delete[]阵列的负担可能很难实现。而是使用标准库。这是制作二维网格的一种方法:

#include <vector>

std::vector<std::vector<int>> grid(grid_x, std::vector<int>(grid_y));
grid[x][y] = 42; // for any x is between 0 and grid_x-1, y between 0 and grid_y-1

或者使用单个连续数组可能更有效;你需要自己的小功能来访问它作为一个二维网格。这样的事情可能是一个很好的起点:

template <typename T>
class Grid {
public:
    Grid(size_t x, size_t y) : size_x(x), size_y(y), v(x*y) {}

    T       & operator()(size_t x, size_t y)       {return v[y*size_x + x];}
    T const & operator()(size_t x, size_t y) const {return v[y*size_x + x];}

private:
    size_t size_x, size_y;
    std::vector<T> v;
};

Grid grid(grid_x,grid_y);
grid(x,y) = 42;

答案 2 :(得分:1)

  

第3行应该创建一个包含5个元素的数组吗?或者用数字5填充第一个元素?

创建一个包含5个元素的数组。

  

第4行填充第一个元素,如何填写其余元素?

grid[n] = x;

其中n是您要设置的元素的索引,x是值。

答案 3 :(得分:0)

第3行在内存中并排分配5个整数的内存,以便可以通过...来访问和修改它们。

括号运算符x[y]*(x+y)完全相同,因此您可以将第4行更改为grid[0] = 34;以使其更具可读性(这就是grid[2]将执行此操作的原因与2[grid]相同的事情!)

答案 4 :(得分:0)

int grid_x = 5 
int * grid; 
grid = new int[grid_x];
*grid = 34; 
cout << grid[0];

Should line 3 create an array with 5 elements? Or fill the first
element with the number 5?

绝对是前者。使用运算符“new”,您将分配内存

  

第4行填充第一个元素,如何填写其余元素?

使用运算符[],例如:

for int (i=0; i < grid_x; i++) { //Reset the buffer
  grid[i] = 0;
}


  

如果没有第4行,第5行读取“-842150451”。

你只是阅读未初始化的内存,它可以是任何值。

  

我不明白发生了什么,我正在努力创造一个2   维度数组使用用户指定的x和y值,然后   使用也指定的数值逐个填充每个元素   用户。我上面的代码试图用1维度来尝试   数组第一。

其他用户解释了如何使用矢量。如果你只需要设置一次数组的大小,我通常更喜欢boost::scoped_array,当变量超出范围时,它会负责删除。

对于编译时未知的二维数组,你需要一些有点棘手的东西,比如scoped_arrays的scoped_array。但是,创建它需要一个for循环。

using boost::scoped_array;
int grid_x;
int grid_y;
///Reading values from user...
scoped_array<scoped_array<int> > grid(new scoped_array<int> [grid_x]);
for (int i = 0; i < grid_x; i++)
  grid[i] = scoped_array<int>(new int[grid_y] );

然后,您将能够以

的形式访问网格元素
grid[x][y];

注意: 它也可以将scoped_array从游戏中删除,

typedef int* p_int_t;
p_int_t* grid = new p_int_t [grid_x];
for (int i = 0; i < grid_x; i++)
  grid[i] = new int[grid_y];

但是你必须在数组的生命周期结束时删除所有子数组。

答案 5 :(得分:0)

数组只是一块连续的内存块。因此它有一个起始地址。

int * grid;

是整数地址的C表示,您可以将*读作'指针'。由于您的数组是整数数组,因此数组中第一个元素的地址实际上与数组的地址相同。因此第3行

grid = new int [grid_x];

分配足够的内存(在堆上)来保存数组并将其地址放在grid变量中。此时,该内存的内容与上次使用物理芯片时的内容无关。从未初始化的内存中读取将导致不可预测的值,因此您观察到遗漏第4行会导致奇怪的输出。

还记得*指针吗?在第四行,您可以将其读作“指针的内容”,因此

*grid = 34;

表示将grid指向的内存的内容设置为值34.但第3行给出了grid数组第一个元素的地址。因此第4行将数组的第一个元素设置为34。

在C中,数组使用从零开始的索引,这意味着数组的第一个元素是数字0,最后一个是数组中的元素数 - 1.这是一种填充方法array是依次索引每个元素以为其设置值。

for(int index = 0; index < grid_x; index++)
{
    grid[index] = 34;
}

或者,您可以继续使用指针执行相同的工作。

for(int* pointerToElement = grid; 0 < grid_x; grid_x-- )
{
    // save 34 to the address held by the pointer
    /// and post-increment the pointer to the next element.
    *pointerToElement++ = 34;
}

享受数组和指针的乐趣,它们一直提供大量的机会来度过无眠时间,想知道为什么你的代码不起作用,PC重启,路由器着火等等。