pointer 指標

位址與變數關係

宣告兩個變數 int a=2,B=5;

這兩個變數各自會產生以上圖表的位址、資料(內容)。

欲知道a、B存放的位址,可以下 &a語法、B則是 &B

&加上變數就是意指「變數存放位址」。

printf ("&a=%d",&a); 輸出上表的 &a=7339532

printf ("*a=%d",*a); 錯誤、編譯不會過,變數非指標變數。

*接位址,應該是「指標」或「&變數」。

printf("*&a=%d\n",*&a); //輸出 *&a=2 //&a是位址

宣告一個指標變數:int *p=a;

p=&a; //把變數a的位址複製給p指標變數

printf("p=%d\n",p); //輸出 p=7339532,就是a所在位址

printf("*p=%d\n",*p); //輸出 *p=2,就是a內容

printf("p+1=%d\n",p+1); //輸出 p=7339536,加上一個int所佔的空間(不是1),這時候p還是指向a的位址中。

實際把p加1、再印出來會發生什麼事?

p=p+1;

printf("p=%d\n",p);

printf("*p=%d\n",*p);

※因為p所指向的位址已經變成7339536,所以*p就取不到a的內容了。

把p指向a、再把p所指向的位址的內容加1(等於把a加1)。

p=&a; //把p指向a

*p+=1; //p所指向的位址的內容加1

printf("*p=%d\n",*p);

printf("a=%d\n",a);

指標存放的是記憶體位址,這一點要記住。

挑出下列的表示式那些不合法?

int a; //宣告整數變數

int *p; //宣告指標變數

p=a;

*p=a;

*p=&a;

p=&a;

※你挑對了嗎?亂給是會導致無法編譯或是程式無法順利執行的呦。上面4只個有一個是對的,是哪一個呢?

陣列與位址的關係

陣列是可以存放多個資料的一個變數名稱,它的記憶體位址的安排是連續的,因此利用指標的特性來存取,會方便許多。

一維陣列與指標

int Arr[5]; //宣告一個存放5個資料的陣列,索引值0~4。

int *P1=Arr; //宣告一個指標變數P1,並指向Arr陣列的第一個元素Arr[0]的位址,它們的關係如下表。

如表所示,P1存的是Arr[0]的位址7335904,接下來只要將P1加上適當數字,就能對應到元素所在位址,P1+1意即Arr[1]的位址、餘此類推,要注意的是:不要超出陣列索引範圍0~4。

※將指標加1,會依據int占用記憶體的大小自動加上去,此例的int占用記憶體4Bytes。

你有注意到嗎?陣列的5個元素還沒給值,想要一次輸入5個數字以空隔開,可以這麼做:

for (int i=0;i<5;i++)

scanf ("%d",&Arr[i]);

例如輸入:12 30 36 5 8

接下來,找出陣列Arr內元素的最大值在哪裡?可以使用傳統陣列索引配合for迴圈。

int mx=0,index=0;

for (int i=0;i<5;i++)

if (Arr[i] > mx){

mx = Arr[i];

index = i;

}

printf ("Max=Arr[%d]=%d",index,mx);

利用指標來找,你可以這麼做:

int index=0;

int *P1=Arr; //把陣列第一個元素的位址給指標P1

for (int i=0;i<5;i++)

if ( *(P1+i)>=*(P1+index) ){

index = i;

}

printf ( "Max=Arr[%d]=%d",index,*(P1+index) );

二維陣列與指標

二維只是邏輯上的稱謂,實際存在於記憶體內也是連續的。

邏輯上是長這樣的:

在記憶體裡面,從Arr[0][0]~Arr[3][4]是連續的記憶體位址,每個元素間隔一個int的大小。(4Bytes,依系統而定)