# 我們來"參考"一下 [TOC] ## 參考是什麼? 參考是什麼? 參考,英文名字叫做Reference 簡單來說,大家都有被取綽號的經驗吧,像是: 我名字叫做張簡雲翔,有人會叫我張簡、雲翔、山豬、死胖子等 ~~(都好難聽Q)~~ 當別人叫我的時候,就可能會叫上面的名字,我都會知道別人再叫我 不管你用哪個名詞叫我,我還是我 不會你叫我山豬,我就真的變成一隻山豬吧XD Reference有點像這種感覺 **就是一個變數,但是它有很多很多個名字** 換句話說 **一個變數,它除了自己的名字外,還有別名(Alias)** 我們來看段程式碼 ```cpp= #include<iostream> using std::cout; using std::endl; int main(int argc,char* argv[]) { int n=0; int& rn=n; //declar reference cout<<" n:"<<n<<endl; cout<<"rn:"<<rn<<endl; n=20; cout<<" n:"<<n<<endl; cout<<"rn:"<<rn<<endl; return 0; } ``` 上面這段程式碼,輸出的結果如下:  你會發現,我剛剛上面的程式碼,我改的明明是n的值,但是rn也被改了 這個就是參考的威力 ~~(威利在哪裡)~~ 你還會發現,上面的程式碼,出現了一個神奇的語法 > int& rn=n; 這段語法就是在進行宣告一個參考的動作 **我宣告一個參考叫做rn,這個東西是n的別名** 接下來,我們把上面的程式碼改一下,變成這樣 ```cpp= #include<iostream> using std::cout; using std::endl; int main(int argc,char* argv[]) { int n=0; int& rn=n; //declar reference int *p1,*p2; p1=&n; p2=&rn; cout<<" n的記憶體位置:"<<p1<<endl; cout<<"rn的記憶體位置:"<<p2<<endl; return 0; } ``` 結果變成這樣:  你會發現,這時候無論是n還是rn的記憶體位置都是一樣的 可以證明,我無論再叫n還是rn都是在叫同一個記憶體位置  ### 小結 所謂參考,就是一個變數,我們給他另外一個別名 無論叫它自己本來的名字,還是參考的名字,都是在講同一個記憶體位置 ## 複習一下Pass by value/address 如果你學過Function,你對這兩個名詞應該都不陌生 如果你沒學過Function,或者完全忘記那是什麼,~~那你加油~~ 我這邊就不贅述Function是什麼,不知道的,請你自己先去研究完再繼續看 ### Pass by value 顧名思義,就是**傳值** 範例如下 ```cpp= #include <iostream> using std::cout; using std::endl; int value(int); //prototype int main(int argc,char* argv[]) { int a=0,b=0; b=value(a); cout<<a<<'\t'<<b<<endl; return 0; } int value(int a) { a=a+100; return a; } ``` 上述程式碼,結果如下  從上面的程式碼,你可以發現 今天我在main function ~(第9行到第15行)~裡面的a 跟在value這個function ~(第17行到第21行)~裡面的a 是不一樣的a ~~(好繞口)~~ 這是因為,今天在**傳值**的時候 我是把一個數字傳過去,之後那邊再開一個記憶體空間來存它 所以當我value這個function結束後,value的a就會不見了  ### Pass by address 從名字上能看得出來,就是**傳址** 但畢竟遇到是要**傳址**,所以會跟指標扯上關係,所以我們先來複習一下指標 >int* p; 宣告一個整數指標做叫p >p=&a; &是一個一元運算子,它又稱為取址運算子,用途是在取得跟在它後面的變數在記憶體中所儲存的空間的位置 ~~(真的很繞口)~~ 所以說這句話的意思是,我對a取址放進p這個整數指標變數 >*p+=100; *在這邊也是一個一元運算子,它是一個提領運算子,用途是在取得,這個指標所對應的資料型態大小的空間。 上面的語法就會提領p後面整數大小的空間 並對p所指向的空間,加100 上面講的有點饒口,我們再看一個例子 * Ex: >double a; >double *ptr=&a; 這個是一個**雙精度浮點數**指標變數p,裡面放a的位置 >*ptr; 這一行就會提領後面**雙精度浮點數大小**(8 bytes)的空間出來。 複習完指標了,那我們來看傳址的範例 ```cpp= #include <iostream> using std::cout; using std::endl; void value(int*); //prototype int main(int argc,char* argv[]) { int a=0; int* p=&a; value(p); cout<<a<<endl; return 0; } void value(int* p) { *p+=100; } ``` 結果如下  從上面的程式碼,你可以觀察到 a原本是0但是經過value(p)這一行後,a卻變成了100 這代表在value這個function中,它改變了a的值 可是這個情況跟剛剛**傳值**感覺起來不一樣 這是因為,我們傳的東西,並不是一個數值,而是**一個指標** 我們利用指標去找同一塊記憶體位置,去進行運算,所以才會改變原本的數值  ### 小結 Pass by value 只有傳值過去,那邊的空間與這邊的空間都沒有關係 Pass by address 透過指標,去找同一塊記憶體空間,改變裡面的數值 ## 來傳參考囉:Pass by reference Pass by reference 是一種C沒有,C++才有的一種傳遞參數的方法 我私心覺得,它是一個很好用的方法 因為傳址的語法比較複雜,有時候會打錯 那什麼是Pass by reference呢? 我們先來看一段語法 ```cpp= #include <iostream> using std::cout; using std::endl; void value(int&); //prototype int main(int argc,char* argv[]) { int a=0; value(a); cout<<a<<endl; return 0; } void value(int& ra) { ra+=100; } ``` 結果長得像這樣  從上面語法你會發現,我既沒有用指標,也沒有回傳數值,但是我main function裡面的a還是被改變了 這個就是**傳參考**的方便之處 我自己會覺得,**傳參考**有點像傳值跟傳址的融合 語法像傳值但是行為像傳址 今天我在開頭的prototype中 > void value (int&); 已經先跟電腦說好,我等等接收的參數會是一個**參考** 然後我再呼叫這個function的時候 >value(a); 它就會進入value這個function 這時候的ra就是a在value這個function的參考/別名 既然它是a的別名,自然我在value中,呼叫ra就是在叫a **但是ra這個名字,只能在value這個function中用** 就跟你有些綽號,特定的人才能叫一樣  ### 小結 Pass by reference是一種傳遞參數得方式 今天傳遞的東西是reference 被傳遞的參數,在這個function會有一個新的別名 這個別名只能在這個function中用 ###### tags:`筆記`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up