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

C語言指標完全指南:運算、陣列、函式、字串與進階應用總結

     編輯:關於C語言

前言

指標是C語言的靈魂,也是區分初學者與資深工程師的分水嶺。本文系統總結指標運算規則、函式參數傳遞、陣列關係、多維陣列映射、函式指標、字串處理等核心知識點,並附帶記憶體模型圞解,助你建立完整指標知識體系。

一、指標運算核心規則

1. 運算子優先級與結合性

  • & (取址) 與 * (間接存取) 優先級相同,右結合
  • 單目運算子皆為右結合
  • 關鍵差異:
    • *p++ 等價 *(p++):先取值,指標後移
    • (*p)++:取值後,所指物件值加 1
    • *p++ 中 ++ 結合 p,非 *p

2. 指標減法:元素個數而非位元組差

若 p、q 指向同一陣列元素,p - q 為兩者之間的元素個數(類型大小已內隱除以 sizeof(type))。

3. 指標與整數加減:相對位移

  • p + n:向後移動 n 個元素(位址增加 n × sizeof(*p))
  • *(p + 1) 等價 p[1]

4. 指標比較:同一物件內才有意義

僅當指向同一陣列(或同一物件內部)時,比較才有定義行為;否則屬未定義行為 (UB)。

二、指標作函式參數:模擬傳址呼叫

void swap(int *p, int *q) {
    int tmp = *p; *p = *q; *q = tmp;
}
// 呼叫:swap(&a, &b);
// 函式內修改 *p、*q 影響實參;但 p、q 本身(區域副本)不影響實參指標值

三、指標與陣列:深度關聯

1. 一維陣列

  • 陣列名 a 在大多數表達式中退化為 &a[0](首元素位址)
  • a[i] 編譯器總是轉換為 *(a + i)
  • p = a 或 p = &a[0] 皆可

2. 多維陣列:陣列的陣列

int a[3][4] 視為 3 個長度 4 的一維陣列:a[0], a[1], a[2]

  • a[i][j] → *(a[i] + j) → *(*(a + i) + j)
  • a[i][j][k] → *(*(*(a + i) + j) + k)

位址推導:

  • *(a + i) + j 是 a[i][j] 的位址
  • *(*(a + i) + j) + k 是 a[i][j][k] 的位址

3. 行指標:指向整個行的指標

int a[3][4];
int (*p)[4] = a;  // p 指向含 4 個 int 的陣列
// p+1 指向下一行,跨度 sizeof(int[4]) = 16 位元組
// *(p+2)+3 等價 &a[2][3]
// *(*(p+2)+3) 等價 a[2][3]

關鍵:int (*p)[4] 括號不可省略,否則 int *p[4] 變成指標陣列。

4. 指標陣列 vs 指向指標的指標

  • int *p[4]:指標陣列,常用於字串陣列 char *argv[]
  • int **pp:指向指標的指標,多維動態陣列、命令列參數 char **argv

四、指標與函式

1. 函式指標

// 宣告:回傳 int,接受兩 int 參數的函式指標
int (*funcp)(int, int);

void swap(int x, int y) { ... }
void (*p)() = swap;  // 不需指定參數類型,但第一組括號不可少

應用:回調函式、策略模式、狀態機

int process(int x, int y, int (*func)(int, int)) {
    return func(x, y);
}

2. 回傳指標的函式

int* create_array(int n) {
    return malloc(n * sizeof(int));
}
// 呼叫端必須 free()

五、字串與指標

  • 字串常數 "hello" 存於唯讀區,型態 const char*
  • char *p = "hello":p 指向唯讀區,不可修改內容
  • char arr[] = "hello":堆疊陣列,可修改
  • 標準庫函式:strlen, strcpy, strcat, strcmp, strchr, strstr 皆以指標操作字串

記憶體模型圞解

棧區 (Stack)          堆區 (Heap)
+----------------+     +----------------+
| main() 區塊    |     | malloc 區塊    |
| 區域變數、指標 |     | 動態陣列、結構  |
+----------------+     +----------------+
資料區 (Data/BSS)      程式碼區 (Text)
+----------------+     +----------------+
| 全域/靜態變數  |     | 機器指令       |
| 字串常數       |     | 唯讀           |
+----------------+     +----------------+

常見陷阱與最佳實踐

陷阱正確做法
野指標初始化為 NULL,free 後置 NULL
釋放後使用free 即失效,不再解引用
指標越界嚴格檢查索引範圍
const 正確性字串常數用 const char*
函式指標宣告漏括號int (*p)(int) 而非 int *p(int)

總結

指標將「資料」與「位址」分離,賦予C語言直接操作記憶體的威力。掌握指標運算規則、陣列映射機制、函式指標模式,是寫出高效、靈活、系統級C程式的基石。

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