C++ 入門指南 4.01

單元 4 - 指標與參考

-unit4-

指標 (pointer) 儲存變數 (variable) 的記憶體位址 (address) 參考 (reference) 則是變數的別名 (alias)

*nPtr &nRef

C++ 中,除了基本內建型態 (primitive built-in type) 與指標外,其他的變數大都可看作是物件 (object) ,指標是承接自 C 語言儲存記憶體位址的概念,如果指標運用得宜就可以寫出相當有效率的程式。

由於指標是儲存記憶體位址的資料型態,因此都可用指標指向基本內建型態或物件。宣告 (declare) 指標變數使用星號運算子,舉例如下

#include <iostream>

using namespace std;

int main(void) {
    // 設定 n 為整數 11
    int n = 11;
    cout << n << endl;

    // 設定 nPtr 為指向 n 的指標
    int *nPtr = &n; // & 是取址運算子
    cout << nPtr << endl;

    // 設定 t 取得從 nPtr 位址指向的值
    int t = *nPtr; // * 是反參考運算子
    cout << t << endl;

    return 0;
}

/* 《程式語言教學誌》的範例程式
   http://kaiching.org/
   檔名:pointer_demo.cxx
   功能:示範指標運算子
   作者:張凱慶 */

這個例子中,我們先宣告整數變數 n ,並且設定為 11

    // 設定 n 為整數 11
    int n = 11;
    cout << n << endl;

然後用 nPtr 取得 n 的記憶體位址。須留意 nPtr 的前面(等號左邊)加星號表示是指標,而這個星號運算子 * 用為宣告指標,指標的型態 (type) 必須與取得記憶體位置變數的型態相符,等號右邊則是利用取址運算子 (address-of operator) & 取得變數 n 的記憶體位置

    // 設定 nPtr 為指向 n 的指標
    int *nPtr = &n; // & 是取址運算子
    cout << nPtr << endl;

下面則是利用反參考運算子 (dereference operator) ,同樣是星號 * ,但是出現在等號的右邊,由 t 取得 nPtr 所儲存記憶體位置變數的值,這裡 nPtr 儲存的是 n 的記憶體位址, n 的值為整數 11

    // 設定 t 取得從 nPtr 位址指向的值
    int t = *nPtr; // * 是反參考運算子
    cout << t << endl;

會不會有點霧沙沙的呢?來組建執行看看囉

-pointer_demo.cpp-

指標就是儲存某個物件的記憶體位址,取址運算子用來取得變數或物件的記憶體位址,至於反參考運算子可從指標取得指向物件的值。

腦袋有沒有比較清楚了呢?大型程式常常上上下下、左左右右都是 *& ,我們在這裡先把這個容易搞混的地方用簡單的例子說明,另舉一個例子如下,連帶介紹參考 (reference) 與 new 關鍵字 (keyword)

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    // a 為字串變數
    string a = "There is no spoon.";
    cout << a << endl;

    // b 為對 a 的指標
    string *b = &a;
    cout << b << endl;

    // c 為對 a 的參考
    string &c = a;
    cout << c << endl;

    // d 為另一個指標
    string *d = new string("There is no spoon.");
    cout << d << endl;

    return 0;
}

/* 《程式語言教學誌》的範例程式
   https://kaiching.org/
   檔名:pointer_demo2.cxx
   功能:示範指標及參考運算子
   作者:張凱慶 */

宣告參考變數用到與取址運算子相同的 & ,但這出現在等號的左邊

    // c 為對 a 的參考
    string &c = a;
    cout << c << endl;

簡單來說,參考只是個別名,這個例子 ca 都是相同的字串 (string) 物件。

下面用 new 建立新的字串物件, new 建立的物件就必須放在指標之中

    // d 為另一個指標
    string *d = new string("There is no spoon.");
    cout << d << endl;

new 與指標為建立物件的另外一種方式,此例組建執行結果如下

-pointer_demo2.cpp-

總和以上來說, & 出現在等號左邊時用為宣告參考,出現在等號右邊是當作取址運算子,而 * 出現在等號左邊時用為宣告指標,出現在等號右邊則是反參考運算子。

有清楚了嗎?不過 &* 還有其他用法唷!碰到再介紹好了,接下來我們先來談談變數命名規則。

中英文術語對照
位址address
取址運算子address-of operator
別名alias
宣告declare
反參考運算子dereference operator
關鍵字keyword
物件object
基本內建型態primitive built-in type
指標pointer
參考reference
型態type
變數variable
重點整理
1. 指標用來儲存記憶體位址,宣告指標變數使用 * 運算子,可用取址運算子 & 取得記憶體位址。
2. 參考是變數的別名,宣告參考使用 & 符號。
3. 若用指標指向物件,新建物件須用 new 關鍵字及建構函數初始化物件,字串則可用字面常數的形式直接指派。
問題與討論
1. 為什麼指標運用得宜,可以寫出相當有效率的程式?
2. 反參考運算子用於指標所指向變數的值,是否也可以用於設定指標所指向變數的值呢?
3. 參考的用途為何?指標跟參考可以互相替代嗎?
練習
1. 寫一個程式 exercise0401.cxx ,先宣告一個 int 型態的變數 a ,並將 a 的值設定為 1 ,然後用指標 aPtr 取得 a 的記憶體位址,然後在命令列印出 aPtr 的值。 參考程式碼
2. 承上題,另寫一個程式 exercise0402.cxx,繼續加入一行 *aPtr = 2; ,然後在命令列印出 a 的值。 參考程式碼
3. 承上題,另寫一個程式 exercise0403.cxx,繼續加入一行 int b = *aPtr; ,然後在命令列印出 b 的值。 參考程式碼
4. 承上題,另寫一個程式 exercise0404.cxx,繼續加入一個參考變數 aRef ,以 aRef 當作 a 的別名,然後在命令列印出 aRef 的值。 參考程式碼
5. 承上題,另寫一個程式 exercise0405.cxx,將 aRef 更改為 3 ,然後在命令列印出 a 的值。 參考程式碼
6. 寫一個程式 exercise0406.cxx ,先宣告一個 stirng 型態的變數 c ,並將 c 的值設定自訂字串,然後用指標 cPtr 取得 c 的記憶體位址,然後在命令列印出 *cPtr 的值。 參考程式碼
7. 承上題,另寫一個程式 exercise0407.cxx,設定另一個指標變數 dPtr ,然後利用等號將 cPtr 的值指派給 dPtr ,再利用比較相等運算子 == 比較是否相等,若是相等就在命令列印出 c 的值。 參考程式碼
8. 承上題,另寫一個程式 exercise0408.cxx,設定另一個字串變數 d ,將 d 設定成跟 c 為相同內容的字串,另外設定指標變數 ePtr 並取得 d 的指標,然後在命令列印出 *ePtr 的值。 參考程式碼
9. 承上題,另寫一個程式 exercise0409.cxx,利用比較相等運算子 == 判斷 dPtrePtr 是否相等,如果相等就在命令列印出「指標相等」。 參考程式碼
10. 承上題,另寫一個程式 exercise0410.cxx,利用比較相等運算子 == 判斷 *dPtr*ePtr 是否相等,如果相等就在命令列印出「內容相等」。 參考程式碼

相關教學影片

上一頁 單元 3 - 基本內建型態與物件
回 C++ 入門指南 4.01 目錄
下一頁 單元 5 - 變數命名規則
回 C++ 教材
回程式語言教材首頁