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

C語言指針完全指南:從基礎概念到函數指針的系統性掌握

     編輯:關於C

1. 指針基礎:定義、賦值、解引用

int a = 9;\
int *aPtr = NULL;      // 定義並初始化為空指針\
aPtr = &a;             // 取地址賦值\
printf("a=%d, *aPtr=%d\\n", a, *aPtr);  // 解引用獲取值\
printf("&a=%p, aPtr=%p\\n", &a, aPtr);  // %p 輸出地址\
// * 和 & 互補:&*aPtr == *&aPtr == aPtr
  • NULL (0) 表示不指向任何對象,唯一可直接賦給指針的整數常量。
  • 指針變量本身佔用固定大小(32位 4B,64位 8B),存儲地址值。

2. 指針作為函數參數:模擬引用傳遞

2.1 值傳遞 vs 指針傳遞

C 僅支持值傳遞。傳遞指針(地址)可在被調函數中修改主調函數變量。

void swap(int *x, int *y) {\
    int t = *x; *x = *y; *y = t;\
}\
int a=1, b=2; swap(&a, &b);  // a=2, b=1

2.2 const 修飾符四種組合

聲明含義可修改指針值可修改所指值
int *p指向非常量的非常量指針✅✅
int *const p指向非常量的常量指針❌✅
const int *p指向常量的非常量指針✅❌
const int *const p指向常量的常量指針❌❌

口訣:const 在 * 左修飾所指值,右修飾指針本身。

3. sizeof 與指針算術

3.1 sizeof

  • 編譯期運算符,返回類型/變量佔用字節數。
  • sizeof(arr) 返回整個數組大小;sizeof(ptr) 返回指針大小(非數組大小)。
  • 數組元素個數:sizeof(arr)/sizeof(arr[0])。

3.2 指針算術運算

  • 合法運算:ptr++、ptr--、ptr + n、ptr - n、ptr1 - ptr2。
  • 步長 = sizeof(指向類型)。int *p; p++ 移動 4 字節。
  • ptr1 - ptr2 返回元素個數差(需同屬一數組)。

3.3 void* 通用指針

  • 可接收任意類型指針賦值,無需轉型。
  • 不能解引用(編譯器不知類型大小)。
  • 用於泛型函數參數(如 memcpy、qsort 比較函數)。

4. 指針與數組的深度關聯

4.1 數組名本質

int a[6] 中 a 為常量指針(指向首元素),a[3] ≡ *(a+3) ≡ *(aPtr+3)。

區別:aPtr = aPtr + 3 合法;a = a + 3 非法(常量不可修改)。

4.2 指針數組:字符串數組的高效表示

const char *suit[4] = {"Hearts", "Diamonds", "Clubs", "Spades"};\
// 每元素 4/8 字節指針,指向字面量區,共享只讀內存\
// sizeof(suit[i]) == sizeof(char*) == 4/8\
// sizeof(suit) == 4 * sizeof(char*)

對比二維字符數組 char suit[4][10] 固定分配 40 字節,指針數組極大節省空間且支持可變長字符串。

5. 函數指針:回調與策略模式的基石

5.1 基本聲明與調用

int max(int a, int b);\
int (*p)(int, int) = max;\
int res = (*p)(2, 3);  // 或 p(2,3)

5.2 回調實現冒泡排序策略切換

int ascending(int a, int b) { return a > b; }\
int descending(int a, int b) { return a < b; }\
\
void bubble(int arr[], int n, int (*cmp)(int, int)) {\
    for (int i = 1; i < n; ++i)\
        for (int j = 0; j < n - i; ++j)\
            if ((*cmp)(arr[j], arr[j+1])) swap(&arr[j], &arr[j+1]);\
}\
\
bubble(a, 10, ascending);   // 升序\
bubble(a, 10, descending);  // 降序

5.3 函數指針數組:命令分發表

void func1(int x); void func2(int x); void func3(int x);\
void (*f[3])(int) = {func1, func2, func3};\
(*f[choice])(choice);  // 根據輸入分發

6. 綜合最佳實踐清單

  1. 定義即初始化:int *p = NULL; 或 int *p = &var;。
  2. 解引用前檢查非空:if (p) { ... }。
  3. 函數參數優先 const T*,需修改才用 T*。
  4. 指針算術僅在同一數組/分配塊內進行。
  5. 釋放後置空:free(p); p = NULL; 防野指針。
  6. 避免多級指針(>2 級),改用結構體封裝。

指針是 C 語言靈魂,掌握其類型系統、內存模型、算術規則、與數組/函數的轉換關係,才能寫出高效、安全、優雅的系統級代碼。

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