在學習 C 語言時,無法迴避的就是對「指標變數」的理解。對於初學者而言,「位址」與「間接參照」等概念可能會感到難以理解,但指標是 C 語言的根本重要元素,掌握它後即可進行更高階的程式設計。 本篇文章將從「什麼是指標變數?」的基礎開始,逐步且細緻地說明實作範例、以及與陣列、函式的關係、應用方式等。為了讓讀者更易掌握專業術語的意義與運作概念,會搭配圖解與範例程式碼,即使對 C 語言尚未熟悉的讀者也能安心閱讀。 指標一旦熟悉,就會成為非常強大且便利的功能。它能進行動態記憶體操作、函式參數的傳遞等,極大擴展程式的可能性。希望透過本篇文章,能加深對指標變數的理解,讓您在 C 語言開發技能上提升一個層次。
2. 指標變數是什麼?
指標變數的基本概念
在 C 語言中,指標變數是「儲存記憶體位址的變數」的意思。一般變數儲存資料本身,而指標則記憶另一個變數所儲存的位址(地址)。 例如,考慮以下程式碼。
int a = 10;
int *p = &a;
在此情況下,變數a儲存值 10,p儲存 a 的位址。寫成 *p 時,可間接取得 p 所指向位址中的值(此例為 10)。
int arr[3];
int *p = arr;
p = p + 1; // OK
arr = arr + 1; // 錯誤(陣列名稱不可重新賦值)
熟練指標與陣列的好處
使用指標即可、彈性操作記憶體空間。
陣列處理會變得更快速且高效(有時指標運算比索引稍快)。
在將陣列傳遞給函式時,只會傳遞首位址而非實體,因此指標相關知識是必須的。
5. 函式與指標
在 C 語言中,將變數傳遞給函式時,值傳遞(call by value)是基本方式。因此,即使在函式內更改參數,原始變數也不會受到影響。然而,透過使用指標,函式可以直接操作原始變數的值。 本章將說明函式與指標的關係、值的改寫方法、函式指標的基礎等,解釋在函式中使用指標的方式。
使用指標改寫值
首先,若要在函式內更改變數的值,需要使用指標。
範例:未使用指標的情況
void update(int x) {
x = 100;
}
int main() {
int a = 10;
update(a);
printf("%d
", a); // 結果: 10(未變更)
return 0;
}
在此情況下,函式收到的是 a 的副本,因此 a 本身不會被更改。
範例:使用指標的情況
void update(int *x) {
*x = 100;
}
int main() {
int a = 10;
update(&a);
printf("%d
", a); // 結果: 100(已變更)
return 0;
}
如此一來,將變數的位址傳遞給函式,即可更改原始值。這是作為「參照傳遞(call by reference)」技巧被廣泛使用。
陣列與函式的關係
在 C 語言中,將陣列傳遞給函式時會自動被視為指標。也就是說,列首元素的位址會傳遞給函式,因而在函式內可以修改其內容。
void setValues(int *arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] = i * 10;
}
}
int main() {
int nums[3];
setValues(nums, 3);
printf("%d
", nums[1]); // 結果: 10
return 0;
}
如同此例,只要直接傳遞陣列名稱,即可在函式內修改其內容。
函式指標的基礎
在 C 語言中,也可以將函式的位址存入變數並呼叫。這就是函式指標。
宣告與使用範例:
int add(int a, int b) {
return a + b;
}
int main() {
int (*funcPtr)(int, int); // 回傳 int 型,接受兩個 int 型參數的函式指標
funcPtr = add;
int result = funcPtr(3, 4);
printf("%d
", result); // 結果: 7
return 0;
}