# C++ 左值與右值
在 C++ 的任何運算式當中,都有包含所謂左值(lvalue)以及右值(rvalue),在解釋之前先看以下程式碼:
```cpp=
int x = 42069;
```
在這個範例中`42069` 是右值(專業術語是 literal constant)、變數 `x` 是左值,最直接的差別就是,右值我們沒有明確的定義其記憶體位置,而左邊的變數 `x` 是有記憶體位址的。
```cpp=
int* p = &x;
```
而在這邊的程式碼中,`&` 是一個取址運算元,它接收一個變數(左值)即可產生其變數的記憶體位址(右值),並最後 assgin 給指標 `p`,所以它也是一個左值,因為它也有自己的記憶體位置。
你不可能這樣寫:
```cpp=
int x;
666 = x; //error: lvalue required as left operand of assignment
int* p = &666; //error: lvalue required as unary '&' operand
```
### 左右值參考
```cpp=
// 左值參考
int a = 5;
int& b = a;
// 右值參考
int& c = 5; // error: cannot bind non-const lvaule refernce of type 'int&' to an rvalue of type 'int'
const int& d = 5; // OK
int&& e = 5; // OK
```
參考只能參考左值,這其實很合理因為右值本身就是暫時的值,它隨時都可能被釋放,而且也沒有具體的記憶體位址,你參考右值是很奇怪的。但是如果你多加個 `const` 的話,就可以參考右值了,看以下範例:
```cpp
void magic(int& x, int& y) {
x = x + 2;
y = x + y;
}
int main() {
int a = 2;
int b = 3;
magic(a, b);
// 錯誤:非常數參考的初始值必須是左值
// magic(5, 8);
return 0;
}
```
參考只能接受左值,如果要接收右值,就必須是 const 才能去參考右值,為甚麼呢?可以這樣思考:右值是程式臨時產生出來的值,不可以被修改,所以說必須加上修飾詞 const 才可以去參考右值。
#### 結論
* 左值:任何有記憶體位址的變數都是左值,包括不可修改的 const 變數。
* 右值:非左值即右值,通常也是運算式所產生**暫時**的值。
###### tags: `C++`