# 指標 & 參照 ## 2021/11/05 電算社第七堂社課 --- ## 記憶體 ---- 是電腦儲存變數值的地方, 可以把它想像成是<font color="#FFF300">一個很長的紙帶</font> 上面有很多<font color="#FFF300">連續的格子</font>,每一個格子有<font color="#FFF300">連續的編號</font> 每個格子是 1 bit(0 or 1) 8 個 bit 組成 1 byte ![](https://i.imgur.com/sgeOA6h.png =80%x) --- ## 指標 Pointer ---- 指標是一種變數, 裡面存放一個變數的第一個記憶體位置(address) 可以視為它是<font color="#FFF300">"指向該變數的變數"</font> ---- 宣告 ```cpp= int *ptr; ``` 指向(賦值) ```cpp= int a = 100; int *ptr = &a; //宣告一個指標ptr,指向 a 的記憶體位置 //&是取址的意思,也就是取得a的記憶體位址 ``` ```cpp= //或者是 int *ptr; int b = 100; ptr = &b; //宣告一個指標ptr,指向 b 的記憶體位置 ``` ---- 取值 ```cpp= int a = 100; int *ptr = &a; cout << ptr << " 、 " << *ptr << endl; //*ptr可以知道ptr指向的變數的值 //輸出結果 : a的記憶體位置 、 100 ``` ---- 改值 ```cpp= int a = 100; int *ptr = &a; cout << ptr << " 、 " << *ptr << endl; //輸出結果 : a的記憶體位置 、 100 *ptr = 110; //它會直接更動指向的變數(a)的值 cout << ptr << " 、 " << *ptr << endl; //輸出結果 : a的記憶體位置 、 110 ``` ---- ### 小差異(常用錯!!) ```cpp= int a = 10, b = 20; int *ptr = &a; //ptr這個指標指向a ptr = &b; //現在改成指向b *ptr = a; //這個跟上一行不一樣,ptr仍舊指向b,但是b的值被改為與a相同 ``` --- ## reference(參照) ---- reference可以理解成是一個變數的<font color="#FFF300">別名</font> 它不像指標會儲存記憶體位置 他反而可以<font color="#FFF300">直接操控該變數</font> ---- ```cpp= int a = 10; int &b = a; //宣告一個reference b,指向a,想像它是a的綽號 ``` ---- 應用 ```cpp= int a = 10; int &b = a; cout << a << ' ' << b << endl; //輸出 10 10 b = 100; //會間接讓a也變成100 cout << a << ' ' << b << endl; //輸出 100 100 ``` --- ## 指標 vs 參照 ---- 直接看例子吧:D ---- ```cpp= #include <iostream> using namespace std; int main(){ //宣告 int a = 2; int *pt = &a; // pt是一個指標變數,存取a的記憶體位置 int &r = a; // r是一個參照,為a的綽號 cout << a; // 2 cout << &a; // a的記憶體位置 cout << *&a; // 2 cout << pt; // a的記憶體位置 cout << &pt; // pt的記憶體位置 cout << *pt; // 2 cout << r; // 2 cout << &r; // a的記憶體位置 cout << *&r; // 2 return 0; } ``` --- ## 函式 ## call by value & call by address & call by reference --- ### call by value ---- call by value就是傳值的意思, <font color="#FFF300">呼叫變數時是複製一份數值,</font> 而非將記憶體連動過去 上一堂課中的那些引數都是 call by value ---- Example: ```cpp= #include <iostream> using namespace std; void add(int value_a){ value_a++; cout << value_a << '\n'; //2 } int main(){ int a = 1; add(a); cout << a; // 1 return 0; } //上面的函式將a的數值複製一份到value_a,所以改變value_a的值並不會改變a的值 ``` ---- 那如果想<font color="FFF300">改變值</font>的話該怎麼辦呢 這時候就必須<font color="#FFF300">回傳</font> ---- ```cpp= #include <iostream> using namespace std; int add(int value_a){ value_a++; return value_a; } int main(){ int a = 1; cout << add(a); // 2 return 0; } ``` --- ### call by address ---- call by address 就是傳指標,傳到函式時用指標連動到原先的變數,所以改變指標時原先的值也會改變 ---- Example: ```cpp= #include<iostream> using namespace std; void add(int *pointer_a){ (*pointer_a)++; //記得加(),因為 ++ 的優先度高於取值(*) } int main(){ int a = 1; add(&a); //記住要傳的是 a 的位置 cout << a; // 2 return 0; } //pointer_a 是個指向 a 記憶體位置的指標 //所以改變 pointer_a 的值 a 也會變 ``` --- ### call by reference ---- call by reference就是傳參照,呼叫變數時會直接連動記憶體,所以改變值時原變數的值也會跟著改變 ---- Example: ```cpp= #include <iostream> using namespace std; void add(int &reference_a){ reference_a++; } int main(){ int a = 1; add(a); cout << a; // 2 return 0; } //reference_a和a的記憶體位置是共用的 //所以改變reference_a的值也就改變了a的值 ``` --- ### 小練習 ---- 試著做出一個可以調換數值的函式吧,規定此函式回傳值必須為void,且輸出必須放在main函式中 ---- 輸入說明:輸入兩個數a, b 輸出說明:輸出a, b調換數值後的結果 範例輸入:1 2 範例輸出:2 1 ---- 我是防雷頁:D ---- 常見錯誤 ```cpp= #include <iostream> using namespace std; void swap(int a, int b){ int t = a; a = b; b = t; } int main(){ int a, b; cin >> a >> b; swap(a, b); cout << a << b; return 0; } //call by value的函式會複製一份數值進去函式,所以不會改變原來的值 ``` ---- 解答(call by address) ```cpp= #include <iostream> using namespace std; void swap(int *a, int *b){ int t = *a; *a = *b; *b = t; } int main(){ int a, b; cin >> a >> b; swap(&a, &b); cout << a << ' ' << b; return 0; } ``` ---- 解答(call by reference) ```cpp= #include <iostream> using namespace std; void swap(int &a, int &b){ int t = a; a = b; b = t; } int main(){ int a, b; cin >> a >> b; swap(a, b); cout << a << ' ' << b; return 0; } ```
{"metaMigratedAt":"2023-06-16T12:35:04.444Z","metaMigratedFrom":"YAML","title":"指標 & 參照","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"theme\":null}","contributors":"[{\"id\":\"4f731eff-9d88-41f4-af56-2e3e02f20cfc\",\"add\":1814,\"del\":47},{\"id\":\"9e7d687a-83f2-4e8a-8ee6-8846394e69a5\",\"add\":26,\"del\":16},{\"id\":\"68c94489-3c2e-4879-b847-e982f360b03c\",\"add\":2389,\"del\":210},{\"id\":\"efc43b79-1b19-4cb1-9b18-ce50fad56214\",\"add\":384,\"del\":7}]"}
    474 views