首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言核心筆記(十):指標完全指南——從入門到進階應用

     編輯:關於C語言

一、 指標基礎:記憶體位址的操控者

指標是 C 語言的靈魂,也是初學者最大的挑戰。簡單說:指標變數專門儲存另一個變數的記憶體位址。透過位址,我們可以間接存取、修改原變數的值,實現高效的資料操作與動態記憶體管理。

1.1 指標變數定義語法

型別指標名 *指標變數名;  // 例:int *p;  float *q;

關鍵點:* 屬於型別宣告一部分,表示「指向 型別 的指標」;變數名是 p 而非 *p。

1.2 指標賦值與間接存取

  • 取址運算子 &:p = &var; 取得 var 位址。
  • 間接運算子 *:*p = 20; 透過位址修改原變數值;val = *p; 讀取值。
  • 指標複製:p2 = p1; 兩指標指向同一位址。
  • 空指標:NULL (或 0) 表示「不指向任何物件」,常用於錯誤檢查。

1.3 範例:基本型別指標操作

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

二、 指標進階:指標交換 vs 內容交換

這是面試高頻考點,釐清「交換指標值」與「交換指向內容」的差異。

2.1 指標交換(僅改變指向)

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 本身值未變

2.2 內容交換(真正交換資料)

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

三、 指標運算:位址的數學運算

3.1 & 與 * 互逆關係

*&var == var,&*ptr == ptr(前提 ptr 已合法初始化)。

3.2 指標遞增/遞減:步長由基礎型別決定

p++ 使指標移動 sizeof(*p) 位元組。對 int* 通常 +4 位元組;char* +1 位元組。

運算式含義副作用
*p++取值後指標後移p 指向下一個元素
(*p)++取值並遞增該值原變數值 +1,p 不動
*p+1取值加 1無副作用

3.3 指標比較與減法

  • 同型別指標可比較 == != < > <= >=,高位址大於低位址。
  • 同型別指標相減結果為元素個數差(位址差 / 型別大小)。
  • 指標可與 NULL 比較判斷有效性。

四、 指標作為函數參數:實現多返回值與修改實參

單一 return 只能回傳一個值;傳入變數位址,函數內解參考修改,即可影響多個實參。

4.1 範例:同時計算和與差

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;
}

4.2 三種交換函數寫法對比

  1. 值傳遞:void swap(int x, int y) — 失敗,僅交換區域副本。
  2. 指標傳遞但交換指標:void swap(int *p1, int *p2) 內做 p1=p2 — 失敗,僅改變區域指標指向。
  3. 指標傳遞並交換內容:void swap(int *p1, int *p2) 內做 *p1=*p2 — 成功。

五、 指標與一維陣列:天生一對

5.1 陣列名即首元素位址

int arr[10], *p = arr;        // p 指向 arr[0]
int *q = &arr[3];             // q 指向 arr[3]

arr、&arr[0]、arr+0 等價。

5.2 指標法存取陣列:高效且靈活

/* 方法一:指標算術 */
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 為「結尾後一個」合法位址,不可解參考。

5.3 實戰:統計正數個數

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 語言區別於其他高階語言的核心特性,掌握它等於掌握了記憶體控制權。建議大量動手實驗,觀察位址與值的變化,建立直觀心智模型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved