# Chapter 08 記憶體與指標 <C++> ###### tags: `C++` --- [TOC] --- ## 8.1 指標與變數 ``` 資料型態 *指標名稱 = &變數位址; ``` - 上面是宣告指標名稱同時指定變數位址給指標 - 下面範例是將**int* numPtr** 與 **numPtr = number** 二敘述合併成一敘述。 ```cpp= int number; int *numPtr = &number; ``` ### 間接運算符號 * - [間接運算符號(indirection operator)](http://tw.gitbook.net/cplusplus/cpp_pointer_operators.html)是用來取得參考位址內的值,也稱為[反參考運算符號(de-reference operator)](http://tw.gitbook.net/cplusplus/cpp_pointer_operators.html) 下面範例是取得指標內的資料,*numPtr 表示取得指標 numPtr 索引位址的值。所以x =*numPtr 與 x = number 的作用是一樣的,不同的是 *numPtr 是間接取得,使用 number 是直接取得。 ```cpp= int x; int number = 10; int *numPtr = &number; . x = *numPtr; ``` 下面範例是設定一個整數指標變數,並將整數 100 存入指標所指定的位址。 ```cpp= int *numPtr; *numPtr = 100; ``` 下面是實務會用的寫法。 ```cpp= int main() { int x, number = 10; int* pointer = &number; x = *pointer; // 這個*是必要 std::cout << x << std::endl; } ``` 範例證明,非位址是無法存入指標變數。 ```cpp= int *numPtr = 100; //錯誤,int 不能存入 int* ``` --- 取址與取值的差別 ```cpp= int number = 100; int *numPtr = &number; cout << "numPtr = " << numPtr << endl; cout << "*numPtr = " << *numPtr << endl; ``` * 程式輸出 ```cpp numPtr = 0027F8CC *numPtr = 100 ``` --- ### 長度運算符號 ``` sizeof 變數名稱; ``` sizeof 運算符號通常被用來計算陣列元素的個數,計算方式如下: * `sizeof array / sizeof array[0] ` **:** 可取得陣列指標中的元素個數。 ## 8.2 指標與陣列 陣列名稱本身就是指標,所以可以直接將陣列名稱當作指標來使用外,還可將陣列名稱指定給另一個指標。最後字串陣列又與一般數值陣列不盡相同,所以字串陣列指標的用法又有些許差異。 ```cpp= int array[10]; int *arrayPtr = array; arrayPtr = array; // 下面這行做的事與上面一樣 ``` ### 8.2.2 陣列元素指標 ``` 資料型態 *指標名稱 = &陣列名稱[註標]; ``` - 若指標指向陣列的註標位址,陣列名稱[**註標**]之前必須加位址運算符號(&)。 - EX : ```cpp= #include <iostream> using namespace std; int main() { short array[] = {30, 47, 26, 17, 22, 23}; short *arrayPtr; const int SIZE = (sizeof array)/(sizeof array[0]); for(int i=0; i<SIZE; i++) { arrayPtr = &array[i]; //宣告並起始陣列指標 cout << "array 的第 " << i << "個陣列元素是 : "; cout << *arrayPtr << endl; //如果*arrayPtr不加*就是記憶體位置 } } ``` ### 8.2.3 指標運算 ``` *(陣列名稱+n) ``` - EX : ```cpp= short array[] = {30, 47, 26, 17, 22, 23}; for(int i=0; i<6; i++) { cout << "array[" << i << "] = " << *(array+i); } ``` ### 8.2.4 指標增減 - 第一種 ``` ++指標名稱 | 指標名稱++ --指標名稱 | 指標名稱-- ``` - 第二種 ``` 指標名稱 += n 指標名稱 -= n ``` - EX : ```cpp= #include <iostream> using namespace std; int main() { double array[] = {3.0, 4.7, 2.6, 1.7, 2.2, 2.3}; double *arrayPtr = &array[0]; //宣告並起始陣列指標 const int SIZE = (sizeof array)/(sizeof array[0]); // 計算陣列個數 cout.precision(1); //設定有效位數1位 cout.setf(ios::fixed); //改為小數有效位數1位 for(int i=0; i<SIZE; i++) { cout << "array 的第 " << i << "個陣列元素是 : "; cout << *arrayPtr++ << endl; } } ``` - 陣列指標增減練習 ```cpp= #include <iostream> using namespace std; const int SIZE = 6; int main() { int array[SIZE]; int* arrayPtr = &array[0]; int i; cout << "請輸入 " << SIZE << " 筆整數資料 : "; for (int i = 0; i < SIZE; i++) { cin >> *arrayPtr++; } } ``` ## 8.3 指標與函數 ### 8.3.1 傳遞變數指標 ``` 函數名稱(變數指標); //呼叫敘述 傳回型態 函數名稱(參數型態 *參數名稱) //函數表頭 { //函數本體 } ``` - [傳遞變數指標(pass-by-reference using a pointer)](http://hungming.ct.ntust.edu.tw/2020spring/ct3407/classnotes/ct3407_9.pdf)與 傳遞變數位址(pass-by-reference) 類似,都是傳遞變數的位址給被呼叫函數,只是傳遞變數指標是先將變數位址存入變數指標再傳遞。 ## 8.4 動態記憶體 --- ### 延伸閱讀 * [[C++基础]019_指针和引用(int*、int&、int*&、int&*、int**)](https://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/10/2719192.html) ---