C 速查手冊- 6.1 指標 - 程式語言教學誌

文章推薦指數: 80 %
投票人數:10人

C 語言的指標(pointer) 是用來指向儲存指向某個記憶體位址的資料型態(data type) ,實際上我們須認識電腦管理記憶體好比一個長列,每一列都有以位元編碼的位址,每一位 ... C速查手冊 6.1指標 C語言的指標(pointer)是用來指向儲存指向某個記憶體位址的資料型態(datatype),實際上我們須認識電腦管理記憶體好比一個長列,每一列都有以位元編碼的位址,每一位址都可儲存位元編碼的資料,示意圖如下 0000▭▭▭▭ 0001▭▭▭▭ 0010▭▭▭▭ 0011▭▭▭▭ 0100▭▭▭▭ 0101▭▭▭▭ 0110▭▭▭▭ 0111▭▭▭▭ 1000▭▭▭▭  ↓   ↓ 位址  內容 例如,我們宣告並指派初值22給整數變數(variable)a,編譯器(compiler)將變數a放在0011的記憶體位址裡,稍後我們再宣告另一個指向a的指標變數aPtr,假設編譯器aPtr放在0111的記憶體位址裡,如下圖所示 0000▭▭▭▭  45 0001▭▭▭▭  98 0010▭▭▭▭ 509 0011▭▭▭▭  22   a 0100▭▭▭▭1234 0101▭▭▭▭   0 0110▭▭▭▭ 382 0111▭▭▭▭0011aPtr 1000▭▭▭▭9000  ↓   ↓     ↓   ↓ 位址  內容   數值  變數 其他記憶體位址的數值可能為殘值,意思是如果沒有被程式利用,就對程式沒有用處。

因此,指標變數aPtr的內容為變數a的記憶體位址,如下 0000▭▭▭▭  45 0001▭▭▭▭  98 0010▭▭▭▭ 509 0011▭▭▭▭  22   a 0100▭▭▭▭1234    ↖ 0101▭▭▭▭   0     ↑ 0110▭▭▭▭ 382     ↑ 0111▭▭▭▭0011aPtr↗ 1000▭▭▭▭9000  ↓   ↓     ↓   ↓ 位址  內容   數值  變數 宣告C語言的指標變數,格式如下 datatype*name; *為宣告指標所用的運算子(operator),注意這跟乘法運算子一樣,編譯器會依上下文判斷星號用為宣告指標,還是用為兩數相乘。

很多情況下我們都需要直接操作記憶體位址,例如提升程式執行效率與建立資料結構。

C語言中使用指標需要先經過宣告,如下列程式建立一個指標變數aPtr指向變數a #include intmain(void) { inta=9; int*aPtr; aPtr=&a; printf("利用指標指向變數*aPtr=%d\n",*aPtr); return0; } /*《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:aPtr.c 功能:示範指標的宣告及使用 作者:張凱慶*/ 編譯後執行,結果如下 $gccaPtr.c $a.out 利用指標指向變數*aPtr=9 $ 以下為宣告指標變數 int*aPtr; 下一行替指標變數指派初值 aPtr=&a; 注意,&為取址運算子,可以取得該變數的記憶體位址,這跟位元運算的且運算子是相同的,所以編譯器會依前後文自行判斷用途。

這兩行可以合併寫成 int*aPtr=&a; 印出指標變數的一行 printf("利用指標指向變數*aPtr=%d\n",*aPtr); 指標變數使用時另加上的星號*,稱為間接運算子或反參考運算子,這是用來取得該指標所指向的數值,而非記憶體位址。

下列程式依次印出變數a的值與記憶體位址、aPtr的值與所參考的數值 #include intmain(void) { inta=9; int*aPtr=&a; printf("a=%d\n",a); printf("&a=%p\n",&a); printf("aPtr=%p\n",aPtr); printf("*aPtr=%d\n",*aPtr); return0; } /*《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:aPtr2.c 功能:印出指標變數的記憶體位址 作者:張凱慶*/ 編譯後執行,結果如下 $gccaPtr2.c $a.out a=9 &a=0x7ffee64bd848 aPtr=0x7ffee64bd848 *aPtr=9 $ 由於C語言的函數只能回傳一個值,所以當程式需要呼叫函數修改超過兩個值的時候,可以傳遞指標當作參數,讓呼叫的函數直接進行修改,如下例的函數swap()將a及b的值進行對調 #include voidswap(int*,int*bPtr); intmain(void) { inta=22; intb=11; printf("兩數交換以前..a=%d,b=%d\n",a,b); swap(&a,&b); printf("兩數交換以後..a=%d,b=%d\n",a,b); return0; } voidswap(int*aPtr,int*bPtr) { inttemp; temp=*aPtr; *aPtr=*bPtr; *bPtr=temp; } /*《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:swap.c 功能:示範利用指標修改兩個參數 作者:張凱慶*/ 編譯後執行,結果如下 $gccswap.c $a.out 兩數交換以前..a=22,b=11 兩數交換以後..a=11,b=22 $ 呼叫swap()的地方 swap(&a,&b); 將兩個變數取址後就是指標變數,然後傳遞給函數swap() voidswap(int*aPtr,int*bPtr) { inttemp; temp=*aPtr; *aPtr=*bPtr; *bPtr=temp; } 函數swap()接受兩個指標的參數後,另以一個區域變數temp暫存aPtr所指向的值,然後把bPtr的值給aPtr,注意此時兩個變數aPtr及bPtr的值一樣。

最後把暫存變數temp的值,也就是aPtr原先所儲存的值給bPtr,兩數的值便做了對調。

由於陣列(array)名稱就是指標,字串(string)也就是字元(character)陣列常常直接利用指標來操作,如下例 #include intmain(void) { char*aPtr="Seeingisbelieving."; while(*aPtr!='.'){ printf("%c\n",*aPtr); aPtr++; } return0; } /*《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:charPtr.c 功能:示範利用指標操作字元陣列 作者:張凱慶*/ 編譯後執行,結果如下 $gcccharPtr.c $a.out S e e i n g   i s   b e l i e v i n g $ 宣告、建立指標變數的地方 char*aPtr="Seeingisbelieving."; 指標變數aPtr會指向此字串第一個字元,也就是大寫S的記憶體位址。

下面的while迴圈(loop) while(*aPtr!='.'){ printf("%c\n",*aPtr); aPtr++; } 這裡利用迴圈逐行印出每個字元。

此外注意指標也是可以進行計算的,但有其限制,合法的指標運算如下表 相同資料型態的指標才可互相指派; 指標可相加或相減某一範圍的整數; 指向相同陣列的指標可以相減或比較; 指標可以指派0或是與0做比較。

關於在結構中使用指標,請參考C語言的結構,另有指向函數的指標,請參考函數指標。

上一頁單元6-衍生資料型態 回C速查手冊首頁 下一頁6.2陣列 回C教材首頁 回程式語言教材首頁



請為這篇文章評分?