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

C++ 指標入門完全指南:從基礎到動態記憶體管理

     編輯:關於C++

什麼是指標?

指標本質上也是變數,但一般變數儲存實際資料,指標儲存資料所在的記憶體位址。它像路標指引程式在記憶體何處找到資料。這是核心概念,許多演算法(如鏈結串列)皆圍繞指標設計。

指標宣告與初始化

宣告指標在變數名前加 *,慣例以 p 開頭命名提高可讀性:

int *pNumberOne;
int *pNumberTwo;

初始化使用 & 取址運算子(讀作「某物的位址」):

pNumberOne = &some_number;
pNumberTwo = &some_other_number;

此時 pNumberOne 指向 some_number,透過 *pNumberOne 即可存取該值。

基礎範例:透過指標修改變數值

#include <iostream>
using namespace std;

int main() {
    int nNumber = 15;
    int *pPointer = &nNumber;

    cout << "nNumber = " << nNumber << endl;  // 15

    *pPointer = 25;  // 透過指標修改值

    cout << "nNumber = " << nNumber << endl;  // 25
    return 0;
}

陷阱:指向區域變數的指標

int *pPointer;

void SomeFunction() {
    int nNumber = 25;
    pPointer = &nNumber;  // 危險!
}

int main() {
    SomeFunction();
    cout << *pPointer;  // 未定義行為:nNumber 已銷毀
}

錯誤原因:nNumber 為區域變數,函數結束時自動銷毀,pPointer 成為懸空指標,指向已無效的記憶體區域。

解決方案:動態記憶體配置

動態配置在堆疊 (heap) 分配記憶體,不隨函數結束而釋放,直到手動歸還。

int *pNumber;
pNumber = new int;      // 配置一個 int 空間,pNumber 指向它

double *pDouble;
pDouble = new double;   // 配置 double 空間

修正後的範例

int *pPointer;

void SomeFunction() {
    pPointer = new int;  // 配置記憶體
    *pPointer = 25;
}

int main() {
    SomeFunction();
    cout << *pPointer << endl;  // 正確輸出 25
    delete pPointer;             // 釋放記憶體!
    return 0;
}

重要:配置了記憶體必須釋放

動態配置的記憶體絕不會自動釋放。若不呼叫 delete,會造成記憶體洩漏,累積導致系統資源耗盡甚至崩潰。

delete pPointer;  // 釋放單一物件

陣列動態配置與釋放

int *pArray = new int[6];  // 配置 6 個 int 陣列
// ... 使用 pArray[0] ~ pArray[5] ...
delete[] pArray;           // 必須用 delete[] 釋放陣列!

錯誤示範:delete pArray; (漏掉 []) 僅釋放第一個元素,其餘洩漏。

指標作為函數參數:傳址呼叫

預設傳值呼叫只傳遞副本,函數內修改不影響原變數。傳遞指標可修改原值:

void AddFive(int *Number) {
    *Number = *Number + 5;  // 修改指標指向的值
}

int main() {
    int nMyNumber = 18;
    cout << "Before: " << nMyNumber << endl;  // 18
    AddFive(&nMyNumber);                       // 傳遞位址
    cout << "After: " << nMyNumber << endl;   // 23
}

函數回傳指標宣告:int * MyFunction();

指向類別的指標

類別指標存取成員需用 -> 運算子(而非 .):

class MyClass {
public:
    int m_Number;
    char m_Character;
};

int main() {
    MyClass *pPointer = new MyClass;
    pPointer->m_Number = 10;
    pPointer->m_Character = 's';
    delete pPointer;
}

指向陣列的指標

方法一:動態配置

int *pArray = new int[6];

方法二:指向現有陣列

int MyArray[6];
int *pArray = &MyArray[0];  // 或簡寫為 pArray = MyArray

注意:&MyArray 型別為「指向 6 個 int 陣列的指標」(int (*)[6]),非 int*,多維陣列易出錯。

指標陣列運算

  • pArray++ / pArray + 1:移至下一元素
  • pArray - 1:移至上一元素
  • pArray[i] 等價於 *(pArray + i)
  • 危險:指標運算不檢查邊界,越界存取導致未定義行為甚至崩潰。

常見錯誤與 FAQ

錯誤:刪除未動態配置的指標

void main() {
    int number = 10;
    int *pNumber = &number;
    delete pNumber;  // 嚴重錯誤!number 非 new 配置
}

FAQ

Q: 編譯 new/delete 報錯 symbol undefined?
A: new/delete 為 C++ 關鍵字,檔案副檔名必須為 .cpp,否則編譯器視為 C 程式碼。
Q: new 與 malloc 差異?
A: new 為 C++ 標準運算子,支援建構子/解構子、型別安全;malloc 為 C 函式,不呼叫建構子,C++ 中避免使用。
Q: 可混用 free 和 delete?
A: 嚴禁。free 僅配合 malloc,delete 僅配合 new,混用導致未定義行為。

補充:引用 (Reference) 簡介

引用是變數別名,語法 int &ref = var;。類似指標但自動管理生命週期、無懸空風險、不可重新綁定。適用於函數參數傳遞、運算子多載等場合。

int myFirst = 25, mySecond = 20;
int &myRef = myFirst;
myRef = mySecond;  // 將 myFirst 改為 20,而非讓 myRef 指向 mySecond
cout << myFirst;   // 輸出 20
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved