C 學習之引用 左值右值

2021-09-29 19:34:53 字數 3498 閱讀 8766

引用定義

1)引用即別名,就是某個變數的別名,對引用別名的操作與對變數本身完全相同.

2)語法規則

型別 & 引用名 = 變數名;

注:引用在定義時必須初始化,初始化以後繫結的目標不能再改變。

注:引用的型別與繫結的目標變數型別要相同。

常引用1)定義引用時加const修飾,即為常引用,不能通過常引用修改引用的目標。

const 型別 & 引用名 = 變數名;

型別 const & 引用名 = 變數名;

以上兩個通式,在有些情況下並不同。比如 const char * &rp;並不是應用型別為char *的常引用,而是引用型別為const char *的普通引用。若是想把const char * &rp宣告為常引用,則應該採用第二個通式的方法,const char * const &rp;

eg:int a = 10;

const int& b = a;//b是a的常引用

b++;//error

a++;//ok

2)普通引用也可以叫做左值引用,只能引用左值;而常引用也可以叫做萬能引用,既可以引用左值,也可以引用右值。

引用型函式引數

1)可以將引用用於函式的引數,這時形參將是實參的別名,可以通過形參直接修改實參變數,同時還可以避免引數值傳遞的過程,減小函式呼叫開銷,提高**執行效率。

2)引用型引數有可能意外的修改實參,如果不希望修改實參本身,可以將引數定義為常引用,提高傳參效率的同時還可以接收常量型的實參.

引用作為引數

#include

using

namespace std;

/*void swap1(int* x,int* y)*/

void

swap2

(int

& x,

int& y)

void

swap3

(const

char

*& x,

const

char

*& y )

intmain

(void

)

#include

using

namespace std;

struct teacher

;void

print

(const teacher*

&t)int

main

(void);

const teacher *p =

&wangjl;

print

(p);

return0;

}

引用型函式返回值

1)可以將函式的返回型別宣告為引用,這時函式的返回結果就是return後面資料的別名,可以避免函式返回值所帶來的的記憶體開銷,提高**執行效率.

2)如果函式返回結果是乙個普通(左值)引用,那麼該函式呼叫表示式結果就也是左值.

注:不要從函式中返回區域性變數的引用,因為所引用的記憶體會在函式返回以後被釋放,使用非常危險!但是可以從函式中返回成員變數、全域性變數、靜態變數的引用。

#include

using

namespace std;

struct a

int&

func2

(void)}

;int

main

(void);

cout << a.data << endl;

//100

= 200

a.func()

=200

;//ok

cout << a.data << endl;

//200

return0;

}

引用和指標

1)從c語言角度看引用的實現,其本質就是指標,但是c++開發中推薦使用引用而不是指標.

int i = 100;

int* const pi = &i;

int& ri = i;

*pi <==> ri

2)指標可以不做初始化,其指向的目標可以修改(指標常量除外);而引用必須初始化,一旦初始化其繫結目標的不能再修改.

int a,b;

int* p;//ok

p = &a;//p指向a

p = &b;//p指向b

int& r;//error

int& r = a;//r引用a,r就是a別名

r = b;//ok,不是修改引用目標,僅是賦值操作

&nbps;

3)可以定義指標的指標(二級指標),但是不能定義引用的指標

int a;

int* p = &a;

int** pp = &p;//ok,二級指標

int& r = a;

int&* pr = &r;//error,引用的指標

int* pr = &r;//ok,但僅是普通指標

4)可以定義指標的引用(指標變數的別名),但是不能定義引用的引用

int a;

int* p = &a;

int* & rp = p;//ok,指標的引用

int& r = a;

int& & rr = r;//error,引用的引用

int& rr = r;//ok,但僅是普通的引用

5)可以定義指標陣列,不能定義引用陣列,但可以定義陣列引用(陣列的別名)

int a=10,b=20,c=30;

int* parr[3]=;//ok,指標陣列

int& rarr[3]=;//error,引用陣列,推理一下,很容易得出不合法:陣列中,&arr[0],&arr[1],

&arr[2]這三個位址,一定是連續的,但是如果是引用陣列,&arr[0],&arr[1],&arr[2]等價於&a, &b, &c,這三個位址,不能保證是連續的。

int arr[3] = ;

int (&rarr)[3] = arr;//陣列引用

6)和函式指標一樣,可以定義函式引用(函式的別名),其語法特性和函式指標一致.

void func(int a,int b){}

int main(void)

左值和右值

左值(lvalue):可以放在賦值操作符左側,可以被修改.

–》普通變數

–》字首++、--

–》賦值表示式結果

右值(rvalue):只能放在賦值操作符右側,不可以被修改

–》字面值常量

–》型別轉換結果的臨時變數

–》加法(大多數、後++、–)表示式結果的臨時變數

–》函式中返回的臨時變數

注:const int a = 100; 可以稱a為不可修改左值

#include

using

namespace std;

intfunc

(void

)int

main

(void

)

c 左值 右值 右值引用 左值引用

c 裡一切值必須屬於左值 右值兩者之一。左值 一切變數 包括用const修飾的變數 物件 包括引用都屬於左值 右值 一切字面值 可以是巨集 臨時無名物件 函式返回值 表示式 如a n 說明一下 函式返回值,返回的是某乙個型別的值,並不是返回變數。左值並不是說能放在 左邊的值就是左值 雖然用const...

c 左值 右值 左值引用 右值引用

在c語言中,左值認為是賦值語句的左側,右值認為是賦值語句的右側。在c 中,意義稍有不同。c 中,每乙個表示式會產生乙個左值或者右值,相應的,該表示式也就被稱作 左值表示式 右值表示式 乙個左值表示式的求值結果是乙個物件或者是乙個函式。左值可以當右值使用,而右值不能當左值使用。c prime 中這麼簡...

C 左值 右值 左值引用 右值引用

就變數而言,對於一些變數,我們只會讀取並使用它們的值,而不會改變他們的值 唯讀 對於其餘的變數,我們既會讀取它們的值,有的時候還會改變它們的值 讀寫 這是很常見的。在c 中,前一種變數稱為右值,後一種變數稱為左值,例如 int a 1 a是左值,1是右值稍稍不同的一點是,在c 中,乙個變數是左值還是...