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

C語言指針進階:三道參數傳遞考題深度解析

     編輯:關於C語言

三道經典考題

考題一:值傳遞

void Exchg1(int x, int y) {
    int tmp = x; x = y; y = tmp;
    printf("x=%d, y=%d\n", x, y);
}
int main() {
    int a=4, b=6;
    Exchg1(a, b);
    printf("a=%d, b=%d\n", a, b);
}

輸出:

x=6, y=4
a=4, b=6

解析:調用時隱含 int x=a; int y=b;,函數內操作副本,原變量 a,b 不變。

考題二:地址傳遞(指針)

void Exchg2(int *px, int *py) {
    int tmp = *px; *px = *py; *py = tmp;
    printf("*px=%d, *py=%d\n", *px, *py);
}
int main() {
    int a=4, b=6;
    Exchg2(&a, &b);
    printf("a=%d, b=%d\n", a, b);
}

輸出:

*px=6, *py=4
a=6, b=4

解析:傳遞地址,函數通過解引用直接修改原內存,實現真正交換。

考題三:引用傳遞(C++ 特有)

void Exchg3(int &x, int &y) { // C++ 引用語法
    int tmp = x; x = y; y = tmp;
    printf("x=%d, y=%d\n", x, y);
}
int main() {
    int a=4, b=6;
    Exchg3(a, b);
    printf("a=%d, b=%d\n", a, b);
}

輸出:

x=6, y=4
a=6, b=4

解析:引用是變量別名,語法上如值傳遞,語義上等同指針傳址。C 語言無此語法,需用指針模擬。

核心知識點總結

傳遞方式C 語法函數內能否修改實參本質
值傳遞func(int x)否拷貝副本
地址傳遞func(int *p)是傳遞指針,解引用修改
引用傳遞func(int &x) (C++)是編譯器自動處理取址/解引用

C 語言模擬引用傳遞的標準模式

// 1. 函數參數用指針
void swap(int *a, int *b) {
    int t = *a; *a = *b; *b = t;
}

// 2. 調用時取地址
swap(&x, &y);

// 3. 輸出參數規範:const 輸入指針,非 const 輸出指針
void get_min_max(const int *arr, int n, int *min, int *max);

常見錯誤與避坑

  • 指針參數未檢查 NULL:導致段錯誤。防御性編程:if (!ptr) return ERROR;。
  • 返回局部變量地址:棧內存函數返回後失效。
  • 多級指針混淆:需修改指針本身時傳 **p,修改指向內容傳 *p。
  • const 正確性:只讀參數加 const,防止誤修改並允許傳入常量。

內存視角理解

/* 值傳遞內存圖 */
main棧幀: a=4, b=6
Exchg1棧幀: x=4, y=6  ← 拷貝獨立副本
交換後: x=6, y=4  (main 的 a,b 不受影響)

/* 地址傳遞內存圖 */
main棧幀: a=4, b=6
Exchg2棧幀: px=&a, py=&b  ← 存儲地址
*px=6, *py=4  ← 直接修改 main 棧幀內存
main 的 a,b 變為 6,4

進階:嵌入式/系統編程中的寄存器傳參

ARM/x86-64 調用慣例前幾個參數通過寄存器傳遞(如 R0-R3 / RDI, RSI, RDX, RCX),屬於「值傳遞」的一種實現,但對指針參數同樣適用——寄存器存放地址值。理解調用慣例有優化性能關鍵路徑。

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