C/C++ 指標(*) point 和 參考(&) refrence 差別及相關範例
本文所指的指針的指針指的是指標,個人覺得這樣比較好做區別
初學時時常讓人搞不清楚的兩個不同的東西,這邊提供幾個大原則做判斷
指針:可以儲存記憶體位置的型別
參考:就好像別名一樣可以完全等同於所指之物
比較特別的還有一種情況叫做(*\&)指針的參考,這又是什麼呢?
兩個符號的用法
分別是
*
取址 reference
&
取值 dereference
他們放在非宣告時的變數的前方,從英文可以看出他們具有相反的關係。
首先最讓人搞不清楚的是為什麼他們在宣告時有不同的關係,那根本就是不一樣意思了。
int* i;
int& a;
你把它當作別的東西來看直接把整串看做是一個型別。
我的意思是你不要這樣看int
* i; 而直接是 int*
i;
前者表示宣告一個指針容器,後者表示宣告一個別名,跟剛剛的*&
完全是兩回事。
由此我也更推薦你使用 int* i;
而不是 int *i;
這樣更容易表達。
除非你需要連續宣告,這就真的不得已了int *i, *j;
連續宣告時要個別指定。
回到剛剛的取址與取值簡單來說就是你現在有一個變數,它存在記憶體的某個地方,這個某個地方會用一串數值表示位置比如說 0x01
現在你手上拿到 p=0x01 你希望獲取他的數值就是使用取值 *p
獲取內容
你現在手上拿到 p=0; 你希望獲取他的地址就是使用取址 &p
獲取地址
地址的傳遞可以共同編輯
函式(包含main)內都有各自的空間,彼此是不同互相存取的除非你使用全域函式。
他就像一個公用櫃子一樣,只要你告訴別人我的東西放在幾號櫃子別人就可以來存取。
比如以下的代碼
int i=0;
int* p=&i;
現在p也可以修改i
*p = 1;
把它放到函式內就像這樣
void fun(int* p){
*p = 1;
}
使用時就像這樣
fun(&i);
參考基本用法
底層裡面都是做指針的存取,使用方法怎麼區別可以這樣想像
參考就像一個不用輸入符號的指針
什麼意思呢,假設有一個指針為下
int i=0;
int* p=&i;
現在p也可以修改i
如果寫成參考就像這樣子
int i=0;
int& ali=i;
現在ali也可以修改i,現在操作ali就像在操作i
叫王小明的綽號 阿明
就像在叫王小明一樣。
放到函式可以省很多事情
void fun(int& p){
p = 1;
}
使用時就像這樣
int i=0;
fun(i);
現在你在函式內的操作以及呼叫函式時的操作,全部都不用加上符號上了,是不是更好用呢?
或許你會在學到參考後一股腦地全部換參考,但其實他們之間大概有細微的差異
指針
- 需要檢查有效性
- 可以指向Null表示無效,也可以隨時更換指向的目標
- 有指針的指針
參考
- 不需檢查有效永遠有效
- 不能換參考,且只能在宣告時給定目標
- 沒有參考的參考
彙整出來的兩條守則:
- 不想付出檢查成本就用參考
- 需要更動指向的目標物或初始化為無效,只能用指針
活用參考與指針
很多時候他們是可以互相通用的,這可能不好記憶,透過練習題更容易熟悉,詳見以下的範例
有一個函式
看起來有些繞口,直接看代碼會比較好理解
要可以做到以下的樣板功能
int i;
fun();
fun() += 10;
大致可以有以下四種做法,各字看一次,做一次應該10分鐘就可以入門參考與指針了
#include <iostream>
using namespace std;
int* fun1(int* i){
*i = 1;
return i;
}
int* fun2(int& i){
i = 2;
return &i;
}
int& fun3(int* i){
*i = 3;
return *i;
}
int& fun4(int& i){
i = 4;
return i;
}
int main() {
int i=0;
*fun1(&i) += 10;
cout << "i=" << i << endl;
*fun2(i) += 10;
cout << "i=" << i << endl;
fun3(&i) += 10;
cout << "i=" << i << endl;
fun4(i) += 10;
cout << "i=" << i << endl;
return 0;
}