【C语言进阶深度学习记录】三十 二维数组与二维指针
文章目錄
- 1 二維指針(指向指針的指針)
- 2 二維數組
- 3 二維數組的類型
- 3.2 如何動態申請二維數組
- 4 總結
1 二維指針(指向指針的指針)
- 指針的本質是變量
- 指針的指針是保存指針變量的地址。如下面的代碼:
為什么需要指向指針的存在?還記得之前學習的過程中說的函數傳值調用和傳址調用么?當要在函數內部修改傳進來參數變量的時候,需要傳址調用。
同理,如果傳進來的本來就是一個指針,想要修改該指針,那么就需要傳指向該指針的指針了。道理是一樣的。看下面的代碼就明白了:
- 代碼34-1.c:函數reset為重新為某一段內存分配一段內存空間(可大可小)
- 編譯運行結果為:
p = 0x8833008
reset p = 0x8833018
分析:
上述代碼中reset函數是重新為一塊內存分配另一個內存空間。我們知道要分配另一塊空間的話,地址肯定是會變的,那么想要最終將原來的地址p改變,就需要進行傳址調用。因為p本來就是指針,所以需要傳指針的指針進入reset函數。在reset函數中,進行重新分配內存空間并將原有的內存空間中的值拷貝到新的內存地址處。具體自己好好看一下reset函數就可以理解。
由運行可以看出:
- 地址p確實改變了,說明傳址調用起了作用
- 注意理解指向指針的指針的意義與用法。需要多琢磨。
2 二維數組
在C語言中,沒有二維數組的概念。它只是另一種形式的一維數組。
- 二維數組在內存中是以一維數組的形式排布
- 二維數組的第一維是一維數組(注意,一維數組相當于一個常量指針,也就說二維數組的第一維是存的指針)
- 二維數組的第二維是具體存的數值
- 既然一維數組的數組名可以看成是常量指針,那么二維數組的數組名也同樣可以看成是常量指針
- 結合上述四條看看下圖中的二維數組在內存中的樣式:
結合下面的代碼來認識認識二維數組:
- 代碼:34-2.c :
- 編譯運行結果為:
分析:
- 上述代碼并不是很難,所以不做詳細分析。只做以下幾點說明:
可以像這樣訪問二維數組:*(*(a+i)+j) 。可以想這樣理解: 其中a+i 代表是一維數組的第i個元素(即指針),*(a+i)代表找到第i個一維數組的起始地址,*(a+i)+j 表示第i個一維數組中的第j個元素的地址。最終*(*(a+i)+j) 表示取出元素。可以參考上面的二維數組的內存圖。
由:a = 0xbfb71b00, a+1 = 0xbfb71b0c 知道:二維數組的名字a可以看成是一個常量指針,它的值為二維數組首元素(這個首元素相當于是一個一維數組)的地址值。a+1就直接跨過一個一維數組的長度(這里是12,三個int)。
由:&a = 0xbfb71b00, &a+1 = 0xbfb71b24 知道: &a 代表整個數組的地址(這與一維數組很相似)。&a+1 就直接跨過整個數組的大小到數組末尾
由print_array 函數的參數是一維數組知道,二維數組在內存中排布是一維數組的形式。參考上圖。
3 二維數組的類型
- 之前學過以為數組的類型如下:
int a[5] ==>>> a的類型為: int*
- 二維數組的類型為:
int a[2][5] ==>>> a的類型為:int(*)[5]
3.2 如何動態申請二維數組
從下面的代碼來學習如何動態申請二維數組(參考下面的二維數組的內存模型就可以理解下面的代碼):
- 代碼:34-3.c:
- 編譯運行代碼如下:
雖然上述的數組中的各個值都是0,但是我們要知道malloc申請后的內存中的值是不確定的,并不一定是0
分析:
- 上述代碼中的核心代碼已經標注,多畫圖分析即可
- 可以參考下面的二維數組的內存模型圖進行分析:
至此,就學會了如何動態的申請二維數組了。一位數組的動態申請比較簡單,之前的文章也有學習過。
4 總結
- C語言中只支持一維數組,所謂的二維數組在內存中依然是以一維數組的形式排布
- C語言中的數組大小,必須在編譯期就作為常數確定。(畢竟數組的大小是數組類型的一部分,類型都不確定好,如何編譯)
- 二維數組就是一個一維數組存的元素是同類型的數組而已
總結
以上是生活随笔為你收集整理的【C语言进阶深度学习记录】三十 二维数组与二维指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3DMAX 的重要知识和插件介绍
- 下一篇: 【C语言进阶深度学习记录】十 C语言中: