1.數組和指針
對於一維數組其實很好理解。
假設數組int A[n],
和int *p;
因爲都知道數組名其實就可以表示數組的首地址
既p = A;
然後我們可以用指針來操作數組。
*p = A[0];
*(p+1) = a[1];
然後去掉(),既*p+1=A[0]+1;因爲*的優先級高於雙目運算符+,所以是先取了數組第一個元素,然後+1;
*p++ 則是其實是兩步操作,先取了p指向值,然後指針++;
其實按運算符優先級和操作順序來說是這個表達式是這麼結合起來的。
*和++的優先級處於同一個級別,都是從右往左結合。因此p先和++結合,*和p結合。
但是p++是要等整個表達是結束,p值才++。因此正確的描述應該這樣的。
而對於前面說先取p指向值,然後指針++只是說表面上和邏輯是這麼呈現的。
但是這和先取p指向值,然後p指向值++是完全不同概念。
這個的表達形式應該是這樣(*p)++;
而*p++這樣的表達是一般常用指針操作數組進行元素的遍歷。
對於多維數組,就會有點複雜。
比如int A[n][n].
數組名此時數組名是數組A第一個元素的首地址。
但是會如果我們申明一個int *p指針,給p賦值爲
p = A是有誤的。p指向的是一個int類型變量的地址。
但是A是一個2維數組,A表示的首地址是指向是一個(指向int變量類型的指針),既指針指向的是
一個指針變量,也就是A的指向感覺是比p指向多了一級。
因此 這樣表示 p = *A從類型來看是正確的。
如果將A[0]看成整體,*A就表示了A[0]的首地址,而我們知道A[0]中又有N個int類型的元素,同樣如果我們在細分一下的話,就可得知,*A也就表示是A[0][0]元素的地址,那麼對於獲取A這個多維數組的第一個int元素
我們就可以這麼表示了 **A,
因此我們取A[n][n]的第一個元素可以這麼表示
A[0][0] = **A = *A[0];
那麼如何遍歷A中的元素。
*(*A+i); 0<=i <=n^2;
比如i取2,表達式的意思就是,*A取了A[0]中元素的首地址,然後偏移了兩位,
就指向了A[0]中第三個元素A[0][2];
那麼稍微改變下**A+i表示的是什麼?
*的優先級高於雙目+。那麼實際上(**A)+i;
添上括號就很好理解了,一直做的是取了A[0][0]然後+i。
至此,我們還可以推測出一種情況
**(A+i),此刻A指針偏移了i位,事實上是從A[0]變成了A[0+i];
如果和一維數組一樣用指針來操作數組元素遍歷。
我嘗試申請一個int *p用++自加來實現
int *p = A[0]後其實和一維數組操作是一樣的。
tips;這邊在提一個很重要的問題。
我們以一維數組舉例
我們知道int *p = A;
然後可以用 p++來遍歷數組。
那直接用A++不就也可以實現位置偏移嘛?
但是這是錯誤的,數組A確定後,A首地址是固定不變的,假設讓我們操作了
A++,那麼也就是說A數組首地址往後偏移了一位,那對於A來說,A已經不能表達
原來那個數組了。因爲你地址偏移了,對於數組來說,你就少了一個元素存儲空間,
因此,資料行也明確定義了不能直接拿數組來做指針++或是--,編譯器也報錯通不過。
以上是一個朋友去校招碰到的一個題目,多維數組用指針操作的問題~