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

C 語言指針完全掌握:四大核心屬性、算術運算、運算符與表達式詳解

     編輯:關於C語言

指針的四大核心屬性 (必須能瞬間回答)

屬性獲取方法示例 int *p;意義
指針類型 聲明語句去掉變量名 int * 決定指針本身佔用內存大小、解引用類型、指針算術步長
指向類型 聲明去掉變量名及最左 * int 決定 *p 的類型、sizeof(*p)、訪問內存的方式
指向內存區 (值) 賦值時決定 p = &x; &x 指針指向的起始地址,佔用 sizeof(指向類型) 字節
指針自身內存 sizeof(p) 4 字節 (32位) / 8 字節 (64位) 存儲地址值的變量自身

複雜聲明拆解練習

int *p;           // 類型:int*  指向:int
char *p;          // 類型:char* 指向:char
int **p;          // 類型:int** 指向:int*
int (*p)[3];      // 類型:int(*)[3] 指向:int[3] (指向3元素數組的指針)
int *(*p)[4];     // 類型:int*(*)[4] 指向:int*[4] (指向4元素指針數組的指針)

指針算術運算:步長由「指向類型」決定

char a[20]; int *p = (int*)a;  // 強制轉換演示
p++;  // p += sizeof(int) = 4 (32位)
/* 
   原指向 a[0..3] (4字節)
   現指向 a[4..7] (下4字節)
*/
  • p + n → 地址增加 n * sizeof(指向類型) 字節。
  • 指針減指針 → 返回元素個數差 (類型必須相同)。
  • 越界指針:語法合法,解引用即 UB。p+5 指向 a[20] 合法 (尾後指針),p+6 即 UB。

遍歷數組標準範式

int arr[20]; int *p = arr, *end = arr + 20;
for (; p != end; ++p) (*p)++;  // 修改每個元素

運算符 & (取址) 與 * (解引用)

運算符操作數結果類型結果值結果左值性
&左值 (變量/數組元素/解引用)類型 + *操作數地址右值
*指針類型指針指向類型指針指向的對象左值 (可賦值)

多級指針演示

int a = 12, b;
int *p = &a;        // p: int*, 指向 int, 值 &a
int **ptr = &p;     // ptr: int**, 指向 int*, 值 &p
*p = 24;            // a = 24
**ptr = 34;         // *ptr 是 p, **ptr 是 a → a = 34

指針表達式:結果為指針的表達式

int a, b, arr[10];
int *pa = &a;           // &a 是指針表達式
int **ptr = &pa;        // &pa 是指針表達式
pa = arr;               // arr 退化為指針表達式
pa++;                   // pa+1 是指針表達式
char *str = *parr;      // *parr (parr: char**) 是指針表達式
str = *(parr + 1);      // *(parr+1) 同理
  • 指針表達式同樣具備四大屬性。
  • 左值語境 (賦值目標) 表示存儲地址;右值語境 表示讀取地址值。

進階專題:函數指針與回調

// 聲明:返回 int,參數 (int, int) 的函數指針類型
typedef int (*BinOp)(int, int);

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

int compute(int x, int y, BinOp op) { return op(x, y); }

int main() {
    printf("%d\n", compute(3, 4, add));  // 7
    printf("%d\n", compute(3, 4, mul));  // 12
}

常見陷阱與最佳實踐清單

  1. 未初始化指針:定義即初始化 int *p = NULL; 或 int *p = &x;。
  2. 野指針:free(p) 後立即 p = NULL;;函數不返回局部變量地址。
  3. const 正確性:const int *p (指向常量) vs int *const p (常量指針) vs const int *const p。
  4. 指針 vs 數組:sizeof(arr) = 整個數組大小;sizeof(p) = 指針大小。數組不退化時 (如 &arr) 類型為 int (*)[N]。
  5. 結構體指針訪問:p->member 等價 (*p).member,前者更易讀。
  6. void 指針:通用字節指針,不可算術運算 (GCC 擴展允許按 1 字節),轉換為具體類型後再運算。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved