# C++ 指標與參考 [toc] ## 指標(Pointer) C++ 的原生指標定義為: ```c= #include <iostream> int main(int argc, char** argv) { int a = 6; int* p = &a; std::cout << "The value of variable a: " << a << std::endl; std::cout << "The address of variable a: " << &a << std::endl; std::cout << "The value of the referenced variable by pointer p: " << *p << std::endl; std::cout << "The value of pointer p: " << p << std::endl; std::cout << "The address of pointer p: " << &p << std::endl; return 0; } ``` > `*` 稱之為解引用運算元(dereference operator),在這邊 `&` 為取址運算元(address-of operator) 指標 `p` 本身儲存是所指向資料的記憶體位址,如果輸出 `p` 的話看到的只是指向資料的記憶體位址,必須搭配解引用運算元 `*p`,才能取得指標所指向的資料。 ### Null Pointer 原生指標可以是 nullptr(建議不要使用 NULL),例如: ```c= int* p = nullptr; ``` > 指標 p 的值會是 0x0000000,沒有任何記憶體位置可以參考,使用 `*p` 將會出錯哦。 ### Void Pointer 沒有指定特定資料型態的指標,可以好處是可以自由切換資料型態,但輸出時需要轉型。 ```cpp= #include <iostream> int main(int argc, char** argv) { int a = 5; char e = 'e'; void* p; p = &a; std::cout << "The value of the referenced variable by pointer p: " << *static_cast<int*>(p) << std::endl; std::cout << "The value of pointer p: " << p << std::endl; std::cout << "The address of pointer p: " << &p << std::endl; p = &e; std::cout << "The value of the referenced variable by pointer p: " << *static_cast<char*>(p) << std::endl; std::cout << "The value of pointer p: " << p << std::endl; std::cout << "The address of pointer p: " << &p << std::endl; return 0; } ``` ### 複雜指標 ```cpp= int a = 5; // 一般變數 int* b = &a; // 指向 int 的指標 int** c = &b; // 指向 int* 的指標 int**& d = c; // int** 指標的參考 ``` ### 指標與陣列 ```cpp= int b[3] = { 0, 1, 2 }; // 宣告一維陣列 int* a = b; // 指向陣列的指標 int* c = &b[0]; // 指向 b[0] 的指標 // 二維陣列 int d[2][3] = { {4, 5, 9}, {1, 2, 10} }; int* e = d[0]; int* f = &d[0][0]; int* g[2] = { d[0], d[1] }; int** h = g; int i = h[0][2]; // it's 9. ``` ## 參考(Reference) 參考是 C++ 才有的功能,可以簡單看做別名(Alias)的意思。 ```cpp= int n = 10; // 宣告變數 int* p = &n; // 宣告指標 int& r = n; // 定義參考,變數 n 的別名 ``` 參考不會複製該物件(記憶體區塊),缺點是參考不可以是 NULL、必須要有初始值,且不能參考右值(rvalue)。這邊的 `&` 並不是取址運算元哦!稱之為參考運算元(reference operator) > 參考與指標最大的不同在於,用在函數當參數使用時,指標實際上依舊是 Call by Value,而真正的 Call by Reference 是 C++ 的參考才具有的。 ```cpp= #include <iostream> void magic(int a, int b) { std::cout << "Call by value" << std::endl; std::cout << "The Value of a in magic: " << a << std::endl; std::cout << "The Address of a in magic: " << &a << std::endl; std::cout << "The Value of b in magic: " << b << std::endl; std::cout << "The Address of b in magic: " << &b << std::endl; } void magic2(int* a, int* b) { std::cout << "Call by pointer" << std::endl; std::cout << "The Value of a in magic: " << *a << std::endl; std::cout << "The Address of a in magic: " << a << std::endl; std::cout << "The Value of b in magic: " << *b << std::endl; std::cout << "The Address of b in magic: " << b << std::endl; std::cout << "The address of pointer a: " << &a << std::endl; std::cout << "The address of pointer b: " << &b << std::endl; } void magic3(int& a, int& b) { std::cout << "Refernce" << std::endl; std::cout << "The Value of a in magic: " << a << std::endl; std::cout << "The Address of a in magic: " << &a << std::endl; std::cout << "The Value of b in magic: " << b << std::endl; std::cout << "The Address of b in magic: " << &b << std::endl; } int main(int argc, char** argv) { int a = 5; int b = 6; int* pa = &a; int* pb = &b; std::cout << "In Main Program" << std::endl; std::cout << "The Value of a in magic: " << a << std::endl; std::cout << "The Address of a in magic: " << &a << std::endl; std::cout << "The Value of b in magic: " << b << std::endl; std::cout << "The Address of b in magic: " << &b << std::endl; std::cout << "The address of pointer pa: " << &pa << std::endl; std::cout << "The address of pointer pb: " << &pb << std::endl; magic(a, b); magic2(pa, pb); magic3(a, b); return 0; } ``` 透過以上程式會發現,在 `main()` 當中的指標 `pa` 與 `pb` 與函數 `magic2()` 當中的指標 `a` 和 `b` ,兩邊的指標記憶體是不相同的,也就是說如果在函數 `magic2()` 修改了指標 `a` 和 `b` 的值(記憶體位置),在 `main()` 中的指標 `pa` 與 `pb` 並不會跟著連動。 參考也可以參照指標,語法如下: ```cpp= int a = 5; // 一般變數 int &b = a; // a 的參考(a的別名) int* p = &a; // 宣告指標 int*& r = p; // int* 指標的參考 int&* g = p; // error: cannot declare pointer to 'int&' ``` > 要怎麼理解 `int*&`,從右往左讀就對了,所以它是一個 "參考",參考什麼呢?是整數指標 `int*`;然後需要特別注意一下 `int&*` 是不合法的。 ## Template https://vinesmsuic.github.io/2020/01/12/c++-template/#template-specialization https://docs.microsoft.com/zh-tw/cpp/cpp/templates-cpp?view=msvc-170 https://hackmd.io/@butastur/cpp11-templates-1 https://www.rocksaying.tw/archives/3641717.html https://magicjackting.pixnet.net/blog/post/221968938 ###### tags: `C++`