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

C/C++ 指標學習兩大經典範例:交換排序與函數傳遞深度剖析

     編輯:關於C++

範例一:指標交換實現兩數排序(不動原變數值)

int a, b;
int *p1 = &a, *p2 = &b, *temp;

if (a < b) {  // 以 a,b 大小決定交換指標
    temp = p1;  // 暫存 p1 指向的地址
    p1 = p2;    // p1 指向 b
    p2 = temp;  // p2 指向 a
}
printf("%d,%d", *p1, *p2);  // 輸出較大值在前

核心洞察

  • **未修改 a、b 本身**,僅交換指標變數 p1、p2 所持有的地址。
  • *p1 等價於當前 p1 指向的變數值,透過指標間接訪問實現「邏輯交換」。
  • 這種技巧常用於**不想移動大型結構體**時,僅調整指標陣列順序(如 qsort 排序指標陣列)。

範例二:函數參數傳遞指標實現真實交換(修改原變數)

void swap(int *p1, int *p2) {
    int temp = *p1;  // 取得 p1 指向的值
    *p1 = *p2;       // 將 p2 指向的值寫入 p1 指向的位置
    *p2 = temp;      // 將暫存值寫入 p2 指向的位置
}

int main() {
    int a, b;
    scanf("%d,%d", &a, &b);
    swap(&a, &b);  // 傳遞地址
    printf("%d,%d", a, b);  // a、b 真實交換
}

關鍵差異對比

維度範例一範例二
目的邏輯上輸出有序,原變數不動真實修改原變數值
操作對象指標變數 (地址)指標指向的記憶體內容
函數簽名無函數,主函數內直接操作void swap(int*, int*)
適用場景大型物件排序、多關鍵字索引通用交換、輸出參數

指標核心概念圖解

int a = 10, b = 20;
int *p1 = &a, *p2 = &b;

記憶體:
a (0x1000): 10
b (0x1004): 20
p1 (0x2000): 0x1000 → a
p2 (0x2004): 0x1004 → b

範例一交換後:
p1 (0x2000): 0x1004 → b
p2 (0x2004): 0x1000 → a
*a, *b 值不變

範例二 swap(&a, &b) 後:
a (0x1000): 20
b (0x1004): 10
p1, p2 未變(主函數內未使用指標變數)

學習指標的三個關鍵認知

  1. *x vs x:x 是地址(指標值),*x 是該地址存儲的值(被指物件)。
  2. &a 取址:獲得變數在記憶體中的位置,賦予指標「導航能力」。
  3. 指標變數本身也是變數:有地址、有大小、可被賦值、可作為函數參數傳遞(傳遞的是地址副本)。

進階練習:雙重指標修改指標指向

void reassign(int **pp, int *new_target) {
    *pp = new_target;  // 解引用一次,修改原指標指向
}

int main() {
    int x = 100, y = 200;
    int *p = &x;
    reassign(&p, &y);  // 傳遞指標的地址
    // 此時 p 指向 y
}

這是 C 語言模擬「引用」或「輸出指標參數」的標準模式,C++ 直接用 int* & 更直觀。

總結

  • **範例一**展示指標作為「間接訪問手柄」,交換手柄順序而非物件本身。
  • **範例二**展示指標作為「遠程修改通道」,透過地址修改原始物件。
  • 掌握 *p (值) 與 p (地址) 的二元對應,多畫記憶體圖、多寫 printf("%p", p) 觀察地址變化。
  • 指標沒有魔法,只有「地址」與「解引用」兩個原子操作,所有複雜用法皆由此組合而成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved