指標和引用
在 C++ 中,指標和引用是允許直接記憶體操作和高效資料傳遞的基本概念。它們對於理解 C++ 如何管理記憶體以及與硬體互動至關重要,並且它們與 JavaScript 的記憶體模型有顯著差異。
指標概念和語法
指標是一個儲存另一個變數記憶體位址的變數。它「指向」記憶體中儲存值的位置。指標功能強大,但需要仔細處理。
宣告和初始化指標
int* ptr;
// 宣告一個指向整數的指標。int* ptr = &variable;
// 使用variable
的位址初始化ptr
。
解引用指標
*ptr
// 存取儲存在ptr
中記憶體位址的值。
正在加载...
引用概念和語法
引用是現有變數的別名(另一個名稱)。一旦引用被初始化為一個變數,它就不能被重新設定以引用另一個變數。引用通常用於透過引用將參數傳遞給函式。
宣告和初始化引用
int& ref = variable;
// 宣告一個引用ref
並將其綁定到variable
。
正在加载...
指標算術運算
指標算術運算涉及對指標執行算術運算。它主要用於陣列。
ptr + n
:將指標向前移動n
個元素(而不是n
個位元組)。ptr - n
:將指標向後移動n
個元素。ptr1 - ptr2
:計算ptr1
和ptr2
之間的元素數量。
正在加载...
函式指標
函式指標是指向函式記憶體位址的指標。它允許你間接呼叫函式、將函式作為參數傳遞或將它們儲存在資料結構中。
正在加载...
指標和引用之間的差異
特性 | 指標 | 引用 |
---|---|---|
初始化 | 可以不初始化宣告 (但危險) | 必須在宣告時初始化 |
空值 | 可以是 nullptr (或 NULL ) | 不能為空 |
重新賦值 | 可以重新賦值以指向不同的變數 | 不能重新設定 (始終引用相同的變數) |
記憶體位址 | 儲存記憶體位址 | 是別名;不儲存自己的位址 (概念上) |
解引用 | 需要 * 才能解引用 | 不需要明確的解引用運算子 (直接使用) |
常見指標錯誤
- 懸空指標: 指向已釋放記憶體的指標。
- 野指標: 未初始化且指向任意記憶體位置的指標。
- 空指標解引用: 嘗試解引用
nullptr
,導致程式崩潰。 - 記憶體洩漏: 忘記
delete
動態分配的記憶體(模組 2 中已涵蓋)。
與 JavaScript 引用的比較
JavaScript 沒有 C++ 意義上的明確指標或引用。相反,持有物件(包括陣列和函式)的 JavaScript 變數儲存對這些物件的引用。這些引用由 JavaScript 引擎的垃圾回收器管理。
- 無手動記憶體管理: 你不需要在 JavaScript 中
new
或delete
物件;GC 會處理它。 - 無指標算術運算: 你不能對 JavaScript 引用執行算術運算。
- 引用可以重新賦值: 與 C++ 引用不同,JavaScript 引用可以重新賦值以指向不同的物件。
本質上,JavaScript 的物件引用在某種程度上類似於 C++ 指向物件的指標,但具有自動記憶體管理,並且無法執行指標算術運算或直接記憶體存取。
練習題:
- 解釋 C++ 指標和 C++ 引用之間的核心差異。何時會選擇使用其中一個?
- 編寫一個 C++ 函式,該函式接受一個整數指標作為參數,將其指向的值增加 5,然後列印新值。示範如何在
main
中呼叫此函式。 - 什麼是懸空指標,以及如何在 C++ 中避免建立它?
專案構想:
- 使用原始指標在 C++ 中實作一個簡單的動態陣列(類似於
std::vector
)。你的實作應包括新增元素、移除元素、調整陣列大小和按索引存取元素的函式。密切注意記憶體分配和釋放,以防止記憶體洩漏和懸空指標。