左值&右值


一、引子

我們所謂的左值、右值,正確的說法應該是左值表達式、右值表達式。

因為C++的表達式不是左值就是右值。

在C中,左值指的是既能夠出現在等號左邊也能出現在等號右邊的表達式,右值指的則是只能出現在等號右邊的表達式。

而在C++中,二者的區別就不是這么簡單了。

 

二、關鍵點

【官方定義】

  1. 一個左值表達式的求值結果是一個對象或者一個函數,而某些右值表達式的求值結果也是對象;
  2. 以常量對象為代表的某些左值並不能作為賦值語句的左側運算對象。
  • 歸納:當一個對象被用作右值的時候,用的是對象的值(內容);而被用作左值的時候,用的是對象的身份(在內存中的位置)。

【解讀定義】

  解讀第一句:既然左值和右值都可以是對象,那怎么區分一個對象是左值還是右值呢?

  • 左值:能用“取地址&”運算符獲得對象的內存地址
  • 右值:不能用“取地址&”運算符獲得對象的內存地址
  • 特例:因為可以用&取得字符串字面值常量的地址,所以它是一個左值;而其他的字面值常量則不可用&取地址,所以它們是右值

我們知道對象是一塊空間,那么有哪些對象以及為什么不能用&取地址呢?

  • 對於臨時對象,它可以存儲於寄存器中,所以沒辦法用“取地址&”運算符;
  • 對於(非字符串常量,它可能被編碼到機器指令的“立即數”中,所以沒辦法用“取地址&”運算符。

 

  解讀第二句:字符串字面值常量確實不能放在等號左邊啊,沒錯啊!

  解讀歸納:所以啊,左值看地址,右值看內容。

【補充】

#include <iostream>

using namespace std;

int& func(int &a)
{
	return a;			// 不能返回局部對象的引用 
}

int main()
{
	int a = 10;
	func(a) = 100;			// 返回非常量引用的函數可以當作左值使用 
	cout << a << endl;		// 輸出100 
	return 0;
}

 

三、為什么要區分左值右值

  • 不同的運算符對運算對象的要求各不相同,有的需要左值運算對象、有的需要右值運算對象;返回值也有差異,有的得到左值結果、有的得到右值結果。

  舉例:使用關鍵字decltype的時候,其表達式的求值結果若是左值,decltype作用於該表達式(不能是變量)得到一個引用類型。例如,p的類型是int *,因為解引用運算符生成左值,所以decltype(*p)的結果是int &。而另一方面,因為取地址運算符生成右值,所以decltype(&p)的結果是int **,即結果是一個指向整型指針的指針。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM