C語言中的 int** 是什么?這要從int* 和int 說起...


文章來源:https://yian.me/blog/what-is/pointer-to-pointer-in-c-programing-language.html?utm_source=tuicool&utm_medium=referral

作者: Y!an

從int* 和int 說起

“int** 是什么” 這個問題其實不難。

我們可以遞歸分析,先看下int* 是什么,嗯?好像還可以繼續遞歸到int

我們都知道,int 是 C 的基礎數據類型整型 ,而多了個* 的int* 是指向整型變量的指針,那么int** 是什么就不言自明了,列個表:


 

看到這里,你對int**應該有了個初步的認識,但你可能覺得有點繞,沒關系,下面我們寫一段代碼看看:

#include <stdio.h>

int main()

{

    int i = 418;

    int* pi;

    // 根據上面的表格,我們知道 int* 是指向“整型”的指針,

    // 那么 pi 可以保存的是 int 類型的變量 i 的地址:

    pi = &i;

    int** ppi;

    // ppi 可以保存的是 int* 類型的變量 pi 的地址:

    ppi = π

    // 恭喜你,現在你已經知道了怎么定義 int** 類型的變量和給它賦值

    // 我們先寫到這里

    return 0;

}

深入思考

假如定義有int** p(為了方便,我們暫且把p認為是ppi的別名),那么p,*p,**p,p + 1,*p + 1,*(p + 1),**p + 1,*(*p + 1),**(p + 1)分別是什么?

先看最指針自身

乍一看有點多,開始有點慌是吧,沒關系,我們先看不帶加法運算的前三個:p,*p以及**p

從上面的代碼我們已經知道p就是存放int*類型變量的地址的變量

// 從上面暫停下來的地方我們繼續

    // 我們都知道,在指針前面加個 * 就是“取得這個指針指向的地址里的值”

    // 因為 pi 存放的是 i 的地址,那么 *pi 就是取得 i 存放的值,類型是 int

    // 同理,*ppi 取得的是 pi 存放的值,類型是 int*

    printf("*pi = %d, *ppi = %p\n", *pi, *ppi);

    // 輸出 *pi = 418, *ppi = 0000002D6FF2FD58 (*pi = 后面的值在每台機器上都可能不一樣)

    // 既然 *ppi 是 int*,那也就是說我們還可以對它再做一次解引用,

    // 拿到 *ppi 這個地址里存放的值,類型是 int

    printf("**ppi = %d\n", **ppi);

    // 輸出 **pi = 418

這時,你已經掌握p,*p以及**p分別是什么了

再看指針的加法運算

接下來我們還是先挑最簡單的,把不帶*的拿出來:p + 1,指針p做了個加法運算。

那么它加的這個1是什么?數字1?1位?1字節?

都不是,C指針加法運算里的數字操作數的單位是指針的長度,也就是說p + 1表示的時候內存中,緊挨着p的下一個可用空間的地址:

printf("ppi = %p, ppi + 1 = %p\n", ppi, ppi + 1);

    // 輸出 ppi = 0000008CA96FFB78, ppi + 1 = 0000008CA96FFB80

    // 並且我們可以看到 0000008CA96FFB80 - 0000008CA96FFB78 = 8(16進制)

    // 恰好等於 x64 系統下 1 個指針的大小:8 字節

那*(p + 1)是什么你應該也知道了,就是p + 1這個地址(假設是合法的)存放的值,類型是int*。

而*p + 1就是*p這個地址再偏移了 1 個指針長度

printf("*ppi = %p, *ppi + 1 = %p\n", *ppi, *ppi + 1);

    // 輸出 *ppi = 0000002D6FF2FD58, *ppi + 1 = 0000002D6FF2FD60

 

    printf("pi = %p\n", pi);

    // 輸出 pi = 0000002D6FF2FD58

    // 可以看到 *ppi == p

好了,還剩下最后三個:**p + 1,*(*p + 1),**(p + 1),先試試結合上面的知識,想一下在我們的例子中這三個分別是什么,想好之后再看下面的答案檢驗一下自己理解得對不對:

**p + 1:**p取得的是int,值是 418,所以**p + 1是 419

*(*p + 1):*p + 1是0000002D6FF2FD60,那么*(*p + 1)就是取得這個地址中的值(假設地址都是合法的)

**(p + 1):先對p + 1這個地址做解引用,得到新的地址*(p + 1),然后再對新的地址做解引用,得到的是個int(假設地址都是合法的)

再給你int***你也能回答了

現在再給你int***,相信你也知道它是什么並且知道它相關的運算是什么了:


 

最后

特別推薦一個分享C/C++和算法的優質內容,學習交流,技術探討,面試指導,簡歷修改...還有超多源碼素材等學習資料,零基礎的視頻等着你!

還沒關注的小伙伴,可以長按關注一下:


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM