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

C語言指標與函數參數傳遞:從交換函數理解指標本質

     編輯:關於C

指標與位址核心規則

規則說明
& 運算元限制僅能用於記憶體中物件 (變數、陣列元素),不可用於表達式、常數、register 變數
* 間接引用作用於指標,存取指向的物件
指標型別嚴格性指標只能指向特定型別,void* 可存放任意指標但不可直接解引用

C 語言參數傳遞機制:傳值呼叫

C 永遠傳值:函數收到的是引數副本,無法直接修改呼叫端變數。


// 錯誤嘗試:無法修改 main 的 x, y
void swap_wrong(int x, int y) {
    int t = x; x = y; y = t;  // 只修改區域副本
}

指標實現「模擬傳址」

傳遞變數位址,函數透過解引用修改原變數:


#include 

void swap(int *x, int *y);

int main() {
    int m = 1, n = 2;
    swap(&m, &n);  // 傳遞位址
    printf("m=%d n=%d\n", m, n);  // 輸出: m=2 n=1
    return 0;
}

void swap(int *x, int *y) {
    int temp = *x;  // 解引用取值
    *x = *y;        // 解引用賦值
    *y = temp;
}

記憶體模型圖解

main 堆疊幀:          swap 堆疊幀:
+----------+          +----------+
| m: 1     | ←──┐     | x: &m    | ──┐
+----------+    │     +----------+   │
| n: 2     | ←──┘     | y: &n    | ──┘
+----------+          | temp: 1  |
                      +----------+

*x  即 *(&m)  即 m
*y  即 *(&n)  即 n

等價轉換理解


// swap 內部操作等價於:
int *x = &m;
int *y = &n;

temp = *(&m);      // temp = m
*(&m) = *(&n);     // m = n
*(&n) = temp;      // n = temp

關鍵差異:C vs Java 參數傳遞

特性C 語言Java
基本型別傳值 (副本)傳值 (副本)
物件/陣列無物件概念,陣列退化為指標傳參考副本 (可修改物件內容)
修改呼叫端變數必須傳位址 (&var)基本型別不可,物件可修改內部狀態
交換函數實作傳指標 swap(int*, int*)基本型別不可實作,需包裝類或陣列

進階:指標參數的 const 正確性


// 僅讀取,不修改 → 加 const
void print_int(const int *p) {
    printf("%d", *p);  // 安全
    // *p = 10;       // 編譯錯誤
}

// 修改指向的資料 → 不加 const
void set_int(int *p, int val) {
    *p = val;  // 正確
}

// 修改指標本身 (罕見) → 指標的指標
void reallocate(int **p, size_t n) {
    *p = realloc(*p, n * sizeof(int));
}

常見錯誤避坑

  1. 傳遞未初始化指標:int *p; func(p); → 垃圾位址崩潰
  2. 解引用 NULL/野指標:int *p = NULL; *p = 1;
  3. 指標型別不匹配:float f; int *p = &f; → 違反嚴格別名規則
  4. 傳遞陣列以為傳整個陣列:void f(int a[]) { sizeof(a); } → a 退化為指標,sizeof 回傳指標大小

最佳實務檢查清單

  • [ ] 函數參數是否需要修改呼叫端變數? → 需傳位址
  • [ ] 是否只讀取? → 加 const
  • [ ] 指標是否可能為 NULL? → 進入函數首行檢查
  • [ ] 是否涉及陣列? → 傳指標 + 長度參數
  • [ ] 所有權轉移? → 文檔標註誰負責 free
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved