青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

CG@CPPBLOG

/*=========================================*/
隨筆 - 76, 文章 - 39, 評(píng)論 - 137, 引用 - 0
數(shù)據(jù)加載中……

數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換

1、左值和右值

表達(dá)式的左值是它的地址,右值是該地址所存儲(chǔ)的內(nèi)容。比如下面代碼:

= x + 1;

這兩個(gè) x 有什么不同呢?第一個(gè)表達(dá)式 x 表示的是它的左值,而第二個(gè)表達(dá)式 x 表示的是它的右值。一個(gè)表達(dá)式能不能放到 賦值操作符 的左邊,取決于這個(gè)表達(dá)式有沒有左值,同樣的,一個(gè)表達(dá)式能不能放到 賦值操作符 的右邊,取決于它有沒有右值。

一個(gè)表達(dá)式究竟是取左值還是右值,需要結(jié)合上下文,大多數(shù)表達(dá)式同時(shí)具有左值和右值。

2、指針類型、數(shù)組類型和函數(shù)類型

C++是一種強(qiáng)類型語言,類型在程序中的非常重要,每個(gè)變量和表達(dá)式都有一個(gè)確定的類型,類型匹配和類型轉(zhuǎn)換也是C++語言中的重要部分。除了內(nèi)建的一些類型和用戶自定義類型(包括類類型),下面重點(diǎn)說一下指針類型、數(shù)組類型和函數(shù)類型。

T* a; 

聲明一個(gè)變量a,它的類型是T*(指向類型T的指針類型)。

T arr[100];

聲明一個(gè)變量arr,它的類型是 T[100](一維,維長(zhǎng)100,元素類型為T的數(shù)組)。

T f(void){/*  . . . */}

聲明一個(gè)變量f,它的類型是 T(void)(返回值為T,參數(shù)為void的函數(shù))

特別要強(qiáng)調(diào)的是,arr 的類型和 f 的類型都不是指針。這兩個(gè)類型的表達(dá)式?jīng)]有右值。

3、&、* 操作符

* 操作符應(yīng)用與左值表達(dá)式,以表達(dá)式左值為地址,取出表達(dá)式類型的值,作為右值返回。
& 操作符應(yīng)用于左值表達(dá)式,返回表達(dá)式的左值。

注意*、& 操作符的操作數(shù)必須擁有左值。

4、左值到右值的轉(zhuǎn)換

C++ 標(biāo)準(zhǔn)轉(zhuǎn)換包含 左值到右值的轉(zhuǎn)換。因?yàn)閿?shù)組類型和函數(shù)類型的表達(dá)式?jīng)]有右值,所以特別這里要說明數(shù)組類型和函數(shù)類型到右值的轉(zhuǎn)換。比如上文所說 arr ,當(dāng)它作為賦值操作符的操作數(shù)時(shí),它需要轉(zhuǎn)換為 T* 類型的指針(注意類型是指針!?。?,其值等于第一個(gè)元素的地址。而上文中所說的 f,當(dāng)它作為賦值操作符的操作數(shù)時(shí),它需要轉(zhuǎn)換為 T(*)(void) 的指針(注意類型是指針?。。?,它指向f的地址。

5、對(duì)數(shù)組類型或者函數(shù)類型施加&、*操作符

&arr、 *arr、 &f、 *f 這些表達(dá)式都是什么呢?打開RTTI,在VC里運(yùn)行下面代碼:

 1 #include "stdafx.h"
 2 #include <iostream>
 3 using namespace std;
 4 
 5 int func()
 6 {
 7         int i = 2;
 8         return i;
 9 }
10 
11 int _tmain(int argc, _TCHAR* argv[])
12 {
13         int arr[100= {0,1,2,3};
14 
15         cout<<typeid(func).name()<<endl;
16         cout<<typeid(*func).name()<<endl;
17         cout<<typeid(&func).name()<<endl;
18         cout<<endl;
19         cout<<typeid(arr).name()<<endl;
20         cout<<typeid(*arr).name()<<endl;
21         cout<<typeid(&arr).name()<<endl;
22         cout<<typeid(int*).name()<<endl;        
23 
24         getchar();
25         return 0;
26 }

運(yùn)行結(jié)果如下:

int __cdecl(void)
int __cdecl(void)
int (__cdecl*)(void)

int 
[100]
int
int (*)
[100]
int *

可以看出 *func 和 func 類型相同,是函數(shù)類型,而&func 是指向函數(shù)的指針。arr 是數(shù)組類型,*arr 是 T 類型, &arr 是 指向數(shù)組的指針(這個(gè)比較費(fèi)解)

因?yàn)?func 和 func 是等價(jià)的,所以可以這樣調(diào)用 func:

(***********************func)();

如果要用 &func,必須這樣(注意第一個(gè)一定是 *):

(*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&func)();

至于 arr、*arr、&arr 因?yàn)轭愋筒煌?,不可混用,?dāng)然用來 memset 的話,表達(dá)式 arr 和 &arr 的值都為第一個(gè)元素的地址,最終都被轉(zhuǎn)換為 void* 。




posted on 2008-04-07 22:50 cuigang 閱讀(4532) 評(píng)論(28)  編輯 收藏 引用 所屬分類: C/C++

評(píng)論

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

幾個(gè)錯(cuò)誤:
左值:返回一個(gè)可修改對(duì)象的表達(dá)式稱為左值
右值:返回一個(gè)不可修改對(duì)象的表達(dá)式稱為右值
*操作符返回的對(duì)象可能是左值也可能是右值
&操作符可用于左值和右值
*操作符的操作數(shù)可以是右值(請(qǐng)參考“映射設(shè)備寄存器到內(nèi)存”http://blog.chinaunix.net/u/12783/showart_385250.html
arr是T [100],那么&arr就是T (*)[100],沒什么費(fèi)解的
2008-04-08 10:27 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

給樓上的糾兩個(gè)錯(cuò):

“左值:返回一個(gè)可修改對(duì)象的表達(dá)式稱為左值”

左值未必都是可修改的,例如數(shù)組名就是不可修改的左值,可參見Expert C Programming 4.3.1

“右值:返回一個(gè)不可修改對(duì)象的表達(dá)式稱為右值”

右值未必都是不可修改的;在C++中,built-in的右值總是不可修改的,但是對(duì)于user defined type 的右值,在某些情況下是允許被修改;例如對(duì)于函數(shù)返回的臨時(shí)對(duì)象,調(diào)用non-const member function是合法的

2008-04-08 18:09 | 嘯天豬

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@raof01

1、我并非說我的左值右值描述是定義,但是你的依靠是否可修改的判斷卻反而是錯(cuò)的,一個(gè)const變量x,表達(dá)式 x 仍然有右值,但是不代表 x 可修改。關(guān)于左值和右值,ISO C++ 98版標(biāo)準(zhǔn)這樣說:

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances.

而《C++ primer》4th 這樣說:

存儲(chǔ)數(shù)據(jù)值的那塊內(nèi)存的地址,它有時(shí)被稱為變量的左值lvalue,讀作ell-value,我們也可認(rèn)為左值的意思是位置值(location value)。

左值代表了一個(gè)可被程序?qū)ぶ返膶?duì)象,可以從該對(duì)象讀取一個(gè)值,除非該對(duì)象被聲明為const,否則它的值也可以被修改。相對(duì)來說,右值只是一個(gè)表達(dá)式,它表示了一個(gè)值,或一個(gè)引用了臨時(shí)對(duì)象的表達(dá)式,用戶不能尋址該對(duì)象,也不能改變它的值。

2、我承認(rèn)對(duì)于 * 操作符用于左值的描述有問題,應(yīng)該說 解引用操作符 用于指針類型,但 & 操作符的確只能應(yīng)用于有左值的表達(dá)式,看C++ 標(biāo)準(zhǔn)這樣說:

The result of the unary & operator is a pointer to its operand. The operand shall be and lvalue or a qualified-id.

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

至于你鏈接的文章,請(qǐng)恕我未能洞悉,不知里面哪里提到 解引用操作符可以用于右值,或者隱含此意味。

雖然標(biāo)準(zhǔn)中沒有說 解引用操作符 到底是用在左值還是右值表達(dá)式上,但是間接尋址(indirection)反而說明了你的觀點(diǎn),它是將指針變量的右值作為地址來訪問指向物,類似的有
‘.’,‘->’運(yùn)算符。

3、我說指向數(shù)組的指針費(fèi)解,不是說我不理解,只是說大多數(shù)人實(shí)際中難以見到,不好理解,如果你可以理解,你可以說說它和多維數(shù)組 arr[][] 的 指針 arr[2] 有什么區(qū)別。

2008-04-08 21:44 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

哪個(gè)是對(duì)的,不要誤解人
2008-04-09 16:14 | 我愛你

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
想太多反而會(huì)把問題搞復(fù)雜。

C++ Primer 4th: ch2.3.1
左值可以出現(xiàn)在賦值語句(等號(hào))的左邊或右邊。
右值只能出現(xiàn)在賦值(等號(hào))的右邊,不能出現(xiàn)在賦值語句的左邊。

無論在哪本C/C++書籍中,對(duì)左值、右值的描述最基本的就是以上兩句話。其他關(guān)于左值、右值話題的討論、延伸都脫離不了以上兩句話。

至于左值是否是地址,右值是否為數(shù)據(jù)本身——
對(duì)于 x = x + 1;
假設(shè) x 為 int 類型,則編譯后匯編語句應(yīng)該為:
mov eax, DWORD PTR x_$[ebp]
inc eax
mov DWORD PTR x_$[ebp], eax

很明顯 ebp 是地址而不是具體數(shù)據(jù),而右邊的 x 是作為右值出現(xiàn)的。也就是說除非字面值表達(dá)式(1, 'a'等),其他表達(dá)式不管左值右值,編譯器都有可能以地址處理。

至于右值是否能被尋址——
const int iX = 100;
cout << &iX << endl;
是合法的。從加上const關(guān)鍵字那一刻起,iX就只能作為右值出現(xiàn)。
試圖用強(qiáng)悍的指針來修改iX的值:
int* pX = &iX; //無法從“const int *”轉(zhuǎn)換為“int *”
*pX = 101;

不是糾錯(cuò),只是討論。
2008-04-09 23:20 | ww

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@嘯天豬
看起來比較抽象,能詳細(xì)舉例說明嗎?
2008-04-09 23:22 | iwong

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

我覺得不嚴(yán)謹(jǐn)?shù)睦斫猓笾稻褪浅绦騿T有權(quán)知道其地址的object;右值則是雖然知道這個(gè)object的存在,但是它的地址對(duì)程序員是無意義的。

至于左值/右值的準(zhǔn)確含義,還是參考標(biāo)準(zhǔn)吧;書畢竟是面向大眾的,通常不會(huì)像標(biāo)準(zhǔn)那樣給出完整、嚴(yán)謹(jǐn)、天書般的定義

@iwong

建議參考水木社區(qū)Cplusplus版的FAQ,解釋的很詳細(xì)

http://www.newsmth.net/bbscon.php?bid=335&id=179727

2008-04-10 00:38 | 嘯天豬

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@嘯天豬

你提供的鏈接解釋很充分,希望你自己也能自己看一下
2008-04-10 22:08 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@ww

嘯天豬的鏈接你看一下,&只能對(duì)左值表達(dá)式取址。我就不用再?gòu)U話了。
2008-04-10 22:20 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

向前輩致敬~
2008-04-11 22:58 | elent

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@嘯天豬
@cuigang

http://www.newsmth.net/bbscon.php?bid=335&id=179727
這篇文章把能夠用&x取得地址的x都視為左值,于是"Hello world!"這樣的字面值字符串和const常量都成為了左值。

可是:
const int i = 1;
i++;
"Hello world!"++;

在VC中編譯時(shí)對(duì)后兩行都會(huì)提示“++需要左值”。

如果相信這篇文章的話,那么這個(gè)結(jié)果是很令人費(fèi)解的。
2008-04-12 14:30 | iwong

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@iwong

你需要區(qū)分概念:左值分為兩類──可修改的左值和不可修改的左值。通常提到的左值都指的是前者──例如上面VC的提示



3.10 Lvalues and rvalues [basic.lval]

Every expression is either an lvalue or an rvalue.

If an expression can be used to modify the object to which it refers, the expression is called modifiable. A
program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is ill-formed.


我自己的理解:

rvalue意味著object的地址對(duì)程序員無意義──它的地址對(duì)編譯器有用,對(duì)程序員是沒用的

modifibale lvalue 意味著object的地址對(duì)程序員有意義,且可以用這個(gè)lvalue對(duì)object進(jìn)行修改

unmodifiable lvalue意味著object的地址對(duì)程序員有意義,但若通過這個(gè)lvalue對(duì)object進(jìn)行修改,也是無意義的(編譯報(bào)錯(cuò)或者運(yùn)行出錯(cuò))

i++出錯(cuò)的原因在于”const int i=1“中的i并不是可修改的左值

而標(biāo)準(zhǔn)規(guī)定,前綴/后綴增量的操作對(duì)象必須是modifiable lvalue

”5.2.6 Increment and decrement [expr.post.incr]
1 The value obtained by applying a postfix ++ is the value that the operand had before applying the operator.The operand shall be a modifiable lvalue.

5.3.2 Increment and decrement [expr.pre.incr]
1 The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. “


”Hello world!“++出錯(cuò)的原因在于這里發(fā)生了string literal 到 pointer的自動(dòng)轉(zhuǎn)換,”hello wolrd“轉(zhuǎn)換為類型為char *的rvalue。對(duì)于一個(gè)built-in type的rvalue執(zhí)行增量操作,肯定是不合法的


4.2 Array-to-pointer conversion

2 A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to char”;
2008-04-12 17:00 | 嘯天豬

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@嘯天豬
"左值未必都是可修改的,例如數(shù)組名就是不可修改的左值":數(shù)組名不是左值。注意我說的話:*返回*可修改對(duì)象……數(shù)組名是一個(gè)* const,不是左值。簡(jiǎn)言之:int a[10];可以有int * p = a; a[10] = x;但不能有a = p;
“但是對(duì)于user defined type 的右值,在某些情況下是允許被修改;例如對(duì)于函數(shù)返回的臨時(shí)對(duì)象,調(diào)用non-const member function是合法的”:臨時(shí)對(duì)象不一定是右值。*返回*不可修改對(duì)象……
討論就是討論,沒有罵人的,看來大家都是好人。哈哈,這里不錯(cuò)。
2008-04-17 13:07 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

sorry,上面有個(gè)錯(cuò)誤:a[10] = x; 改為 a[0] = x;
2008-04-17 13:08 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
請(qǐng)注意我的用詞(有咬文嚼字之嫌,見諒):返回、對(duì)象、表達(dá)式。對(duì)象包括很多:指針、字面常量、臨時(shí)對(duì)象……我認(rèn)為我們之間的分歧在于你把我說的對(duì)象細(xì)分了。

“但 & 操作符的確只能應(yīng)用于有左值的表達(dá)式”——你是對(duì)的,我的錯(cuò)誤。

“至于你鏈接的文章,請(qǐng)恕我未能洞悉,不知里面哪里提到 解引用操作符可以用于右值,或者隱含此意味?!薄獙?shí)際我想說明的就是“但是間接尋址(indirection)反而說明了你的觀點(diǎn),它是將指針變量的右值作為地址來訪問指向物,類似的有‘.’,‘->’運(yùn)算符?!保?yàn)槲野阎羔槷?dāng)作對(duì)象的一種。

“我說指向數(shù)組的指針費(fèi)解,不是說我不理解,只是說大多數(shù)人實(shí)際中難以見到,不好理解,如果你可以理解,你可以說說它和多維數(shù)組 arr[][] 的 指針 arr[2] 有什么區(qū)別。”我相信你理解了,否則也不會(huì)寫出這么有深度的文章。T arr[]中arr的類型是T[],&arr的類型就是T(*)[];但是,T arr[][]中arr的類型是T * arr[],&arr的類型是T**——最后這點(diǎn)是因?yàn)镃中二位數(shù)組是線性存儲(chǔ)的,不是我們所理解的二維矩陣。

——向你的認(rèn)真致敬!呵呵
2008-04-17 13:42 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@raof01

跟你先前的評(píng)論比較,想必你最近也深入研究了這個(gè)問題,雖然言語之中仍然為自己辯護(hù),不過大家觀點(diǎn)畢竟更加接近了,其實(shí)我們對(duì)于這個(gè)問題的理解可能都有少許偏差,但討論之后一定更加接近正確了。

謝謝你捧場(chǎng)。
2008-04-17 13:54 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
你舉的例子x=x+1;其中x無論是在左邊還是右邊都是左值,表達(dá)式"x+1"才是右值。
2008-04-17 14:17 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@raof01

你要說 x + 1 中的 x 是左值, 我真的很無奈。
2008-04-17 23:18 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
你別無奈啊,給個(gè)理由先。
我的依據(jù)是:左/右值指的是表達(dá)式。單純就x這個(gè)表達(dá)式來說,它是個(gè)左值,無論在=左邊還是右邊。
2008-04-18 10:05 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
我始終不同意這句話:“表達(dá)式的左值是它的地址,右值是該地址所存儲(chǔ)的內(nèi)容?!币?yàn)闊o論地址還是內(nèi)容,都是對(duì)象。而且按照你這句話,x = x + 1;第一個(gè)x是個(gè)地址,第二個(gè)x是其內(nèi)容,假設(shè)x是T類型,那么上述表達(dá)式就應(yīng)該理解為=左邊是個(gè)地址,也就是T*,對(duì)吧?矛盾就來了,你把T類型的值賦給了T*。
“雖然言語之中仍然為自己辯護(hù),不過大家觀點(diǎn)畢竟更加接近了”——?jiǎng)偛庞肿屑?xì)看了一遍你的文章,我堅(jiān)持我第一個(gè)評(píng)論里的觀點(diǎn),除了“&操作符能作用于左值和右值”這個(gè)錯(cuò)誤。
我認(rèn)為:因?yàn)槟愕牡谝粋€(gè)觀點(diǎn)是全文的核心,所以我們之間還存在巨大的分歧。
2008-04-18 10:19 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@raof01

本來我以為我們的觀點(diǎn)接近了,但是看到你說 x + 1 的 x 是左值, 我就知道我們根本沒有持相同觀點(diǎn).

現(xiàn)在,我解釋一下為什么 x + 1 中的 x 是右值, 首先要明確對(duì)于一個(gè)表達(dá)式,究竟是左值還是右值, 取決于它在表達(dá)式中的位置, 它并不是一定為左值或者右值,這一點(diǎn)你可以去看c++標(biāo)準(zhǔn),如果你對(duì)這點(diǎn)都不認(rèn)同,我們其實(shí)已經(jīng)無法再繼續(xù)討論了。

其次,對(duì)于一個(gè)表達(dá)式,它都會(huì)有一個(gè)對(duì)象和它對(duì)應(yīng),無論它是一個(gè)變量,還是能產(chǎn)生一個(gè)臨時(shí)對(duì)象,或者是一個(gè)字面常量(自演算表達(dá)式). 這一點(diǎn)你應(yīng)該是同意的. 那么一個(gè)對(duì)象, 其實(shí)是一個(gè)映射關(guān)系, 它實(shí)際存在在內(nèi)存中(或者寄存器中), 它一定有位置信息和值信息(當(dāng)然得到值還需要類型信息), 符號(hào)表是在編譯時(shí)轉(zhuǎn)換用的,運(yùn)行時(shí)雖然沒有這個(gè)表存在,但這個(gè)映射關(guān)系是存在的. 變量就表示了這層關(guān)系.

表達(dá)式 x 的運(yùn)算結(jié)果就是 x , 但是這個(gè)運(yùn)算結(jié)果是 x 本身嗎? 答案是否定的, 眾所周知, 內(nèi)存單元是無法做算術(shù)運(yùn)算的, x 的值 需要被取到 寄存器中, 然后才能加 1 . 如果你看匯編, 你會(huì)看到 一個(gè) 類似 lea 的指令, 所以 x 代表了它的值(先不管是左值還是右值).

對(duì)于一個(gè)非引用類型的a, a=b , 是會(huì)讓 a 和 b 變成同一個(gè)對(duì)象嗎? 不是, 只是讓 a 和 b 的值相等.

象basic那樣,給賦值加上一個(gè)let, let a = b, 這個(gè)a 是符號(hào)表中的那個(gè)a嗎? 一定. b是符號(hào)表中那個(gè)b嗎? 不必. 其實(shí)編譯器也是這么認(rèn)為的, 如果 b 的值 已經(jīng)被取到寄存器,它不會(huì)再取一次. 就象讀起來那樣, 讓a等于b, 只要跟b相等就好, b的位置在哪里無所謂, 但a在哪里就很重要了,否則就會(huì)給錯(cuò)人.

說的很亂,可能看不懂,其實(shí)回到本來的字面,左值就是放到等號(hào)左邊的值,右值就是放到右邊的值. 從 a = b 可以看出, 左值表示位置, 右值表示內(nèi)容(也就是值).

再回到 x + 1, x + 1 會(huì)改變 x 嗎? 不會(huì), 那么不一定需要x ,更不需要 x 的位置, 一個(gè)和 x 相等的對(duì)象也行, 所以, 這里的x 是右值.

對(duì)于非命令式語言, 就沒有左右值的煩惱, 命令式語言著實(shí)的麻煩. 怎么做的,解釋起來都費(fèi)勁.

呵呵.

2008-04-18 11:01 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@cuigang
仔細(xì)查閱了一些資料,發(fā)現(xiàn)對(duì)于lvalue和rvlaue的說明各有不同。找了兩個(gè)比較經(jīng)典的說法,共同參考一下。下面是在comp.lang.c++.moderated上找到的(為避免斷章取義,貼全文):
The simplest explanation I know is that an rvalue, in current C++, is an *expression* that produces a value, e.g. 42, and an lvalue is an *expression* that just refers to some existing object or function[1]. Hence the acronym "locator value"[2], which however is still misleading because an lvalue is simply not a value. Better would be *rexpression* versus *lexpression*, and even better, just value versus reference (unfortunately the term "reference" is already hijacked).

"object" versus "value": in C++ the basic definition of "object" is a region of storage, i.e. anything that actually occupies storage, while a pure value such as 42 doesn't necessarily occupy any storage. A value (an rvalue) can be an object, though. If it is, then it's a temporary object.

C++ allows you to call member functions on a class type rvalue, i.e. on a temporary class type object.

The ability to call member functions on (class type) rvalues, together with C++'s treatment of assignment operator as a member function (automatically generated if needed and none defined), means that you can assign to class type rvalues. However, C++ does not regard that rvalue to be *modifiable*: to be
well-defined, the assignment must do something else than modifiying the object assigned to (and typically we indicate that by declaring the assignment operator const). §3.10/14 "A program that attempts to modify an object through a nonmodifyable lvalue or rvalue expression is ill-formed".

Fine point: §3.10/14 means that rvalue-ness transfers to parts of an rvalue, which are thereby also considered rvalues. However, at least the two compilers I use don't seem to know that rule. Comeau Online does.

I'm not sure if the explanation above holds up with respect to C++0x rvalue references. rvalue versus lvalue got a lot more complicated in C++ than in original C. Perhaps it's even more complicated in C++0x, I don't know. :-)

Cheers, & hth.,
- Alf

Notes:
[1] Amazingly that's also the general definition the standard starts out with, before going into details: §3.10/2 "An lvalue refers to an object or function", however, it would have helped much if the word "expression" was explicitly included there, not just by being mentioned in the preceding paragraph.
[2] Unfortunately the C++ standard doesn't use or even mention the acronym "locator value". This acronym comes from the current C standard. And ironically the C++ standard mentions, by contextual placement, the original old C acronym of "left hand value", in §3.10/4: "built-in assignment operators all expect their left hand operands to be lvalues".

Programming Cpp的解釋:
http://etutorials.org/Programming/Programming+Cpp/Chapter+3.+Expressions/3.1+Lvalues+and+Rvalues/

你的解釋更接近真相,呵呵,不過我還是不同意地址一說,用引用會(huì)比較好一些。要不你整理一下,就lvalue和rvalue專門寫一篇?

看來俺還得多看看標(biāo)準(zhǔn)啊。
我的C++標(biāo)準(zhǔn)丟了,給發(fā)一個(gè)?raof01@gmail.com。
2008-04-18 14:13 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@raof01

C++03 標(biāo)準(zhǔn)
http://www.newsmth.net/bbsanc.php?p=335-15-1-4-2

我覺得有必要再羅嗦幾句

關(guān)于數(shù)組名是不是左值,C++標(biāo)準(zhǔn)中我沒找到具體條目,不過在C中,《Expert C Programming》4.3.1 確實(shí)提到”Hence,arrayname is a lvalue but not modifiable lvalue“

我把左值理解為”object with a name“,數(shù)組名在此范圍之內(nèi)



右值這個(gè)概念,本質(zhì)上是與可修改沒有關(guān)聯(lián)的

關(guān)于rvalue,常見的誤解是”不可修改“。并不是這樣的,右值并不是根據(jù)“不可修改”這個(gè)性質(zhì)來定義的

首先,函數(shù)的返回值一定是右值,除非返回的是引用

C++03 3.10.5
“The result of calling a function that does not return a reference is an rvalue.”

其次,右值是否能修改要看其是否是const-qualified

C++03 3.10.9
“Class rvalues can have cv-qualified types; non-class rvalues always have cv-unqualified types.”

也就是說,對(duì)于UDT,右值是否可修改要看這個(gè)右值是否被限定為const

舉個(gè)例子

class A
{
public:
void foo() {}
void fooc() const {}
};

A func() { return A();}
const A func2() {return A();}

func().foo(); //Ok
func().fooc(); //Ok
func2().foo(); //Error,對(duì)const rvalue調(diào)用non-const member function
func2().fooc(); //OK

func和func2的區(qū)別在于返回值(rvalue)是否限定為const──對(duì)于UDT,有沒有這個(gè)const限定的結(jié)果顯然不同

至于“臨時(shí)對(duì)象不一定是右值”,我想不出什么情況下臨時(shí)對(duì)象不是右值
2008-04-19 06:23 | 嘯天豬

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@嘯天豬
數(shù)組名是lvalue。但lvalue不是object with name,而是內(nèi)存區(qū)域的引用。這個(gè)問題我更傾向于cuigang的說法,雖然他用的是地址。
臨時(shí)對(duì)象是右值,呵呵。
我對(duì)于lvalue和rvalue的理解基本上是錯(cuò)誤的,呵呵,多謝cuigang和豬了。
2008-04-19 12:35 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

@raof01

善哉善哉
2008-04-19 21:26 | cuigang

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

如果:
“* 操作符應(yīng)用與左值表達(dá)式,以表達(dá)式左值為地址,取出表達(dá)式類型的值,作為右值返回?!?br>
那么:
int foo(int *p)
{
return (*p)++; // Or *p += 1;
}
如何解釋?
2008-07-28 14:46 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換[未登錄]  回復(fù)  更多評(píng)論   

表達(dá)式的lvalue是不可修改的,可修改的只有其rvalue。因?yàn)楫?dāng)一個(gè)表達(dá)式具有l(wèi)value時(shí),它在內(nèi)存中的位置是固定的,也就是lvalue是固定的。所謂修改表達(dá)式的值只是通過其lvalue來修改其rvalue。
比如
int i = 10;
假定i的地址為0x1000,那么i的lvalue是0x1000,rvalue是10,
i = 100;
則表示0x1000存放的內(nèi)容也就是rvalue被修改成100,而不是i的lvalue——0x1000被修改成別的值,其內(nèi)容為100。
2008-07-28 15:21 | raof01

# re: 數(shù)組類型、函數(shù)類型到左值和右值的轉(zhuǎn)換  回復(fù)  更多評(píng)論   

@raof01

這句話說得確實(shí)有問題,應(yīng)該是把表達(dá)式的值(右值)作為地址(但不是表達(dá)式的左值),取出內(nèi)容。

謝謝指正。
2008-08-03 13:45 | cuigang
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩视频一区二区| 国产欧美一区二区三区视频| 最新69国产成人精品视频免费| 亚洲视频1区| 亚洲免费视频在线观看| 亚洲一区二区黄色| 久久久国产一区二区三区| 久久精品视频在线看| 免费观看成人www动漫视频| 久久久精品999| 欧美激情精品| 一二三四社区欧美黄| 中文亚洲字幕| 久久久亚洲欧洲日产国码αv| 中文国产一区| 久久久国产精品亚洲一区 | 欧美一区成人| 久久亚洲欧美国产精品乐播| 亚洲精品美女| 久久一区亚洲| 国产精品电影观看| 亚洲精品国产精品乱码不99 | 欧美视频一区二区三区…| 国产精品高清网站| 日韩视频一区二区三区在线播放| 亚洲欧美一区二区激情| 男女精品网站| 欧美在线视频网站| 欧美亚洲第一页| 在线视频精品一区| 亚洲国产精品ⅴa在线观看| 久久aⅴ国产欧美74aaa| 国产女主播一区二区三区| 亚洲午夜电影在线观看| 亚洲乱码视频| 国产精品亚洲一区二区三区在线| 中文国产一区| 亚洲无玛一区| 国产一区二区精品久久99| 久久久精品免费视频| 久久久欧美精品| 亚洲第一综合天堂另类专| 牛牛影视久久网| 国产精品啊啊啊| 久久久久久九九九九| 欧美日韩三级视频| 欧美在线关看| 欧美a级片网| 欧美一乱一性一交一视频| 久久男人资源视频| 在线视频日本亚洲性| 久久久久一区| 亚洲在线一区| 久久综合精品一区| 西西裸体人体做爰大胆久久久| 欧美一区网站| 欧美与欧洲交xxxx免费观看 | 亚洲经典三级| 亚洲一本视频| 亚洲午夜视频| 欧美国产日韩精品免费观看| 亚洲自拍啪啪| 亚洲欧美日韩精品久久| 欧美护士18xxxxhd| 欧美大片专区| 一色屋精品视频免费看| 欧美在线视屏| 欧美在线视频一区| 国产精品网站在线播放| 99国内精品| 亚洲一区二区视频在线观看| 欧美日韩亚洲网| 99精品黄色片免费大全| 亚洲视频精品| 国产精品三级视频| 性一交一乱一区二区洋洋av| 午夜精品影院在线观看| 国产精品v亚洲精品v日韩精品| 一区二区三区欧美日韩| 亚洲性视频h| 国产午夜精品视频| 久久久久久夜| 99视频超级精品| 久久国产免费看| 亚洲精品视频在线看| 欧美日韩国产一中文字不卡| 亚洲午夜精品久久久久久app| 久久精品国产成人| 一本色道久久加勒比精品| 国产精品国产三级国产普通话蜜臀 | 国产精品久久午夜夜伦鲁鲁| 午夜精品偷拍| 亚洲第一福利社区| 欧美亚洲免费在线| 日韩视频在线观看一区二区| 国产精品美女www爽爽爽| 免费在线一区二区| 久久成人在线| 亚洲天堂免费观看| 亚洲国产精品一区制服丝袜 | 亚洲一区国产精品| 在线观看福利一区| 国产精品国产三级国产专区53 | 久久综合九色综合久99| 午夜日韩激情| 午夜性色一区二区三区免费视频| 日韩视频―中文字幕| 在线看日韩欧美| 亚洲成人资源网| 亚洲欧洲三级电影| 亚洲免费av网站| 亚洲无亚洲人成网站77777| 一区二区三区国产精品| 日韩视频欧美视频| 宅男精品视频| 亚洲欧美一区二区原创| 久久久久国产精品一区三寸| 欧美在线视频观看| 免费亚洲电影| 在线视频欧美精品| 亚洲天堂成人在线视频| 欧美一区三区三区高中清蜜桃| 欧美一区二区视频网站| 欧美国产免费| 国产日韩精品视频一区二区三区| 狠狠干综合网| 国产精品成人一区二区| 国产伦理精品不卡| 最新国产の精品合集bt伙计| 亚洲午夜在线| 欧美成人xxx| 午夜欧美大片免费观看| 快播亚洲色图| 国产亚洲欧美激情| 一区二区三区精品视频在线观看| 欧美在线在线| 亚洲午夜在线观看| 欧美日韩亚洲另类| 亚洲精品看片| 欧美激情国产日韩| 久久久国产精品一区| 国产精品国产三级国产专播精品人 | 国产女主播一区二区三区| 日韩午夜激情| 亚洲国产黄色| 久久婷婷丁香| 亚洲人成绝费网站色www| 久久国产精品网站| 午夜精品理论片| 国产精品自拍网站| 欧美在线免费观看亚洲| 亚洲午夜久久久久久久久电影网| 欧美日韩一区在线视频| 一区二区三区www| 亚洲一区中文| 一区视频在线| 亚洲人被黑人高潮完整版| 欧美日韩在线观看一区二区| 午夜久久一区| 久久综合久久美利坚合众国| 亚洲国产精品毛片| 亚洲第一区在线| 欧美视频中文一区二区三区在线观看| 精品999在线播放| 国产一区二区三区黄| 免费久久久一本精品久久区| 欧美激情中文不卡| 午夜免费日韩视频| 欧美电影电视剧在线观看| 亚洲欧美日韩国产综合在线| 蜜桃久久精品乱码一区二区| 亚洲嫩草精品久久| 美女久久一区| 久久蜜桃资源一区二区老牛| 欧美区日韩区| 欧美国产亚洲精品久久久8v| 国产亚洲成精品久久| 一区二区三区高清| 亚洲精品综合| 快she精品国产999| 欧美~级网站不卡| 黄色小说综合网站| 午夜精品在线观看| 欧美伊人久久久久久久久影院| 欧美性猛交99久久久久99按摩| 亚洲电影欧美电影有声小说| 在线免费观看日本欧美| 久久免费视频一区| 亚洲高清自拍| 亚洲伦理在线免费看| 欧美高清日韩| 日韩午夜在线| 久久av一区二区三区| 国产一区二区成人| 久久综合久色欧美综合狠狠| 欧美激情亚洲激情| 亚洲视频精选| 在线观看视频欧美| 欧美1区2区| 亚洲免费观看在线观看|