一維數組名可以賦值給一個普通的指針

數組通常轉換成指向首元素的指針。

int a[4];
int *ap = a;

二維數組名卻不可以賦值給一個指向指針的指針

二維數組轉換成的指針也指向首元素(一維數組),而不指向指針。

int b[2][4];
int (*bp)[4] = b;

據 @emmm 的評論編輯了回答。


在C語言中,數組在多數表達式中(例外包括取址和sizeof),隱式轉換為指向其首元素的指針右值,稱為數組退化。

二維數組的元素是一維數組,因此其退化後的類型是指向一維數組的指針,而不是指向指針的指針。


我覺得能提出這個問題的人,對指針是真正地思考過的。這個問題的答案也很簡單,就一句話「不同類型的東西不能互相賦值」。舉個例子:

家貓、野貓和獅子都是貓科動物,家貓和野貓可以繁衍出後代,而家貓和獅子是沒法繁衍出後代的。你看,同屬於貓科動物的它們不一定都能繁衍後代。

回到這個問題上,我們以int a[]舉例,a是數組名,它本質上是int *類型的指針,而普通的指針p如果也是int *類型的話,那麼a就可以賦值給p,也就是a是家貓,p是野貓,都是同一個子科目,它們可以繁衍後代。

二維數組int b[][]的數組名b,本質上是int (*)[]類型的指針,指針的指針int **q的類型是int **,倆不同類型的東西不可以互相賦值2793068398這裡如果b是家貓的話,q就是獅子,是倆不同的子科目,不可以繁衍後代。

所以,它們看著都是指針,但是指針的類型也分好幾種呢,就是這麼簡單咯!

正版!朱偉戀詞2022考研英語辭彙單詞書歷年真題5500詞淘寶¥ 39.80去購買?


可以,不過有編譯」警告罷了。警告是在提示你可能存在潛在問題,而不是不能這樣做,你完全可以強制轉換。編譯器行為罷了,就像char* s = "hello";其實字元串常量應該是const char*,但是C編譯器偏偏沒有警告,C++編譯器就會有警告,因為C++的類型檢查比C嚴格。


至於為什麼有警告:

拋個問題給題主,int a[5]; 請問a的類型是什麼?

明白了,也就知道了。


經過大佬 @左江 提醒,不同類型的指針做類型強轉還是會被編譯器搞鬼的,被稱為「嚴格別名規則」,讀書少確實不太行。這規則確實會給編譯器優化提供一定的操作空間,但是確實容易限制程序猿的發揮(′;︵;`)。有興趣的盆友可以去看看gcc官方文檔:https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc.pdf搜索-fstrict-aliasing關鍵字了解詳情,或者看看c99標準里的對應關鍵字也行。

建議題主不要聽那些說指針跟數組是一回事的人瞎BB,類型什麼的,都是浮雲。指針是根針,數組是個池子,能有啥關係?

只是恰好,多維數組是數組的數組,數組指針的偏移量粒度等於該數組類型的長度而已

數組跟指針,是毫不相干的倆東西,只是某些情況下看起來比較像。

數組名是個特殊的指針常量,數組跟指針沒關係。其實作為解引用符號時,方括弧下標和星號都是專屬於指針的,跟數組沒關係,之所以可以用來表示對數組元素的索引,只是對數組名這個特殊的指針常量的解引用而已。數組是個池子,指針是根針,能有關係才見鬼。

另,附上c里一加一可以等於很多數的表達式

c里,一個數等於多少,取決於倆東西:

1.實際存儲介質中存儲的內容,

2.讀取它的方式(即認為該地址上存儲的類型是啥)

即說到底指針有且僅有倆屬性:值和類型

數組有且僅有倆屬性:數組長度和數組維數

本來倆毫不相干的東西,只是有些時候看起來有點像,但是不要被表象迷惑,畢竟只是看起來而已。


沒怎麼用過。不過「指向指針的指針」那是二級指針啊。和你二維數組有什麼關係。c語言的二維數組實際上在內存模型上就是所謂的「一維」連續數組。就是個普通指針而已。


推薦閱讀:
相关文章