[轉] 左值和右值

來源:互聯網
上載者:User

標籤:

http://www.cnblogs.com/dejavu/archive/2012/09/02/2667640.html#commentform

<C/C++> 左值和右值, L-value和R-value

一直以為左值是可以出現在賦值運算式左邊(the left side of an assignment expression)的值,Left-value;右值即Right-value.

今天看到一個說法,覺得有點味道:

L-value中的L指的是Location,表示可定址. The "l" in lvalue can be thought of as location.
R-value中的R指的是Read,表示可讀. The "r" in rvalue can be thought of as "read" value.

 

為了尋找lvalue術語的出處,先是<The C Programming Language>中,Kernighan and Ritchie寫道:

"An object is a manipulatable region of storage; an lvalue is an expression referring to an object.

...

The name ‘lvalue‘ comes from the assignment expression E1 = E2 in which the left operand E1 must be an lvalue expression."

然後我又不畏艱險,硬著頭皮翻看C99標準和<The New C Standard>這本書,想從中尋找點蛛絲馬跡:

The name “lvalue” comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue.
Or left value of assignment. The right value being called the rvalue. This is translator writers’ terminology that the C Standard committee has adopted.

...

It is perhaps better considered as representing an object “locator value”.

...

What is sometimes called “rvalue” is in this International Standard described as the “value of an expression”.

似乎缺乏一個統一且明確的標準定義. 不過可以看出,左值原來定義的確跟賦值運算式左側有關,但更好的定義是"記憶體中,有特定位置(地址)的東西"或"指向一個確定對象的東西".

 

 

許多語言中,一個對象(object)只允許通過運算式(assignment)來修改.而C語言更靈活,它允許可以通過操作符(operator)來修改對象的值,而不僅僅是通過運算式(如++自增操作符).這就讓清楚地區分左值和右值的含義變的很重要,如

  int a = 10;  ++(a++); //error!

編譯器(gcc)會報錯:error: non-lvalue in increment (非左值自增)

如果能清楚的理解,左值(lvalue)是一個"擁有一個可以確定的地址(指向一個對象)"的標識符或運算式,而右值(rvalue)只是一個值,並不一定指向一個對象.那這個問題就簡單了:

(a++)運算式 是先將a的值做為整個運算式的值返回,再將a自增1.那麼,(a++)運算式的值並不指向一個對象(不擁有一個記憶體位址),因為它類似 

{
  int temp = a;  a = a+1;  return temp;
}

temp是臨時值(如某個寄存器),它並不指向一個對象(temp並沒有分配實際的地址).所以(a++)運算式不是左值!之後,++(a++)相當於對一個右值(非左值)進行自增(++temp)當然是不合理的!

但是,注意!尾碼增量運算式傳回值一定是個非左值,但首碼增量運算式呢? 首碼增量運算式的傳回值對於C和C++是不同的:

  int a = 10;  (++a)++; //C++ ok,C error!  ++(++a); //C++ ok,C error!
  (a+=1)+=1; //C++ ok,C error!

對於上述代碼,gcc是報錯,而g++是通過!

原因在於,C中,首碼增量運算式(prefix increment)返回的是非左值(C標準6.5.3.1 The expression ++E is equivalent to (E+=1).並且在6.5.16 An assignment expression has the value of the left operand after the assignment, but is not an lvalue. )(這也說明了C語言中(a=1)=2,這樣的連用是錯誤的!)

但在C++中,已經明確定義首碼增量運算式傳回值為一個左值(C++標準5.3.2.1 The value is the newvalue of the operand; it is an lvalue.).所以對(++a)再做一次前++或後++沒問題.(而且賦值運算式返回也是左值,所以(a=1)=2連用沒問題)

 

另外,

在C中,一個運算式要麼是左值要麼是非左值,沒有右值說法,直到C++時,右值才被正名.

左值不一定是可以修改的值,如一個const對象是左值,但不能被修改(non-modifiable lvalue).

右值可以是左值和非左值.

 

 

其他參考:

http://www.cppblog.com/cc/archive/2012/06/27/7619.html

http://eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues

http://stackoverflow.com/questions/3572753/difference-between-cs-expression-and-cs-expression

http://homepage.ntlworld.com/dmjones/cbook1_2.pdf

[轉] 左值和右值

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.