簡體   English   中英

我不明白如何在C ++中創建和使用動態數組

[英]I don't understand how to create and use dynamic arrays in C++

好的,我有;

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

第3行應該創建一個包含5個元素的數組嗎? 或者用數字5填充第一個元素?

第4行填充第一個元素,如何填寫其余元素?

沒有第4行,第5行讀取“-842150451”。

我不明白發生了什么,我正在嘗試使用用戶指定的x和y值創建二維數組,然后用用戶指定的數值逐個填充每個元素。 我上面的代碼是嘗試首先使用1維數組進行嘗試。

創建動態(可調整大小) 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

參閱參考文檔以查看std::vector上可用的所有操作。

第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;

第3行應該創建一個包含5個元素的數組嗎? 或者用數字5填充第一個元素?

創建一個包含5個元素的數組。

第4行填充第一個元素,如何填寫其余元素?

grid[n] = x;

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

第3行在內存中並排分配5個整數的內存,以便可以通過...訪問和修改它們。

括號運算符x[y]*(x+y)完全等價,因此您可以將第4行更改為grid[0] = 34; 使它更具可讀性(這就是為什么grid[2]會和2[grid]做同樣的事情!)

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行填充第一個元素,如何填寫其余元素?

使用operator [] ,例如:

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


沒有第4行,第5行讀取“-842150451”。

你只是閱讀未初始化的內存,它可以是任何值。

我不明白發生了什么,我正在嘗試使用用戶指定的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];

但是你必須在數組的生命周期結束時對所有子數組進行刪除。

數組只是一塊連續的內存塊。 因此它有一個起始地址。

int * grid;

是整數地址的C表示,您可以將*讀作'指針'。 由於您的數組是整數數組,因此數組中第一個元素的地址實際上與數組的地址相同。 因此第3行

grid = new int [grid_x];

分配足夠的內存(在堆上)來保存數組並將其地址放在grid變量中。 此時,該內存的內容與上次使用物理芯片時的內容無關。 從未初始化的內存中讀取將導致不可預測的值,因此您觀察到遺漏第4行會導致奇怪的輸出。

還記得*指針嗎? 在第四行,您可以將其讀作“指針的內容”,因此

*grid = 34;

表示將grid指向的內存的內容設置為值34.但第3行給出了grid數組第一個元素的地址。 因此第4行將數組的第一個元素設置為34。

在C中,數組使用從零開始的索引,這意味着數組的第一個元素是數字0,最后一個是數組中的元素數 - 1.因此,填充數組的一種方法是依次為每個元素編制索引以為其設置值。

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重啟,路由器着火等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM