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

C語言函數參數傳遞:值傳遞 vs 指針傳遞(交換兩數詳解)

     編輯:關於C語言

C語言函數參數傳遞:值傳遞 vs 指針傳遞(交換兩數詳解)

「C語言只有值傳遞」是核心鐵律。要在函數中修改實參,必須傳遞地址(指針)。本文通過「交換兩個整數」這一經典案例,徹底講透兩種傳遞方式的本質區別。

一、代碼對比


#include <stdio.h>

// 值傳遞:無法修改實參
void swap_val(int x, int y) {
    int t = x; x = y; y = t;
    printf("In swap_val: x=%d, y=%d\n", x, y);
}

// 指針傳遞:可修改實參
void swap_ptr(int *x, int *y) {
    int t = *x; *x = *y; *y = t;
    printf("In swap_ptr: x=%d, y=%d\n", *x, *y);
}

int main() {
    int a = 5, b = 10;
    
    printf("Before swap_val: a=%d, b=%d\n", a, b);
    swap_val(a, b);
    printf("After swap_val: a=%d, b=%d\n\n", a, b);  // 無變化
    
    printf("Before swap_ptr: a=%d, b=%d\n", a, b);
    swap_ptr(&a, &b);
    printf("After swap_ptr: a=%d, b=%d\n", a, b);    // 交換成功
    return 0;
}

二、輸出結果


Before swap_val: a=5, b=10
In swap_val: x=10, y=5
After swap_val: a=5, b=10   ← 實參未變!

Before swap_ptr: a=5, b=10
In swap_ptr: x=10, y=5
After swap_ptr: a=10, b=5   ← 實參已交換!

三、內存模型圖解

值傳遞

main棧幀:          swap_val棧幀:
a(地址0x100) = 5   x(地址0x200) = 5  ← 複製值
b(地址0x104) = 10  y(地址0x204) = 10 ← 複製值
                   
函數內交換 x,y 只影響 0x200/0x204
返回後 swap_val棧幀銷毀,main中 a,b 不變

指針傳遞

main棧幀:              swap_ptr棧幀:
a(0x100)=5             x(0x200)=0x100  ← 複製地址值
b(0x104)=10            y(0x204)=0x104  ← 複製地址值

*x 解引用訪問 0x100 → 修改 a
*y 解引用訪問 0x104 → 修改 b
實現真正交換

四、核心概念總結

特性值傳遞指針傳遞
傳遞內容變量的值副本變量的地址副本
函數內修改只影響副本通過解引用修改原變量
實參要求變量/表達式/常量必須是可取地址的左值
調用語法func(a, b)func(&a, &b)
函數參數int xint *x
函數體訪問x*x

五、常見錯誤與修正

錯誤 1:指針函數內修改指針本身


// 錯誤:修改的是形參指針副本,不影響實參指針
void wrong_swap(int *x, int *y) {
    int *t = x; x = y; y = t;  // 只交換了局部指針變量
}

// 正確:修改指針指向的內容
void correct_swap(int *x, int *y) {
    int t = *x; *x = *y; *y = t;
}

錯誤 2:傳遞指針的指針(雙重指針)時機混淆

  • 需修改指針變量本身(如 malloc 分配內存返回指針)→ 傳 int **
  • 需修改指針指向的數據 → 傳 int *

六、宏實現交換(編譯期展開,類內聯)


#define SWAP(type, x, y) do { \
    type tmp = *(y); \
    *(y) = *(x); \
    *(x) = tmp; \
} while(0)

// 使用
int a=5, b=10;
SWAP(int, &a, &b);  // 類型安全,無函數調用開銷

七、總結

  1. C語言只有值傳遞,指針傳遞本質是「傳遞地址的值」
  2. 2. 要在函數修改實參 → 傳遞實參地址 → 函數參數為指針 → 函數體解引用修改 3. *ptr 表示「ptr 指向的內存位置」,是修改原數據的鑰匙 4. 宏 SWAP 利用 do{...}while(0) 實現語句級封裝,類型安全且零開銷 5. 面試必考:畫棧幀圖、解釋為什麼值傳遞失效、指針傳遞生效

理解參數傳遞機制,是從「會寫代碼」進階到「理解程序運行本質」的關鍵一步。

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