--- title: 關於指針的一些事情 tags: C++,挖坑 --- # 快速回顧 ```cpp= int * a_pointer; int a_value = 10; // & 取址符號 address-of operator a_pointer = & a_value; // * 解址(參)符號 dereference operator int another_value = * a_poointer; // 跟宣告指針的 * 不一樣喔 ``` # Pointers and Arrays 指針變數可以存放陣列的起始位置 但是陣列變數不可以任意更改成其他指針 ```cpp= int * pointer; int array[10]; //可以 pointer = array; //會報錯 array = a_pointer ``` :::danger 運算式必須是可修改的左值 ::: >我猜 array這個名字底下應該是宣告成 const >有關 const 請見這篇 "挖坑" ### 位移取值符號`[]` 其實不只陣列可以用這個方法取值 指標也可以 ```cpp= int * pointer = new int(); // 下面是做相同的事情 *(pointer+1)=10; // +1會根據指標的型態 移動對應的大小 // 像是 int 就是 4個byte (沒記錯的話 pointer[1] = 10; ``` 當然 陣列也可以使用第 3 行的方法 :::danger 注意 上面其實是一個非常危險的行為 因為我只有給指標一個位置 但是我卻隨便更改了他下一個位置的值 **但你並不知道這個位置是不是有給誰使用** **所以使用這種位置取值時一定要確認好範圍** ::: ### 常數指針 可以讀取值 但是不能更改值 跟函數常數參照很像 [參考這篇](https://hackmd.io/hYyfy28VROWMBN2ZfmYZCQ) ```cpp= int x; int * p1 = &x; // 非常數指針指向非常數變數 const int * p2 = &x; // 非常數指針指向常數變數 int * const p3 = &x; // 常數指針指向非常數變數 const int * const p4 = &x; // 常數指針指向常數變數 ``` ### 空指針 顧名思義 指向 空 的指針 作用為一個很有彈性的容器 你可以把任何型態的位置存進去 直到確定型態後再將他轉型 ```cpp= // increaser #include <iostream> using namespace std; void increase (void* data, int psize) { if ( psize == sizeof(char) ) { char* pchar; pchar=(char*)data; ++(*pchar); } else if (psize == sizeof(int) ) { int* pint; pint=(int*)data; ++(*pint); } } int main () { char a = 'x'; int b = 1602; increase (&a,sizeof(a)); increase (&b,sizeof(b)); cout << a << ", " << b << '\n'; return 0; } ``` :::info 上面就是用空指針接受變數的位置 其實也不用多宣告兩個指針去接轉型後的空指針 畢竟指針就是位置(:tea: ::: ### null指針 是一個指向 ==沒有地方== 的指針 有三種方式可以宣告 ```cpp= int * p = 0; int * q = nullptr; int * r = NULL; ``` 其中`NULL`代表的是`0`或`nullptr` 在某些標頭檔會宣告起來 ### 函數指針 就是指向函數的指針 長相有點不一樣 但邏輯還是在的 ```cpp= return_type (*function_name)(type_1,type_2...) = a_function; ``` 官方例子 ```cpp= // pointer to functions #include <iostream> using namespace std; int addition (int a, int b) { return (a+b); } int subtraction (int a, int b) { return (a-b); } int operation (int x, int y, int (*functocall)(int,int)) { int g; // 這裡取值時的寫法要注意 g = (*functocall)(x,y); return (g); } int main () { int m,n; int (*minus)(int,int) = subtraction; m = operation (7, 5, addition); n = operation (20, m, minus); cout <<n; return 0; } ```