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

C 語言指針基礎完全掌握:地址、解引用、類型、const 修飾、陷阱與最佳實踐

     編輯:關於C語言

核心概念三部曲

  1. 地址 (`&`)**:變數在記憶體中的編號。`int *p = #`
  2. 指針變數**:儲存地址的變數。`int *p;` (類型 `int*`)
  3. 解引用 (`*`)**:透過地址訪問/修改值。`*p = 20;` 等同 `num = 20;`

指針聲明風格建議


// 推薦:靠近變數名,強調「p 是指針」
int *p, *q;  // p, q 都是 int*

// 避免:靠近類型,易誤導
int* p, q;   // p 是 int*, q 是 int (陷阱!)
// 最佳:逐行聲明或用 typedef
typedef int *IntPtr;
IntPtr p, q; // 明確雙方都是指針

指針初始化:拒絕野指針


int *p;        // 危險:野指針 (隨機地址)
int *p = NULL; // 安全:空指針 (明確無效)
int *p = # // 正確:指向有效對象
// 使用前檢查
if (p) { *p = 10; } // 防空指針解引用崩潰

指針與 `const` 四種組合 (核心考點)

聲明口訣指針可變?值可變?典型用途
const int *p
int const *p
指向常量的指針
(Pointer to const)
是**否** (通過 p)函數參數 `const char *str` 保護只讀
int *const p常量指針
(Const pointer)
**否** (初始化後不可改)是固定緩衝區指針、硬體暫存器基址
const int *const p指向常量的常量指針否否只讀查找表、字串常量指針
int *p普通指針是是一般修改數據

閱讀技巧:從右向左讀 `const` 最近修飾誰。`int *const p` → `p` 是 `const` (指針常);`const int *p` → `int` 是 `const` (值常)。

指針類型與算術運算


int arr[5] = {10,20,30,40,50};
int *p = arr; // 陣列名退化為首元素地址

printf("%d\n", *p);       // 10
printf("%d\n", *(p+1));   // 20 (p+1 移動 sizeof(int) 位元組)
p++;                      // 指向下一個 int
printf("%d\n", p[2]);     // 40 (p[2] == *(p+2))

// 類型決定步長
char *cp = (char*)p; // 強轉 char*,步長變 1 位元組
// 危險:違反嚴格別名規則,僅用於字節流操作 (memcpy 等)

多級指針


int val = 100;
int *p1 = &val;      // 一級
int **p2 = &p1;      // 二級:指向指針的指針
int ***p3 = &p2;     // 三級

**p2 = 200; // 修改 val
// 應用:函數修改指針本身 (輸出參數)
void allocate(int **out_ptr, size_t n) {
    *out_ptr = malloc(n * sizeof(int));
}
int *buf; allocate(&buf, 10);

常見陷阱總結

  1. 懸空指針:`free` 後未置 `NULL`、返回局部變數地址、`realloc` 移動後舊指針。
  2. 空指針解引用:`malloc` 失敗未檢查、未初始化指針、邏輯漏洞導致 `NULL` 傳入。
  3. 緩衝區溢出:指針越界寫入、字串未留 `\0` 空間、`strcpy` 不檢查長度。
  4. 類型雙關違規:`float f; int *p = (int*)&f;` 違反嚴格別名規則 → UB。用 `union` 或 `memcpy`。
  5. 指針減法/比較:僅同一陣列/物件內指針相減有意義 (得元素距離 `ptrdiff_t`)。不同塊比較 UB。

現代 C 最佳實踐

  • **盡量用陣列索引/迭代器** 替代裸指針運算。
  • **所有權語義**:`unique_ptr` (C++), `g_autoptr` (GLib), 或約定 `malloc`/`free` 配對責任歸屬 (API 文檔標註 `caller owns` / `callee owns`)。
  • **`const` 正確性**:參數預設 `const T*`,需要修改才去掉 `const`。
  • **靜態分析**:Clang Static Analyzer, Coverity, Cppcheck 捕獲指針錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved