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

C/C++ 指標學習兩大經典範例:交換變數與函式修改實參

     編輯:VC 教學

指標學習的核心障礙

概念不清:*p(指標指向的**值**)vs p(指標本身的**地址值**)。只要搞懂這對關係,指標就不再是難點。

範例一:利用指標交換兩變數值(不修改原變數,僅交換指標指向)


int a, b;
scanf("%d,%d", &a, &b);

int *p1 = &a, *p2 = &b, *tmp;
if (a < b) {
    tmp = p1;   // 暫存 p1 指向的地址(&a)
    p1 = p2;    // p1 指向 b
    p2 = tmp;   // p2 指向 a
}
printf("%d,%d", *p1, *p2);  // 輸出較大、較小值

記憶體圖解

初始:          交換後:
p1 ───► a=3     p1 ───► b=5
p2 ───► b=5     p2 ───► a=3
*p1=3, *p2=5    *p1=5, *p2=3

關鍵:原變數 a,b **值未變**,僅透過指標間接輸出達到「排序」效果。理解 tmp 保存的是**地址**,非值。

範例二:函式透過指標真實修改實參值


void compositor(int *p1, int *p2) {
    int temp;
    if (*p1 < *p2) {      // 比較指向的值
        temp = *p1;       // 暫存值
        *p1 = *p2;        // 修改 p1 指向的記憶體(實際修改 a)
        *p2 = temp;       // 修改 p2 指向的記憶體(實際修改 b)
    }
}

int main() {
    int a, b;
    scanf("%d,%d", &a, &b);
    compositor(&a, &b);   // 傳遞地址
    printf("%d,%d", a, b); // a,b 真實被修改
}

對比差異

特性範例一範例二
修改實參值?否(僅交換指標指向)是(透過解引用寫入記憶體)
暫存變數類型int*(地址)int(值)
適用場景不想動原資料、需保留原順序需真實交換/修改呼叫端變數

指標學習三步驟法

  1. 畫圖:每行代碼在紙上畫記憶體框圖(變數、指標、箭頭)。
  2. 輸出觀察:printf("%p %p %d\n", p, &a, *p); 同時印地址與值。
  3. 寫註釋:每行標註「此處操作的是指標值/指向的值」。

常見錯誤模式

錯誤代碼問題修正
int *p; *p = 10;野指標解引用 → 崩潰int a; int *p = &a; *p = 10;
void f(int p) { *p = 1; } int a; f(a);傳值非傳址,形參非指標void f(int* p) { *p = 1; } f(&a);
int *p = 0x1234; *p = 5;任意地址寫入 → 未定義行為僅用於記憶體映射 I/O、嵌入式特定場景
int a[10]; int *p = a; p++; 以為 a 變了a 為常量指標不可修改,p 是副本理解陣列名退化為右值指標

現代 C++ 指標觀

  • 裸指標僅作觀察者/非擁有參考:T* 或 T* const 表示「看著這個物件,不負責刪除」。
  • 擁有權用智慧指標:std::unique_ptr (獨佔)、std::shared_ptr (共享)。
  • 避免手動 new/delete:改用 make_unique/make_shared、標準容器。
  • 指標運算僅用於連續記憶體遍歷:且優先用迭代器/範圍 for。

總結

這兩個範例精準切中指標學習的核心:**地址與值的雙重身分、傳址呼叫修改實參、暫存變數類型選擇**。配合畫圖、輸出觀察、註釋三步驟,反覆練習至能心中自動運行記憶體模型。現代 C++ 將指標「降級」為非擁有觀察者,擁有權交給 RAII 類型,讓指標回歸本質——**單純的地址運算工具**。

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