嵌入式學習資源——深入理解C語言指標的奧秘-2

千鋒教育官方發表於2019-08-14

接著我們的C語言指標的奧秘-1接著講:

我們可以用一個指標和一個迴圈來遍歷一個陣列,看例子:

  例三:


intarray[20];
int*ptr=array;
...
//
此處略去為整型陣列賦值的程式碼。
...
for(i=0;i<20;i++)
{
  (*ptr)++;
  ptr++

  這個例子將整型陣列中各個單元的值加 1 。由於每次迴圈都將指標 ptr 1 ,所以每次迴圈都能訪問陣列的下一個單元。

  再看例子:

  例四:

   1 chara[20];

   2 int*ptr=a;

   ...
   ...

   3 ptr+=5;

  在這個例子中, ptr 被加上了 5 ,編譯器是這樣處理的:將指標 ptr 的值加上 5 sizeof(int) ,在 32 位程式中就是加上了 5 4=20 。由於地址的單位是位元組,故現在的 ptr 所指向的地址比起加 5 後的 ptr 所指向的地址來說,向高地址方向移動了 20 個位元組。在這個例子中,沒加 5 前的 ptr 指向陣列 a 的第 號單元開始的四個位元組,加 5 後, ptr 已經指向了陣列 a 的合法範圍之外了。雖然這種情況在應用上會出問題,但在語法上卻是可以的。這也體現出了指標的靈活性。

  如果上例中, ptr 是被減去 5 ,那麼處理過程大同小異,只不過 ptr 的值是被減去 5 sizeof(int) ,新的 ptr 指向的地址將比原來的 ptr 所指向的地址向低地址方向移動了 20 個位元組。

  總結一下,一個指標 ptrold 加上一個整數 n 後,結果是一個新的指標 ptrnew ptrnew 的型別和 ptrold 的型別相同, ptrnew 所指向的型別和 ptrold 所指向的型別也相同。 ptrnew 的值將比 ptrold 的值增加了 n sizeof(ptrold 所指向的型別 ) 個位元組。就是說, ptrnew 所指向的 區將比 ptrold 所指向的記憶體區向高地址方向移動了 n sizeof(ptrold 所指向的型別 ) 個位元組。

  一個指標 ptrold 減去一個整數 n 後,結果是一個新的指標 ptrnew ptrnew 的型別和 ptrold 的型別相同, ptrnew 所指向的型別和 ptrold 所指向的型別也相同。 ptrnew 的值將比 ptrold 的值減少了 n sizeof(ptrold 所指向的型別 ) 個位元組,就是說, ptrnew 所指向的記憶體區將比 ptrold 所指向的記憶體區向低地址方向移動了 n sizeof(ptrold 所指向的型別 ) 個位元組

運算子 & *


  這裡 & 是取地址運算子, * ... 書上叫做 " 間接運算子 "

   &a 的運算結果是一個指標,指標的型別是 a 的型別加個 * ,指標所指向的型別是 a 的型別,指標所指向的地址嘛,那就是 a 的地址。

   *p 的運算結果就五花八門了。總之 *p 的結果是 p 所指向的東西,這個東西有這些特點:它的型別是 p 指向的型別,它所佔用的地址是 p 所指向的地址。

  例五:


inta=12;
intb;
int*p;
int**ptr;
p=&a;
//&a
的結果是一個指標,型別是 int* ,指向的型別是 int ,指向的地址是 a 的地址。
*p=24;
//*p
的結果,在這裡它的型別是 int ,它所佔用的地址是 p 所指向的地址,顯然, *p 就是變數 a
ptr=&p;
//&p
的結果是個指標,該指標的型別是 p 的型別加個 * ,在這裡是 int ** 。該指標所指向的型別是 p 的型別,這裡是 int* 。該指標所指向的地址就是指標 p 自己的地址。
*ptr=&b;
//*ptr
是個指標, &b 的結果也是個指標,且這兩個指標的型別和所指向的型別是一樣的,所以用 &b 來給 *ptr 賦值就是毫無問題的了。
**ptr=34;
//*ptr
的結果是 ptr 所指向的東西,在這裡是一個指標,對這個指標再做一次 * 運算,結果就是一個 int 型別的變數。  


  指標表示式

  一個表示式的最後結果如果是一個指標,那麼這個表示式就叫指標表式。

  下面是一些指標表示式的例子:

  例六:


inta,b;
intarray[10];
int*pa;
pa=&a;//&a
是一個指標表示式。
int**ptr=&pa;//&pa
也是一個指標表示式。
*ptr=&b;//*ptr
&b 都是指標表示式。
pa=array;
pa++;//
這也是指標表示式。  


  例七:


char*arr[20];
char**parr=arr;//
如果把 arr 看作指標的話, arr 也是指標表示式

char*str;
str=*parr;//*parr
是指標表示式
str=*(parr+1);//*(parr+1)
是指標表示式
str=*(parr+2);//*(parr+2)
是指標表示式  


  由於指標表示式的結果是一個指標,所以指標表示式也具有指標所具有的四個要素:指標的型別,指標所指向的型別,指標指向的 區,指標自身佔據的記憶體。

  好了,當一個指標表示式的結果指標已經明確地具有了指標自身佔據的記憶體的話,這個指標表示式就是一個左值,否則就不是一個左值。

  在例七中, &a 不是一個左值,因為它還沒有佔據明確的記憶體。 *ptr 是一個左值,因為 *ptr 這個指標已經佔據了記憶體,其實 *ptr 就是指標 pa ,既然 pa 已經在記憶體中有了自己的位置,那麼 *ptr 當然也有了自己的位置。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69914734/viewspace-2653637/,如需轉載,請註明出處,否則將追究法律責任。

相關文章