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

C語言指針進階:從核心原理到實戰應用

     編輯:關於C語言

C語言指針進階:從核心原理到實戰應用

指針是C語言的精華,也是危險之源。本文通過「小黑板」式筆記,深入講解指針含義、函數應用、數組關係、const 限定、指針運算、動態內存及二維數組指針,並給出經典陷阱與最佳實踐。

一、指針的含義與內存視圖

指針本質是存儲地址的變量。內存視圖示例:

地址   存儲量   存儲值
F1     a(int)     10
F2     b(int*)    F1 (a的地址)

鐵律:指針變量必須初始化。未初始化指針指向隨機地址,解引用可能破壞系統數據,導致崩潰或難以排查的Bug。

二、指針的兩大核心應用場景

  1. 函數返回多個值:通過指針參數傳遞輸出參數。
    void swap(int *a, int *b) {
        int t = *a; *a = *b; *b = t;
    }
    
  2. 函數返回狀態碼,結果通過指針返回:
    int div(int a, int b, int *result) {
        if (b == 0) return 0; // 失敗
        *result = a / b;
        return 1; // 成功
    }
    

三、數組與指針的深層關係

  • 數組名 arr 是首元素地址常量(相當於 &arr[0]),不可修改。
  • 函數參數中 int arr[]、int *arr、int arr[10] 完全等價,均退化為指針。
  • 指針算術:p+1 指向下一個元素,*(p+1) 等價於 arr[1]。

四、const 與指針的組合(高頻面試題)

聲明含義可修改指針?可修改指向值?
int *const p = &i;常量指針(指針本身不可變)否是 (*p = 20)
const int *p = &i;指向常量的指針(不可通過指針修改值)是否
int const *p = &i;同上(const 在 * 左側)是否
const int *const p = &i;雙重常量否否

口訣:const 在 * 右邊 → 指針不可改;在左邊 → 指向值不可改。

實戰用法:函數參數加 const 保護數組不被修改:void print(const int *arr, int n)。

五、指針運算詳解

  1. 增減:p++ 移動 sizeof(*p) 字節。
  2. 相減:同類型指針相減得元素個數差。
  3. *p++ 解析:等價 *(p++),先取值再移動指針。
  4. 比較:支持 > < < == !=。

六、void * 通用指針與動態內存

  • void * 可指向任意類型數據,但不能直接解引用,需轉型後使用。
  • 動態內存分配:
    int *arr = (int*)malloc(n * sizeof(int));
    if (!arr) exit(1); // 必須檢查
    // 使用...
    free(arr); // 必須釋放,防止內存洩漏
    arr = NULL; // 防止野指針
    

七、二維數組與指針的指針

char a[3][4] 在內存中連續存儲。a 是數組指針(指向含4個char的數組),類型為 char (*)[4]。

char **p = (char**)a; // 錯誤!類型不匹配
char (*p)[4] = a;     // 正確:p 指向第一行
p+1 指向第二行
*(*p+1) 即 a[0][1]

動態分配二維數組常用「指針數組」或「單塊內存+指針運算」。

八、經典陷阱總結

  1. int *p, q; 只有 p 是指針,q 是 int。寫成 int *p, *q;。
  2. 函數參數傳指針時,函數內修改指針本身(如 p = malloc(...))不影響外部,需傳二級指針或返回指針。
  3. 釋放內存後未置 NULL,導致野指針。
  4. 棧上數組地址返回給調用者(函數結束棧幀銷毀,地址失效)。

指針雖難,但掌握「地址+類型」雙維認知,配合嚴格的初始化、邊界檢查、釋放置空習慣,即可馴服這把雙刃劍,寫出高效健壯的C代碼。

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