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

C++ 進階數據類型:指針完整指南

     編輯:關於C++

指針基礎:地址與間接訪問

計算機內存是位元組序列,每字節有唯一地址。變量編譯器自動分配地址,& 取地址,* 解引用(間接訪問)。

int andy = 25;
int* ted = &andy;  // ted 存儲 andy 的地址
int beth = *ted;   // beth 獲取 andy 的值 (25)
// ted == &andy, *ted == andy == 25

指針內存示意圖

指針聲明語法

type* name;  // type 是所指對象類型
int*   p1;   // 指向 int
char*  p2;   // 指向 char
float* p3;   // 指向 float
// 多指針聲明每個前加 *
int *p1, *p2; // 正確
int* p1, p2;  // p2 是 int 非指針!

指針與數組:天然聯繫

  • 數組名退化為首元素地址:int a[10]; int* p = a;
  • 數組名是常量指針:a = p; ❌ 不可修改
  • 下標等價指針算術:a[i] == *(a+i) == *(p+i) == p[i]
int nums[5];
int* p = nums;
*p = 10; p++;
*p = 20; p = &nums[2];
*p = 30; p = nums + 3;
*p = 40; *(p+4) = 50;
// nums: 10,20,30,40,50

指針初始化

int num;
int* tommy = # // 聲明時初始化
// 等價於
int* tommy; tommy = #

// 字符串字面值初始化 char*
const char* terry = "hello"; // 指向只讀內存區
// terry[0] = 'H'; // 未定義行為!
// 安全做法
char terry2[] = "hello"; // 字符數組,可修改
terry2[0] = 'H'; // OK

字符串指針內存佈局

指針算術:按類型大小步進

p++ 使 p 指向下一個同類型對象,地址增加 sizeof(*p) 字節。

char*   pc = (char*)1000;  // 1001
short*  ps = (short*)2000; // 2002
long*   pl = (long*)3000;  // 3004
pc++; ps++; pl++;

指針算術步進示意

運算符優先級陷阱

*p++  // 等價 *(p++):先取值後遞增指針
(*p)++  // 遞增所指值
*p++ = *q++ // 先賦值 *p=*q,再 p++、q++

建議:括號消除歧義。

多級指針

char a = 'z';
char*  b = &a;
char** c = &b;
// c 存 8092, *c 存 7230, **c 存 'z'

多級指針內存結構

void 指針:類型擦除的通用指針

  • 可指向任意類型對象:void* pv = &x;
  • 不能直接解引用:類型未知無法確定大小
  • 使用前必須強轉回目標類型
void increase(void* data, int type) {
    switch (type) {
        case sizeof(char):   (*static_cast(data))++; break;
        case sizeof(short):  (*static_cast(data))++; break;
        case sizeof(long):   (*static_cast(data))++; break;
    }
}
char c='a'; short s=1; long l=100;
increase(&c, sizeof(c));
increase(&s, sizeof(s));
increase(&l, sizeof(l));

函數指針:將函數作為數據傳遞

聲明語法

返回類型 (*指針名)(參數列表);
int (*pf)(int, int); // 指向 int(int,int) 的函數指針

實戰:策略模式雛形

int add(int a,int b){ return a+b; }
int sub(int a,int b){ return a-b; }

int operate(int x, int y, int (*op)(int,int)) {
    return op(x,y);
}

int main() {
    int (*funcPtr)(int,int) = sub; // 指向 sub
    cout << operate(7,5,add) << '\n'; // 12
    cout << operate(20,12,funcPtr) << '\n'; // 8
}

現代 C++ 替代方案

C++11 std::function + lambda 更靈活、類型安全:

#include 
using Op = std::function;
int operate(int x, int y, Op op) { return op(x,y); }
operate(3,4, [](int a,int b){ return a*b; }); // lambda

總結:指針核心知識圖譜

  1. & / *:取址與解引用,內存訪問基石
  2. 聲明:T* p,T 為目標類型
  3. 數組退化:數組名 → 首元素地址,不可修改
  4. 算術:按 sizeof(T) 步進,優先級高於 *
  5. 多級:每級 * 解一層引用
  6. void*:類型擦除,需強轉使用,C 風格泛型基石
  7. 函數指針:回調、策略模式,現代 C++ 推薦 std::function

指針是 C++ 性能與靈活性的源泉,亦是 Bug 溫床。掌握內存模型、嚴守類型安全、善用現代封裝(智能指針、容器、span),方能馴服這把雙刃劍。

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