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

C語言指針完全指南:從概念到進階應用(轉載整理版)

     編輯:關於C語言

第一章 指針四大核心屬性

搞懂一個指針,必須明確四個方面:

  1. 指針的類型:聲明語句去掉變量名,剩下的部分。如 int *ptr → 類型 int*。
  2. 指針指向的類型:聲明語句去掉變量名和最左邊的 *。如 int *ptr → 指向 int;int **ptr → 指向 int*。
  3. 指針的值(地址):指針存儲的數值,被編譯器視為內存地址。32 位程序中為 32 位整數。
  4. 指針自身佔用的內存:32 位平台佔 4 字節,64 位佔 8 字節。sizeof(ptr) 即可得知。

第二章 指針算術運算

  • ptr + n:地址增加 n * sizeof(指向類型) 字節。
  • ptr - n:地址減少相應字節。
  • ptr2 - ptr1(同類型指向同一數組):返回元素個數差值。
  • 本質:指針運算以「指向類型大小」為單位,而非字節。

第三章 運算符 & 與 *

  • &a:取地址,結果類型為 a的類型*,指向類型為 a的類型,值為 a的地址。
  • *p:間接訪問,結果類型為 p指向的類型,佔用地址為 p指向的地址。

第四章 指針表達式與左值

  • 結果為指針的表達式稱為指針表達式(如 &a、ptr+1、*ptr)。
  • 指針表達式若已佔據確定內存(如 *ptr 實際是某指針變量),則為左值,可放在賦值號左邊;否則為右值(如 &a)。

第五章 數組與指針的深層關係

  • 數組名 array 有雙重含義:① 代表整個數組(類型 T[N]),用於 sizeof(array)、&array;② 退化為指向首元素的指針(類型 T*),用於 *array、array+i。
  • int (*ptr)[10] 是指向整個數組的指針,類型為 int(*)[10],sizeof(*ptr)==40,sizeof(ptr)==4。

第六章 指針與結構體

  • 正規訪問:ptr->member(ptr 類型為結構體指針)。
  • 非正規訪問:將結構體強轉為 int* 逐字節/字訪問——不可靠,因編譯器可能插入填充字節對齊。

第七章 指針與函數

  • 函數指針:int (*pfun)(char*, int); pfun = fun1; 調用:(*pfun)("arg", 7);
  • 指針作參數:實參傳遞地址值,形參為副本,但指向同一內存。函數內修改 *p 影響實參指向對象;修改 p 本身不影響實參指針。

第八章 指針類型轉換

  • 強制轉換:(TYPE*)ptr 生成新指針,類型改為 TYPE*,地址不變。原指針屬性不變。
  • 函數參數隱式轉換:實參 &a(int*)傳給形參 char*,編譯器內部構造臨時指針完成轉換。
  • 整數與指針互轉:ptr = (TYPE*)addr_int、addr_int = (uintptr_t)ptr(需 stdint.h)。

第九章 指針安全紅線

  1. 越界訪問:指針指向對象邊界外(如 char 強轉 int* 寫入 4 字節)。
  2. 懸空指針:指向已釋放/超出生命週期的內存。
  3. 類型懲罰轉換:sizeof(源類型) < sizeof(目標類型) 時,通過目標指針訪問源內存會越界。
  4. 未初始化指針:野指針,指向隨機地址。

十大避坑口訣

  1. 聲明即初始化(NULL 或合法地址)。
  2. 釋放後立即置 NULL。
  3. 嚴格匹配指向類型,慎用 void* 強轉。
  4. 數組下標檢查,防越界。
  5. 函數參數用 const 修飾只讀指針。
  6. 多級指針逐級分配/釋放內存。
  7. 結構體用 offsetof/成員名訪問,勿手算偏移。
  8. 跨模塊接口文檔化指針所有權與生命週期。
  9. 啟用編譯器警告(-Wall -Wextra -Wpedantic)並視作錯誤處理。
  10. 使用靜態分析工具(Cppcheck、Clang Static Analyzer、Coverity)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved