**p[] 和*(*p)[] 有什麼區別?
**p[] 和*(*p)[] 有什麼區別?
這是周經還是月經問題……
有個簡單的判定方法:
若有個括弧包著 //* 和標識符,則聲明的變數是左值引用/右值引用/指針,指針可能有多層。
若無這種括弧,且標識符右邊接著 [ ,則聲明的變數是數組。
表達式里不能有這兩個東西。
聲明裡,左邊需要有個指定符和可選的限定符。
下面討論 T **p[] 和 T *(*p)[] ,使用偽代碼解釋
(1) array [unknown] of ^ ^ T , ^ T 表示指向 T 的指針,下同
(2) ^ array [unknown] of ^ T
另外 (1) 在函數參數列表中被處理成 ^ ^ ^ T 。
數組聲明 - cppreference.com (2) 的形式是合法的。
個人覺得實踐中 (2) 可能沒有適用的場所, (1) 可能有。
都是錯誤的表達式
作為declarator的話,都是一輩子都用不到的形式。有些人可能會告訴你寫這種東西的人會被直接開除
可以上這個網站看看:https://cdecl.org/
char *(*p)[]
declare p as pointer to array of pointer to charchar **p[]declare p as array of pointer to pointer to charType**[] 是一個數組類型,bound未知,裡面放的是Type**
Type*(*)[] 是一個指針類型,指向一個bound未知的數組,該數組裡放的是Type*
用右左法則讀一下就知道了,不用拆成好幾層,拆了反倒羅嗦不說,出了編譯錯誤以後編譯器照樣揉成整坨給你,不學會怎麼直接讀整坨的類型玩模板的時候要吃虧。
另外,數組不是指針也不相當於指針,只能decay成指針。第二個也不是語法錯誤。
前者相當於***p,後者語法錯誤
這個問題問錯了,你把它們當成表達式來問了。
如果是表達式,那麼方括弧里應該有個數字,或變數,否則你沒東西算。
那麼就應該是聲明了,你缺少了基類型。
一看就知道你是初學者,把指針聲明裡的星號,和普通算式里的間接訪問運算搞混了。
假設你的基類型是整數,用int,那麼int *p;這句話里int的意思,就是你指針里存的那個地址所對應的那個空間,是用來存整數的,不能存小數或字母等。
這個表達式是這麼看的:int * p;
不要這麼看:int *p;
int叫做基類型,int *叫做指向int型數據的指針類型——p里存的是個指針,也就是地址。
那麼int **,就是以int *為基類型的指針類型。它是指向指針的指針——它作為一個地址,所連接的存儲空間里,存的是指向int數據的地址。
所以int ** p〔〕;就是告訴計算機:給我一連串的空間,每個空間都是裝地址的,而且這些地址是指向地址的,別給我搞成指向其他類型的了……
那麼int * (*p)〔〕;想懂這句聲明,你要先明白一個概念:數組的名字,是一個指針。也就是說,數組的名字,他天然就裝著這個數組的地址(也就是它第一個元素的地址)。
比如int a〔〕;int * p;這兩句話寫出來了——那麼,我可以直接用p=a;把a的值給p。
所以int * (*p)〔〕;這句話里,(*p)相當於一個數組名,也就是地址,而這裡的*p,不是取p指向的值!而是在說:p是個指針!!!這個指針指向的指針,是這個數組的第一個元素的地址(也就是這個數組的指針)。
——再連上前面的int *——是說:有一連串的空間,每個空間里都裝的都是地址,這些地址指向的是int型數據。而p,是指針,它指向另一個指針,這個指針沒有名字,但是這個沒名字的指針,是指向這個數組的——也就是與這個數組裡的第一個元素的地址相等。
我知道你不懂,那就再舉個簡單的例子。
int a〔〕;int (*p)〔〕;這兩句話出來了,我能不能用p=a;來給p賦a值?顯然不能,因為a是個地址,p是個指向地址的地址,所以應該是p=a;來把a的地址賦給p。
或者直接寫成int (*p)〔〕=a;——這句話很有迷惑性啊!!一不留神你就把等號左邊當成個算式開始取值了——千萬時刻注意!當一個數據類型和星號共同出現時,它們的目的只有一個:告訴計算機這是指針。至於是指向啥的指針,你自己仔細。
我知道說了這麼多,可能你一個字都沒看懂。
但沒關係,這些都是純玩兒概念的,沒什麼實用價值,屬於「貴族的娛樂」~
優先順序 ()等於[]大於 *
int** p[N],二級指針的數組。
int* (*p)[N],p 指向大小為 N 的數組,且這個數組裡裝的元素是 int*。
PS, 這種聲明要先看括弧,*p代表這是一個指針。看右邊,這個指針指向一個規模為N的數組。最後看左邊,數組裡裝著int*。
顯然此處應使用array來避免[ ]符號。array&
要想弄清這些聲明的含義最行之有效的辦法是從右向左閱讀.我們看下*(*p)[],離p最近的符號就是括弧裡面的*,說明p是一個指針,數組指針具有如下形式:int (*pt)[],該指針pt指向一個數組,數組裡的元素是int,通過對比發現p指向一個數組,括弧前面的*說明數組裡面的元素是一個指針類型的。至於前面那個是二級指針,定義是這麼說的!
第一個是二級指針的數組,第二個是指向指針數組的指針
樓主可以去找一下[] 數組,()函數調用, * 解引用,這三個在一起時,假設不加括弧,他們的結合順序,弄清楚了之後,以後碰到這些都是小菜
**p[]是二級指針的數組,數組p中的每個成員都是二級指針*(*p)[]是指向行指針的指針。
例如
*pt[2];int *(*ptr)[2];就可以ptr = pt;這顯然是沒有看好C++ Primer。裡面講的很清楚。具體哪一頁忘記了。大概是在講指針或者類型別名的那部分,書中著重強調了如何去判別題主的疑惑。
推薦閱讀: