前言:
c:陣列名參與+運算後就會退化為指向該陣列元素型別的指標。
文章末位我已經點明了其中c結論是有問題的,其實前邊兩條我也不敢很自信的說他們是完全正確的。但是我理解的就是這樣,我也反覆推敲過,感覺暫時已經到了我能力的極限不可能再做出更好的優化和這總結了。總之,現階段這三條結論我覺得已經表述清楚了我的理解,雖然以後極可能會做修改。這篇文章,我們主要圍繞著陣列名 a 來**指標陣列和陣列指標,不要糾結為啥還是a,如果你開心,也可以是b。
( 以下**編譯環境均為win32–vs2017 )
1.陣列名a到底是什麼型別?
int main() ;
printf("%d\n", *a); //
*a ==a[0] ==1
printf("%d\n", *(a + 1)); //
*(a+1) ==a[1] == 2
printf("%d\n", sizeof(a)); //sizeof(a) ==8
printf("%d\n", sizeof(a+1)); //sizeof(a+1)==4
puts("----------華麗分割線-----------");
我曾經掉到過 sizeof(a) 的坑裡邊過:
以 int a[2]=; 這個陣列為例。
sizeof(a)==8,為什麼a的步長不是8位元組,而是4位元組?
為什麼sizeof(a+1)==4?
可能有些同學一開始會感覺,這是巧合,和win32平台下指標占用空間大小有關係。但是請看二維陣列:
int b[2][2]=;
sizeof(b)==16,為什麼b的步長,不是16位元組,而是8位元組?
為什麼sizeof(b+1)==4?
可能很多同學看到這裡就覺得懂了!對!是陣列指標!但是我要告訴你,你的想法沒錯,但是我們要更嚴謹一點,因為一維陣列的int型陣列的陣列名是int *指標,所以我們說:陣列名的型別是指向該陣列元素型別的指標。
回顧以下結論c:
c:陣列名參與+運算後就會退化為指向該陣列元素型別的指標。結論c終極版:
c:陣列名參與運算後就會退化為指向該陣列元素型別的指標(sizeof運算子除外)。
我們已經對+運算子進行了研究,其實*和都可以算作 乙個運算子,大家可以自己討論一下,這兩個運算子是否滿足結論c。
2.陣列指標和指標陣列
濫用c指標會讓人痛不欲生,如果想秀技術,指標完全可以你的操縱下勸退新手。但是你工作中讓指標妙筆生花,你的老闆和同事不會削你嗎?比如int **(*p)[3][3],哪位大神可以和我解釋以下這個陣列存在的意義?
所以我們還是老老實實的回歸二維陣列指標和指標陣列:
int(*p)[i],這是乙個陣列指標,注意是指標!p指向乙個含有 i個int型元素的一維陣列,他的步長就是i*sizeof(int)。
int *p[2],這是乙個指標陣列,他本質上是乙個一維陣列,但是每個元素都是乙個
int 。所以說指標陣列我更喜歡這樣定義,int*
p[2],有沒有感覺這樣看起來更容易理解?
其實指標陣列大多數人理解的都沒問題,但是陣列指標這一塊就容易犯迷糊,我想告訴大家如果不理解,那麼你就記住他怎麼用,總有一天你會理解的。
後邊留幾個小題目:
1,用一維int*指標在堆區申請乙個 sizeof(int) * 16個位元組的空間,然後用二維陣列的方式遍歷這段空間,a[4][4]。
2,定義乙個二維陣列int a[4][4],定義乙個int **p = a,那麼可以用p[4][4]的方式遍歷這個陣列嗎?
3,定義乙個二維陣列int *a[4],定義乙個int **p = a,那麼可以用p[4][4]的方式遍歷這個陣列嗎?
陣列指標與指標陣列的理解
在進行閱讀yolo原始碼的時候,由於其都是用c寫的,在指標方面,遇到了很多問題,現在就問題,對c進行更深的理解。1.c當中的strcpy與strcat函式的區別 字串處理strcpy,strcat函式的用法 1 strcat是用來連線兩個字串的,原型是char strcat char dest,ch...
指標陣列與陣列指標的理解
指標陣列與陣列指標是十分繞口的,也不容易記憶,想要知道它是什麼?就看它後面是什麼詞!指標陣列 指標陣列後面的詞就是陣列,所以它就是陣列,而陣列裡面放的是指向這個型別的指標 陣列指標 陣列指標後面的詞是指標,則它就是個指標。在知道指標陣列和陣列指標字面的意思之後,我們就要解決遇到的表示式是指標陣列還是...
我理解的指標與引用
最近在學習golang的過程中,發現乙個有意思的事情,有的文章說函式呼叫傳參時slice是引用傳遞,有的說是值傳遞。為什麼同乙個東西大家會不同認識?為了搞清楚其本質,我進行了以下內容的研究 變數的變數名 變數值 變數位址在記憶體中是怎麼樣的?指標的定義是什麼?引用的定義是什麼?二者有什麼關係?函式傳...