1. 程式人生 > >【c語言】帶你真正走進指標的世界——陣列與指標的關係(一)

【c語言】帶你真正走進指標的世界——陣列與指標的關係(一)

       每天下課之後,都感覺老師上課在神仙程式設計,我們一群凡人在底下面無表情地走神,前一秒還是在講加減乘除的基本用法,後一秒就變成了指標陣列、陣列指標、結構體指標和N級指標的性質以及運用............(真是令人頭禿 —^—)

————————————————下面是正文——————————————————  

一.N級指標

      (1). 一級指標

                  一級指標是我們最經常使用的指標,它的定義簡單明瞭——>  型別*  變數名  

,具體一級指標的定義我在前面的部落格裡已經對其有了介紹,感興趣的童鞋可以點選: https://blog.csdn.net/qq_41884002/article/details/84258830     檢視~~  下面是對一級指標進行一點知識擴充套件,請看下面程式碼

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;

	printf("%d\n",*p1);

    return 0;
}

                  編譯結果毫無新意

                然後再看下彙編

                 結果就是毫無新意的取出p1所存的地址中的值而已~那麼如果我把程式碼修改成這樣,結果還會一樣嗎?

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;

	printf("%d\n",*(p1+0));
	
	return 0;
}

                 彙編如下

                  嗯......在彙編的角度來看和直接寫*p1是完全一樣的,那編譯結果不出意料的話應該也是一樣的

              如果這樣的話,按照我對彙編的理解,突然想到了這樣的一種修改方法

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;

	printf("%d\n",p1[0]);
	
	return 0;
}

                 檢視一下結果

                   答案是出其地一致的,但是彙編會不會是不一致的呢???

                     答案是:它們三個彙編是一樣的。這個時候,我們可不可以得出這樣一個結論呢?

                                             *(P+ i)= P [ i ]     

                     我們嘗試一下程式碼

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;

	printf("%d\n",*(p1+1));

	printf("%d\n",p1[1]);
	
	printf("\n");

	printf("%d\n",*(p1+2));

	printf("%d\n",p1[2]);

	return 0;
}

                     結果如下:

                     得到的結果也是完全一致的,所以,我們可以得出第一個結論:在一級指標中,*(P+ i)= P [ i ] 

 

      (2). 二級指標

                 加一顆 ” * “ 就能成為一級指標,那麼兩顆 ” * “ 就是傳說中的二級指標了。二級指標其實就是我們俗稱的 “ 指標的指標”  ,很多書上或者網上都故作玄虛地擺弄著術語說

          

                     嗯......感覺這些人寫這些東西就是想混餚我的思路,故意不讓我聽明白的樣子......其實二級指標可以這樣理解!

int x = 100;
int* p1 = &x;

                    p1是個變數名,它的型別為int* ,它裡面儲存的是 x 的地址。over。

int x = 100;
int* p1 = &x;
int** p2 = &p1;

                   p2是個變數名,它的型別為int**,它裡面儲存的是 p1 的地址。over。

                   那我可不可以這樣寫呢?

int** p2 = &x;

                    編譯器告訴我們是不能的。

                    錯誤的原因是不能把一個型別為 int* 的值賦值給 int**  ,也就是我在文章開頭給出的那個連線的部落格裡面提到過的 ”&x“ 是 int* 型別的,只能用同是 int* 型別的p1來接收,而”&p1“ 是int** 型別的,只能用型別是int**的p2來接收。

                    綜上所述,二級指標(指標的指標),就是用來儲存型別為兩顆” *  “ 的值的容器。over。

                    接下來,我要放大招了!

                    根據一級指標中得出的一個結論:*(P+ i)= P [ i ] ,那在二級指標裡面,我們可不可以大膽地這樣來定義?

                    在二級指標中,*(*(P+ i)+j ) = P [ i ] [ j ]

                    我們寫出這樣的程式碼

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;
	int** p2 = &p1;

	printf("%d\n",*(*p2));

	printf("%d\n",*(*(p2+0)+0));

	printf("%d\n",p2[0][0]);

	return 0;
}

                     編譯的結果如下

                        再看一眼彙編

                  也是完全一樣的,所以可以得出這樣的結論:在二級指標中,*(*(P+ i)+j ) = P [ i ] [ j ]

——————————————————小插曲————————————————————

        有些同學不是很懂    *(*p2)  得出來的為什麼會是 100,這樣簡單地說一下:首先 (*p2 )得到的值是 p2所儲存的地址(就是p1 的地址) 所指向的東西  (就是 x 的地址),所以 (*P2) ==  x 的地址,然後 *(*p2) 得到的值是(*p2)所儲存的地址(就是x 的地址) 所指向的東西  (就是 100),所以 *(*P2) ==  100

—————————————————————————————————————————

 

      (3). 三級指標

                換句話說,三級指標就是” 指標的指標的指標 “,不過經過上兩級的指標的 ”洗禮“,估計再怎麼複雜的指標,都不會再搞混定義了,所以在此不再累贅。三級指標的賦值也是和二級指標一樣,賦值號左右的型別需要同時相等才能賦值,所以

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;
	int** p2 = &p1;
	int*** p3 = &p2;

	return 0;
}

                然後我們再來把上兩級的套路套在三級指標上面

#include <stdio.h>

int main()
{
	int x = 100;
	int* p1 = &x;
	int** p2 = &p1;
	int*** p3 = &p2;

	printf("%d\n",*(*(*p3)));

	printf("%d\n",*(*(*(p3+0)+0)+0));

	printf("%d\n",p3[0][0][0]);

	return 0;
}

                發現編譯的結果

                 和彙編的過程

                  也是完全一樣的,所以,當我們在往下一直探索 N級指標時,我們可以總結出幾個這樣的結論:

                                                                  1. *()與 【 】 是可以互相轉換的

                                                                   2. *(P+I) = P [ I ]

                                                                       *(* (P+I) + J ) = P[ I ] [ J ]

                                                                                      ............