動態數組(一維二維)探祕

由於作leetcode的一道算法題https://leetcode-cn.com/problems/regular-expression-matching/,須要用到二維數組,結果本身在理解和使用上有很大誤解,因此單獨拿出來,從內存等各方面透徹的梳理一遍。算法

一維數組

    char * a = (char*)malloc(8 * sizeof(char));
    memset(a, 0, 8);
    for (int i = 0; i < 8; i++)
    {
        *(a + i) = 'a' + i;
    }
    for (int i = 0; i < 8; i++)
    {
        cout << *(a+i);
    }
    for (int i = 0; i < 8; i++)
    {
        cout << a[i];
    }
    free(a);

輸出內容abcdefghabcdefghexpress

這樣申請與char a[8]是同樣的,無論是底層實現仍是使用,都是同樣的,這就是一個8個字節長度的數組。咱們看內存,也是一段連續的數據。數組

釋放內存的時候,系統能夠根據內存管理把這連續的8個字節的空間回收。函數

二維數組

咱們先看一下正常的用法

    char a[8][4] = { 0 };
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            a[i][j] = 'a' + i;
        }
    }
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << a[i][j];
        }
    }

輸出結果 aaaabbbbccccddddeeeeffffgggghhhhspa

咱們看一下內存.net

是一段連續的內存,數組a[n][m],按照m跳度,前m個是第一個n的序列,而後是第二個n的m個序列,實際上這是一個一維數組。翻譯

看看咱們第一種實現

        char** a = (char**)malloc(8 * sizeof(char*));
        for (int i = 0; i < 8; i++)
        {
            *(a + i) = (char*)malloc(4 * sizeof(char));
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                a[i][j] = 'a' + i;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << a[i][j];
            }
        }

a是一個數組,也就是a指向了申請的一塊空間,空間是8個char*大小。而後爲a的每個數組元素,又指向了一塊空間,空間是4個char大小。內存空間如圖所示,a指向了一塊空間,有8個元素,每一個元素的空間用來保存了一個char*的數據,也就是char的指針,a算是一個指向指針的指針。a是一個指針,指向了一塊數據,這塊數據保存的是一個指針,指向了一塊數據,這塊數據保存的是一個4字節的char。指針

 

 咱們看一下實際的內存地址code

 

這是char*數組a的數據,8個char*的空間,標藍的是第一個a+0保存的數據,是一個指針地址,由於是32位的,因此是4個字節,翻譯過來就是0X00557600blog

咱們看一下a的第一塊數據指向的內容,是一塊數據,保存了aaaa,四個a。

 

這就是二維數組的實質。一維數組a指向了一塊數據,保存的是字符,二維數組指向了一塊數據,保存的至關因而一個一維數組指針的列表,每一個二維數組元素至關於一個一維數組。以此類推,三維數組就是保存了一個二維數組指針的列表。

它是如何訪問數據的呢,與一維數組同樣,先經過a+i訪問到a的元素指針,而後經過*(a+i)訪問到數據,這個數據又是個數組,經過*(a+i)+j訪問到元素指針,再經過*(*(a+i)+j)訪問到數據,最後提醒,別忘了釋放空間。

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << *(*(a + i) + j);
            }
        }
        for (int i = 0; i < 8; i++)
        {
            free(*(a + i));
        }
        free(a);

二維數組的第二種實現

咱們看到,若是經過char a[8][4]申請一個二維數組,實際上空間是連續的,咱們能不能模擬呢,這樣整塊申請內存,效率更高。代碼以下

        char* a = (char*)malloc(8 * 4 * sizeof(char));

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                *(a + i * 4 + j) = 'a' + i;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << *(a + i * 4 + j);
            }
        }
        free(a);

申請了一個一維數組,大小是a[n][m]中n*m個數組元素個數。訪問呢,就模仿二維數組的訪問,m個元素是一組。內存以下

這裏有一個小小的一問,char a[8][4]這種能夠經過 a[1][2]訪問,可是這種方式不行。char[8][4]系統知道是一個二維數組,保留了它的信息,知道如何跳,而char* a = (char*)malloc(8 * 4 * sizeof(char));系統認爲是一維數組,按照二維的那種方式跳,就會運行錯誤。

插曲

除了malloc,也能夠用new,更方便一些

char * a = new char[8]();

減小了初始化的步驟,這裏就是建立一塊空間,大小是8,單位是char,調用()初始化。這裏()的意思就是調用默認構造函數等於new char[8]{}

二維數組的第三種方法

上面的方法空間在一塊兒了,可是沒法用二維數組的方式訪問 ,很彆扭,那麼有沒有動態二維數組呢,上面插曲的new爲咱們提供了方法。

        auto a = new char[8][4]();
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                a[i][j] = 'a' + i;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << a[i][j];
            }
        }
        delete[](a);

auto a = new char[8][4]()究竟是什麼

感謝評論參考 https://blog.csdn.net/u012027907/article/details/16370625

這種方法的實質是什麼呢?實際上就是第二種方法,只不過告訴了系統,這是一個二維數組。那麼二維數組的指針怎麼定義呢?能夠用以下代替

        char(* a)[4] = (char(*)[4])malloc(8 * 4 * sizeof(char));

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                a[i][j] = 'a' + i;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << a[i][j];
            }
        }
        free(a);
相關文章
相關標籤/搜索