C 的指標與引用(附雙指標問題)

2021-10-01 03:57:47 字數 3566 閱讀 6866

引用(reference)就是給物件起了另外乙個名字,引用建立時需要給予初始化,然後此「別名」與原變數用法一致。

int ival = 1024;

int &refval = ival; //refval指向ival(是ival的另乙個名字)

int &refval2; //報錯:引用必須被初始化

以上ival為原變數,而refval為它的別名(注意要立即初始化)。

然而定義引用時,程式把引用和它的初始值繫結在一起,而不是將初始值拷貝給引用

一旦初始化完成,引用將和它的初始值物件一直繫結在一起

因為無法令引用重新繫結到另外乙個物件,因此引用必須被初始化。

引用即別名

引用並非物件,而知識乙個已經存在的物件的另乙個別名。

定義乙個引用後,對「別名」的所有操作都是與原物件繫結在一起的。

refval=2; //把2賦值給refval指向的物件,即ival

int ii=refval; //其實與ii=ival 一樣的效果

在引用定義時注意資料型別的匹配

int i=1,i2=2;

int &r=i; r2=i2; //這裡r是乙個引用與i繫結在一起,r2是int(不繫結)。

int & refval2=10 ;//錯誤,引用型別的初始化必須是乙個物件

double dval=3.14;

int &r3=dval; //錯誤,因為引用的初始值必須也是「int」

指標是指向另一種型別的復合型別,和引用類似,實現了對其他物件的間接訪問,然而引用和指標有很多不同點:

1.指標本身就是乙個物件,允許對指標賦值和拷貝,而且在其生命週期內它可以先後指向幾個不同的物件;引用並非物件,他只是為乙個已經存在的物件起的另乙個名字,一旦初始化完成,引用將和它的初始值物件一直繫結在一起(簡單來說就是:指標可以修改指向的物件。而引用被繫結在原來的物件上了。)

2.指標無需在定義時賦初始值,和其他內建型別一樣,在塊作用域內定義的指標如果沒有初始化,也將擁有乙個不確定的值;因為無法令引用重新繫結到另外乙個物件,因此引用必須被初始化

獲取物件的位址

指標存放某個物件的位址,想要獲取該位址就要用「取位址符號」(操作符&)

int val=1;

int *p=&val; //p的定義為乙個指向int 的指標,初始化p令其指向名為val的int 物件。

另外,指標的型別也要與所指向的型別相互匹配。

double dval;

double *pd2 = pd; //正確:初始值是指向double物件的指標

int *pi = pd;       //錯誤:指標pi的型別和pd的型別不匹配
如果指標指向了乙個物件,允許使用解引用符(操作符*)來訪問該物件

int ival = 42;

int *p = &ival; //p存放著變數ival的位址,或者說p是指向變數ival的指標

cout<< *p //由符號*得到指標p所指向的物件,輸出42

對指標解引用會得出所指的物件,因此如果給解引用的結果賦值,實際上也就是給指標所指的物件賦值

*p = 0;

cout<< *p;

指標和引用都能提供對其他物件的間接訪問,然而在具體實現細節上二者有很大不同,其中最重要的一點就是引用並非都是乙個物件,一旦定義了引用,就無法再令其繫結到其他物件,之後每次使用這個引用都是在訪問它最初繫結的物件。

指標的和它存放的位址之間就沒有這種現實,和其他變數(只要不是引用)一樣,給指標賦值就是令他存放乙個新的位址,從而指向乙個新的物件。

int i = 42;

int *pi = 0; //pi被初始化,但沒有指向任何物件

int *pi2 = &i; //pi2被初始化,存有i的位址

int *pi3; //如果pi3定義於塊內,pi3的值無法確定

pi3 = pi2; //pi3和pi2指向同乙個物件

pi2 = 0; //現在pi2不指向任何物件了 ****

注意以上pi2=0的操作將乙個指標指向空。

有的時候想搞清楚一條賦值語句到底是改變了指標的值還是指標所之鄉的物件的值不太容易,最好的辦法就是記住賦值永遠改變的是等號左側的物件:

pi = &ival  //pi的值被改變,現在pi指向了ival
*pi = 0;    //ival的值被改變,指標pi並沒有改變
則*pi(也就是指標pi指向的那個物件)發生改變

指標是記憶體中的物件,像其他物件一樣也有自己的位址,因此允許把指標的位址再存放到另乙個指標當中

通過 * 的個數可以區分指標的級別,** 是指向指標的指標, *** 表示指向指標的指標的指標:

int ival = 1024;

int *pi = &ival; //pi指向乙個int型的整數

int **ppi = π //ppi指向乙個int型的指標

解引用int型指標會得到乙個int型的數,同樣,解引用指向指標的指標會得到乙個指標,此時為了訪問最原始的物件需要對指標的指標做兩次解引用,以下程式以三種不同的方式輸出了ival的值。

cout指向指標的引用

引用本身不是乙個物件,因此不能定義指向引用的指標,但指標是物件,所以存在對指標的引用。

int i = 42;

int *p; //p是乙個int型指標

int *&r = p; //r是乙個對指標p的引用 //相當於給p指標起了個別名。(繫結)

r = &i; //r引用了乙個指標,因此給r賦值&i就是令p指向i

*r = 0; //解引用r得到i,也就是p指向的物件,將i的值改為0;

** 相當於給p指標起了個別名 **

(1)將指標作為引數傳遞時,其實是將指標複製了乙份,(自函式裡做修改只是修改的指標的copy,而不是指標本身),也就是說在函式裡對指標的操作都不會影響「實參」的值。

int m_value = 1;

void func(int *p)

int main(int argc, char *ar**)

int main(int argc, char *ar**)

{int n = 2;

int *pn = &n;

cout << *pn << endl;

func(&pn);

cout << *pn 輸出為:2

5

c 中 指標的指標 與 指標的引用

我的生活,我的點點滴滴!今天在看一些c 開源 時,無意間看到下面這段 突然發覺看起好陌生,完全不懂這樣用的意義是什麼呀?void director popscene const std function callback else auto callback scene scene director...

C 指標與引用

include 引用傳遞 int add1 int x,int y 指標傳遞 int add2 int x,int y 值傳遞 int add3 int x,int y void main int a 1 int b a 引用,表示b的引用指向了a 定義引用 開頭 必須賦初值 引用變數不占用記憶體 ...

C 指標與引用

從函式引數傳遞說起 int addition int x,int y int main void duplicate int a,int b int main 按值傳遞,顧名思義,函式形參僅僅得到變數傳來的值,函式的任何操作並不對變數產生任何變化 按位址傳遞,他的定義方式與按值傳遞不一樣 注意其在m...