1. 程式人生 > >詳解:C語言中的指標和p, p+1, *(p+1), *P+1, p[0], &p[0] 的含義

詳解:C語言中的指標和p, p+1, *(p+1), *P+1, p[0], &p[0] 的含義

解析:C語言中的指標和p, p+1, *(p+1), *P+1, p[0], &p[0] 每一種表示式的含義

 一、先解決一個問題:什麼是指標 指標就是存放地址的變數。很好,百度上就是這個答案(哈哈,感覺這句話很廢話)。 指標是一個大小固定為4個byte的變數,不管是什麼型別的指標大小都是固定的,因為存放是一個地址資訊。
void main()  
{
	int a = 1;
	char b = 'a';
	int* i = &a;//指向一個int值變數
	char* c = &b;//指向一個char值變數		
}

從上面的程式中可以看出來,定義一個int型別的指標和char型別的指標,但它們的大小都是4byte,因為存放的是對應型別變數的地址而不是對應型別變數的內容。

二、指標P與指標P+1

void main()  
{  
      int a[] = {1,2,3,4};
      int* b = (int*)&a;
}


在上面的程式中定義一個int型別的指標(在這裡要重點強調一下,這裡是int型別的指標,對後面的內容的理解很重要),指標b的地址為0x0018ff38,指標b+1的地址為0x008ff3c,他們中間相隔了4byte,剛好是一個int型別的大小,而指標b又是一個int型別的指標,所以我們可以得出一個結論:

指標P+1 = 指標P + sizeof(指標的型別) *  1

三、陣列和指標(剛好看到上面程式結果想到的一個點)

在上面的執行結果中,我們可以發現a[1]和*(p+1)得到的值是一樣的,因為&a[1]指向的地址和P+1指向的地址是一致。

在C語言中獲得陣列的值有兩種方法:

第一種:匿名方法   --> a[1]

第二種:具名+匿名方法  --> P + sizeof(陣列型別)*1

四、*(P+1)和*P+1的不同之處

void main()  
{  
      int a[] = {1,4,3,4};
      int* p = (int*)&a;
}

其實這個問題很簡單,因為*的優先順序比+的優先順序高,所以*P+1在編譯器中是先取出p指向的int值然後加1,就是a[0]+1,也就是1+1,所以*p+1取出的值等於2。而*(P+1),因為多了一個括號,所以就變成指標P+1後,再取出裡面的值,也就是a[1]的中的值,所以*(P+1)取出的值等於4。

五、*(P+1)和P[1]

也是用上面的程式,我直接上執行結果,一看就知道了


這大概是寫法不同把,我個人的理解應該是跟上面第三點的兩種取值方法原理相似。我做了以下的嘗試

void main()  
{  
      int a[] = {1,4,3,4};
}

可以正常執行,沒有報錯,這裡就證明我的一個猜想,定義一個int型別的陣列a,可以直接把a當做一個指向陣列a首地址的int型別的指標使用。這就是說,定義一個int陣列其實編譯器內部開闢一個記憶體塊和指向首地址int型別的指標給我們。

到這裡,最後一個&P[0]的含義就很明顯了,可以看成取陣列第一元素的地址。

文章很多地址均為本人用例子嘗試後得到的結論,可能不是很正確,如果您發現有錯誤的地方,請在評論中指出,以免誤導其它人,本人不勝感激。