C指針和數組的關係詳解

1.C中數組和指針的關係

對於任意類型的數組arr,對於同類型的指針類型parr(確切一點,能夠假設類型爲int,即int arr[], *parr)。它們之間有以下"內幕":數組

1.數組的名稱arr自己就是一個指針,這個指針指向數組的第一個元素函數

2.由於名稱arr自己是指針,因此能夠直接賦值給同類型的指針parr:parr = arr,這使得parr也指向數組的第一個元素,因此這個賦值過程等價於parr = &arr[0]spa

3.指針和數組名在效果上是等價的。它們的區別在於:指針是變量。指針變量能夠參與表達式的計算,如parr++parr=arr是有效的,而arr=parrarr++是無效的 4.數組的各元素在內存中是連續的,能夠經過索引下標的方式arr[i]獲取任意一個元素,而arr[i+1]必定表明下一個元素(除非數組索引越界),arr[i-1]必定表明前一個元素(除非沒有前一個元素) 5.由於數組名也是指針,因此也能夠將獲取元素的方式寫成*(arr),它等價於arr[0],即表明第一個元素的值。同理,*(arr+1)等價於arr[1]即表示第二個元素,*(arr+i)等價於arr[i]即表示第i+1個元素 6.也就是說,arr表明第0個元素的地址,arr+1表明第2個元素的地址,arr+i表明第i+1個元素的地址 7.也能夠直接經過指針的加減法運算取得對應位置的元素地址parr表明的是第一個元素(index=0)的地址,parr+1表明第二個元素(index=1)的地址,parr+i表明第i+1個元素(index=i)的地址 8.因此,*(parr)表明的是數組第一個元素的值,*(parr+1)表明數組第二個元素的值,*(parr+i)表明數組第i+1個元素的值指針

9.實際上,數組索引下標運算就是先轉換成對應的指針,再經過指針去取得對應元素的。因此,使用指針的效率比使用索引下標取數組值的效率要高,它少了一個轉換過程。或者說,指針和數組的索引是一一對應的關係。 10.因爲數組名指向的是數組的第一個元素,若是某個指針指向這個數組中的某個元素,那麼能夠說這個指針指向的就是一個子數組。例如arr是原始數組,那麼parr+3是一個子數組,arr+4也是一個子數組。這使得咱們可能訪問到數組第一個元素以前的元素(即父數組中子數組以前的元素),好比-一、-2在操做上都是容許的,除非這樣的訪問超越了父數組的邊界。code

2.指針和數組之間的幾個等價概念

等價的方式              |      意義
--------------------------------|---------------------
&arr[i]    arr+i      parr+i    |  都表示index=i元素的地址
--------------------------------|---------------------
arr[i]     *(arr+i)   *(parr+i) |  都表示index=i元素的值

特別的,當i=0時:blog

&arr[0]    arr      parr      都表示數組第一個元素的地址
arr[0]     *(arr)   *(parr)   都表示數組第一個元素的值

3.指針運算

指針是變量,能夠直接參與表達式的運算,指針是地址,能夠進行地址運算。索引

有效的指針運算包括:內存

  1. 相同類型指針之間的相互賦值運算
  2. 指針與整數之間的加、減法運算。這種運算可讓指針前移或後移N個數組的元素
  3. 指向相同數組中元素的兩個指針之間的減法或比較運算(指針與指針之間只能進行減法和比較),減法運算獲得的結果是指針之間的元素個數(例如(arr+3) - arr + 1表示第1個元素到第4個元素之間的4個元素)
  4. 0賦值給指針的運算、0轉換成指針類型的空、指針和0之間的比較
  5. 其它的運算方式都是非法的

對於指針和整數之間的加減法或指針的自增、自減運算,須要注意的是這些運算符之間的優先級以及從右向左計算的方式。class

parr += 1表示將指針向後移動一位,等價於++parr效率

*++parr表示取下一個數組元素,由於一元運算符*++的優先級相同,它們從右向左運算。

*parr++表示取得parr當前指向的元素,可是parr已經指向下一個元素了。

指針之間能夠比較大小,固然,只有指向同一數組的多個指針之間的比較纔有意義。p和q兩個指針,若是p指向的元素在q指向的元素以前,那麼p < q。經過比較指針,也能夠很容易判斷數組的訪問是否越界。例如,判斷指針指向的元素是否在第99個元素以後,對於只有100個元素的數組來講,這就是在判斷越界。

parr > &arr[99]
parr > arr + 99  // 與上等價

同理,指向同一數組的多個指針之間能夠進行減法運算(只能進行減法),指針之間的減法運算返回的是這兩個指針之間的元素個數

4.指針、數組和函數

C語言是按值拷貝的。

但由於數組名自己就是指向第一個元素的指針,因此按值拷貝也只是拷貝這個指針,拷貝獲得的指針副本仍然指向數組的第一個元素,而且經過這個指針可以遍歷到後面的元素。

由於拷貝後獲得的副本指針指向的仍然是函數外面的數組結構,因此在函數內部能夠直接經過這個指針修改外部數組。

下面兩種想要以數組做爲參數的函數在行爲上是等價的

void func1(int arr[]){}
void func1(int *parr){}

調用該函數時,均可以傳遞數組名或指針給它們:

int arr[];
int *parr;
parr = arr;

func1(arr);
func1(parr);
相關文章
相關標籤/搜索