理解C和C++中的左值和右值

https://blog.csdn.net/xuwqiang1994/article/details/79924310 理解C和C++中的左值和右值

https://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/ Understanding lvalues and rvalues in C and C++

C/C++編程中不是經常出現術語(左值)和rvalue(右值),但是一旦出現,它們的語意就不是特別清晰。最經常看到它們的地方是在編譯錯誤和警告信息中。比如,用gcc編譯下面的程序:

int foo() { return 2; }

int main()
{
    foo() = 2;
    return 0;
}

你會得到:

test.c: In function 'main':
test.c:8:5: error: lvalue required as left operand of assignment

是的,這段代碼不是合法的並且不是你想寫的,但是那個錯誤信息提到了lvalue,一個通常在C/C++教程中不能找到的術語。另一個例子就是用g++編譯下面的代碼:

int& foo()
{
    return 2;
}

現在那個錯誤爲:

testcpp.cpp: Infunction 'int& foo()':
testcpp.cpp:5:12: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

再次,那個錯誤信息提到了難以理解的rvalue。那麼在C/C++中lvalue和rvalue意味着什麼?這是我打算 在這篇文字中探討的。

一個簡單定義

這個部分先給出lvalue和rvalue的一個簡單定義。文章下面將會詳細描述。 
lvalue(locator value)代表一個在內存中佔有確定位置的對象(換句話說就是有一個地址)。 
rvalue通過排他性來定義,每個表達式不是lvalue就是rvalue。因此從上面的lvalue的定義,rvalue是在不在內存中佔有確定位置的表達式。

基本例子

上面的術語定義可能不是特別清楚,所以馬上看一些簡單例子是重要的。 
假設我們定義了一個整形變量並且給它賦值:

int var;
var = 4;

賦值運算符要求一個lvalue作爲它的左操作數,當然var是一個左值,因爲它是一個佔確定內存空間的對象。另一方面,下面的代碼是無效的:

4 = var;        //ERROR!
(var + 10) = 4; //ERROR!

常量4和表達式var+1都不是lvalue(它們是rvalue)。它們不是lvalue,因爲都是表達式的臨時結果,沒有確定的內存空間(換句話說,它們只是計算的週期駐留在臨時的寄存器中)。因此給它們賦值沒有語意-這裏沒有地方給它們賦值。 
因此現在應該清楚了第一個代碼片段的錯誤信息。foo返回一個臨時的rvalue。嘗試給它賦值,foo()=2,是一個錯誤;編譯器期待在賦值運算符的左部分看到一個lvalue。 
不是所有的對函數調用結果賦值都是無效的。比如,C++的引用(reference)讓這成爲可能:

int globalvar = 20;

int& foo()
{
    return globalvar;
}

int main()
{
    foo() = 10;
    return 0;
}

這裏foo返回一個引用,這是一個左值,所以它可以被賦值。實際上,C++從函數中返回左值的能力對於實現一些重載運算符時很重要的。一個普遍的例子是在類中爲實現某種查找訪問而重載中括號運算符 []。std::map可以這樣做。

std::map<int, float> mymap;
mymap[10]=5.6;

給 mymap[10] 賦值是合法的因爲非const的重載運算符 std::map::operator[] 返回一個可以被賦值的引用。 

可修改的左值

開始在C語言中左值定義,它字面上意味着“合適作爲賦值的左邊部分”。然而,之後C標準中添加了const關鍵字後,這個定義不得不重新定義。畢竟:

const int a = 10; //‘a’是一個左值
a = 10;           //但是它不能被賦值

因此需要更深層次的重定義。不是所有的左值都能被賦值。這些可以稱爲可修改的左值。正式的,C99標準定義可修改左值爲:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章