C++ 我不知道';我不了解如何在C+中创建和使用动态数组+;

C++ 我不知道';我不了解如何在C+中创建和使用动态数组+;,c++,arrays,C++,Arrays,好吧,我有 int grid_x = 5 int * grid; grid = new int[grid_x]; *grid = 34; cout << grid[0]; int grid\u x=5 int*网格; grid=newint[grid_x]; *网格=34; 库特 第3行应该创建一个包含5个元素的数组吗?还是用数字5填充第一个元素 创建一个包含5个元素的数组 第4行填充第一个元素,如何填充其余元素 < > >代码> n是您要设置的元素的索引,代码> x>代码>是值。

好吧,我有

int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
int grid\u x=5
int*网格;
grid=newint[grid_x];
*网格=34;
库特
第3行应该创建一个包含5个元素的数组吗?还是用数字5填充第一个元素

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

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


< > >代码> n</代码>是您要设置的元素的索引,<>代码> x>代码>是值。

< p>创建<代码> int <代码>的动态(盟友可调整)数组的默认C++方式是:

std::vector<int> grid;
可以在背面添加新元素:

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

请参阅查看
std::vector

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

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

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

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

还是用数字5填充第一个元素

newint(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.
然而,您通常不希望像这样处理原始指针;完成数组后必须
删除[]
该数组的负担可能很难实现。相反,请使用标准库。这里有一种制作二维网格的方法:

#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
#包括
标准::向量网格(网格x,标准::向量(网格y));
网格[x][y]=42;//对于任何x在0和网格_x-1之间,y在0和网格_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;
模板
类网格{
公众:
网格(大小x,大小y):大小x(x),大小y(y),v(x*y){}
运算符()(size_T x,size_T y){返回v[y*size_x+x];}
T const&运算符()(size_T x,size_T y)const{return v[y*size_x+x];}
私人:
尺寸t尺寸x,尺寸y;
std::向量v;
};
网格网格(网格x,网格y);
网格(x,y)=42;

如果没有第4行,第5行的内容为“-84215041”

您正在读取未初始化的内存,它可以是任何值

我不明白发生了什么,我正在尝试创建一个2 使用用户指定的x和y值的维度数组,然后 用同样由指定的数值逐个填充每个元素 用户。我上面的代码是一个尝试用一维 首先是数组

其他用户解释了如何使用向量。如果只需要设置一次数组的大小,我通常更喜欢在变量超出范围时删除

对于编译时未知大小的二维数组,您需要一些更复杂的东西,比如范围数组的范围数组。不过,创建它需要一个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] );
注意: 它还可以使作用域_阵列退出游戏

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];
typedef int*p_int\t;
p_int_t*grid=新的p_int_t[grid_x];
对于(inti=0;i

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

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

int * grid;
是整数地址的C表示形式,您可以将
*
读取为“指针”。由于数组是整数数组,因此数组中第一个元素的地址实际上与数组的地址相同。因此,第3行

grid=newint[grid_x]

分配足够的内存(在堆上)来保存数组,并将其地址放入
网格
变量中。在这一点上,内存的内容与上次使用物理硅时的内容是一样的。从未初始化的内存中读取将导致不可预测的值,因此您观察到忽略第4行会导致奇怪的输出

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

*grid = 34;
表示将网格所指向的内存内容设置为值34。但是第3行给出了数组第一个元素的地址。所以第4行将数组的第一个元素设置为34

在C中,数组使用基于零的索引,这意味着数组的第一个元素是数字0,最后一个是数组中的元素数-1。因此,填充数组的一种方法是依次为每个元素编制索引,为其设置一个值

for(int index = 0; index < grid_x; index++)
{
    grid[index] = 34;
}
for(int index=0;index
或者,您可以继续使用指针来完成相同的工作

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;
}
for(int*pointerToElement=grid;0
享受数组和指针带来的乐趣,它们始终提供了大量的机会,让您可以不眠不休地思考代码为什么不工作、PC重新启动、路由器着火等问题。

“第3行是否应该创建一个包含5个元素的数组?”是的。或者用数字5填充第一个元素?“否”。如果没有第4行,第5行将读取“-84215051”。“是的,因为数组指向内存中的某个位置,即n
grid[x][y];
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];
int * grid;
*grid = 34;
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;
}