指標是 C 語言的靈魂,也是初學者最大的挑戰。簡單說:指標變數專門儲存另一個變數的記憶體位址。透過位址,我們可以間接存取、修改原變數的值,實現高效的資料操作與動態記憶體管理。
型別指標名 *指標變數名; // 例:int *p; float *q;
關鍵點:* 屬於型別宣告一部分,表示「指向 型別 的指標」;變數名是 p 而非 *p。
&:p = &var; 取得 var 位址。*:*p = 20; 透過位址修改原變數值;val = *p; 讀取值。p2 = p1; 兩指標指向同一位址。NULL (或 0) 表示「不指向任何物件」,常用於錯誤檢查。int num = 12, *pt = #
float pi = 3.14f, *pf = π
char ch = 'm', *pc = &ch;
printf("num=%d, *pt=%d\n", num, *pt); // 12, 12
printf("pi=%.2f, *pf=%.2f\n", pi, *pf); // 3.14, 3.14
printf("ch=%c, *pc=%c\n", ch, *pc); // m, m
這是面試高頻考點,釐清「交換指標值」與「交換指向內容」的差異。
int a=5, b=10, *p1=&a, *p2=&b, *tmp;
if (a < b) { tmp = p1; p1 = p2; p2 = tmp; } // p1 指向 b, p2 指向 a
printf("max = %d\n", *p1); // 10,但 a、b 本身值未變
int a=5, b=10, *p1=&a, *p2=&b, tmp;
if (a < b) { tmp = *p1; *p1 = *p2; *p2 = tmp; } // 解參考後交換
printf("a=%d, b=%d\n", a, b); // a=10, b=5
& 與 * 互逆關係*&var == var,&*ptr == ptr(前提 ptr 已合法初始化)。
p++ 使指標移動 sizeof(*p) 位元組。對 int* 通常 +4 位元組;char* +1 位元組。
| 運算式 | 含義 | 副作用 |
|---|---|---|
*p++ | 取值後指標後移 | p 指向下一個元素 |
(*p)++ | 取值並遞增該值 | 原變數值 +1,p 不動 |
*p+1 | 取值加 1 | 無副作用 |
== != < > <= >=,高位址大於低位址。NULL 比較判斷有效性。單一 return 只能回傳一個值;傳入變數位址,函數內解參考修改,即可影響多個實參。
void calc(int x, int y, int *sum, int *diff) {
*sum = x + y;
*diff = x - y;
}
int main(void) {
int a, b, s, d;
scanf("%d%d", &a, &b);
calc(a, b, &s, &d);
printf("%d + %d = %d\n%d - %d = %d\n", a, b, s, a, b, d);
return 0;
}
void swap(int x, int y) — 失敗,僅交換區域副本。void swap(int *p1, int *p2) 內做 p1=p2 — 失敗,僅改變區域指標指向。void swap(int *p1, int *p2) 內做 *p1=*p2 — 成功。int arr[10], *p = arr; // p 指向 arr[0]
int *q = &arr[3]; // q 指向 arr[3]
arr、&arr[0]、arr+0 等價。
/* 方法一:指標算術 */
for (int i = 0; i < 10; i++) scanf("%d", p+i);
for (int i = 0; i < 10; i++) printf("%d ", *(p+i));
/* 方法二:移動指標本身(更接近硬體,效能略優) */
for (p = arr; p < arr+10; p++) scanf("%d", p);
for (p = arr; p < arr+10; p++) printf("%d ", *p);
注意:指標移動勿越界,arr+10 為「結尾後一個」合法位址,不可解參考。
int a[10], count = 0;
for (int i = 0; i < 10; i++) scanf("%d", a+i);
for (int *p = a; p < a+10; p++)
if (*p > 0) { count++; printf("%d ", *p); }
printf("\n正數個數: %d\n", count);
指標是 C 語言區別於其他高階語言的核心特性,掌握它等於掌握了記憶體控制權。建議大量動手實驗,觀察位址與值的變化,建立直觀心智模型。