C++用new建立二維陣列的方法

晚餐吃什麼發表於2018-11-25

問題來源

在C++中,陣列可以被視為一種型別——但是,不存在‘二維陣列’這種型別。二維陣列本身會被解釋成一個一維陣列:這個陣列的元素型別為另一種一維陣列。比如int[2][3]這個二維陣列,它會被編譯器視作一個元素型別為‘int[3]’的一維陣列。並且,‘int[3]’和'int[4]'會被當成不同的資料型別。

假設a, b為兩個int型變數,如果你希望這樣生成一個二維陣列:new int[a][b],是不會得到編譯器允許的——因為你沒有指定這個陣列的元素型別。由於b的大小未知,編譯器無法確定‘int[b]’到底是一個什麼型別。所以,要用new建立一個二維陣列,這其中有講究。

方法一:使用常量

接上:如果將b指定為一個常量,例如new int[a][5],其實質與new int[a]建立一個動態陣列並無多大區別——只是元素型別由int變為了'int[5]'而已。

示例程式碼:

void TestFunc_(unsigned int n)
{
    unsigned int i, j;
 
    // 元素型別為‘int[5]’的陣列,可賦值給‘int[5]’型別的指標.
    int (* array2D)[5] = new int[n][5];
    for(i=0; i<n; ++i)
    {
        for(j=0; j<5; ++j)
        {
            array2D[i][j] = i * 5 + j;
        }
    }
 
    // 回收方法和普通動態陣列相同,使用'delete[]'即可
    delete[] array2D;
}
用這個方法來建立二維陣列,比較直觀、易用,但它最大的限制在於:你必須在編譯時確定b的大小。

方法二:使用指標間接引用

首先建立若干個大小一致的動態陣列,然後將這些陣列的首地址(轉化為指標)按順序儲存到一個動態陣列中,就相當於模擬了一個二維動態陣列。

示例程式碼:

void TestFunc_pointer(unsigned int height, unsigned int width)
{
    unsigned int i, j;
 
    //     陣列的元素型別為‘int *’,可賦值給指向‘int *’的指標.
    int **array2D = new int *[height];
    for(i=0; i<height; ++i)
    {
        array2D[i] = new int[width];
    }
 
    // 訪問.
    for(i=0; i<height; ++i)
    {
        for(j=0; j<width; ++j)
        {
            // 記憶體非連續,注意防止越界.
            array2D[i][j] = i * width + j;
        }
    }
 
    // 首先回收低一級的動態陣列.
     for(i=0; i<height; ++i)
    {
        delete[] array2D[i];
    }
    // 然後回收高一級的動態陣列.
    delete[] array2D;
}
這個方法實現了兩個維度的動態建立,訪問也比較方便。但是有一個缺點:由於低一級的陣列是分開建立的,所以整個二維陣列的記憶體不連續——類似‘array2D[i * width + j]’這樣的訪問就不要使用了,容易造成訪問越界。


方法三:使用vector

藉助STL中的vector,我們可以很直觀的建立一個二維陣列,而不需要用到基本陣列的概念。

示例程式碼:

void TestFunc_vector(unsigned int height, unsigned int width)
{
    typedef std::vector<int>    IntVector;
    typedef std::vector<IntVector>    IntVector2D;
    unsigned int i, j;
 
    IntVector2D *pArray2D = new IntVector2D;
 
    // 動態設定大小.
    pArray2D->resize(height);
    for(i=0; i<height; ++i)
    {
        (*pArray2D)[i].resize(width);
    }
 
    for(i=0; i<height; ++i)
    {
        for(j=0; j<width; ++j)
        {
            (*pArray2D)[i][j] = i * width + j;
        }
    }
 
    delete pArray2D;
}
可以看到,在vector這個‘更高階’的陣列幫助下,我們能夠很輕易的建立二維陣列。稍微美中不足的是由於引入了STL,程式會變得更大一些——但基本不影響執行速度。


==========================End============================
原文:https://blog.csdn.net/samuelcoulee/article/details/8674388 

相關文章