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

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 閱讀(4544) 評(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á)式取址。我就不用再廢話了。
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á)式類型的值,作為右值返回。”

那么:
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>
            一区二区三区 在线观看视| 狂野欧美一区| 玖玖玖免费嫩草在线影院一区| 国产一区视频在线观看免费| 久久精品国产91精品亚洲| 老鸭窝毛片一区二区三区| 亚洲高清免费| 欧美日韩精品二区| 午夜亚洲视频| 蜜臀久久久99精品久久久久久| 亚洲国产精品久久久久婷婷884 | 国产精品99免费看| 欧美一级二级三级蜜桃| 欧美成人69| 亚洲午夜久久久久久尤物 | 亚洲三级电影全部在线观看高清| 亚洲黄色小视频| 欧美三级电影一区| 欧美一区二区大片| 免费中文字幕日韩欧美| 日韩天堂在线观看| 国产日韩欧美三区| 蜜桃视频一区| 亚洲一区日韩在线| 欧美激情一区二区三区高清视频| 亚洲一二三四区| 在线看国产一区| 欧美三级电影大全| 久久综合婷婷| 亚洲男人av电影| 亚洲国产精品毛片| 欧美一区二区免费视频| 亚洲另类自拍| 国产午夜精品美女视频明星a级| 欧美高清在线一区二区| 西瓜成人精品人成网站| 日韩亚洲在线| 欧美成人按摩| 久久狠狠一本精品综合网| 日韩视频中文| 亚洲国产成人久久综合一区| 国产精品日韩欧美一区二区| 欧美激情第二页| 久久国产66| 亚洲宅男天堂在线观看无病毒| 亚洲丰满少妇videoshd| 久久久国产精品一区| 亚洲性夜色噜噜噜7777| 亚洲精品一线二线三线无人区| 激情欧美日韩一区| 国产欧美一区二区三区视频| 欧美另类极品videosbest最新版本| 久久国内精品视频| 性色av一区二区三区| 亚洲视频axxx| 一本色道久久综合亚洲精品不卡| 国产热re99久久6国产精品| 欧美精品啪啪| 在线免费高清一区二区三区| 国产精品毛片a∨一区二区三区| 欧美国产第一页| 欧美gay视频激情| 久久久综合网站| 久久久噜噜噜久久狠狠50岁| 欧美一级黄色录像| 午夜免费在线观看精品视频| 亚洲午夜日本在线观看| 一本大道av伊人久久综合| 亚洲欧洲一区二区三区在线观看| 欧美激情第3页| 欧美国产日韩在线观看| 欧美高清自拍一区| 亚洲大胆女人| 亚洲激情视频在线| 亚洲精品一区在线观看| 99国产精品久久| av成人免费观看| 亚洲小说欧美另类婷婷| 亚洲中字在线| 久久电影一区| 久久久高清一区二区三区| 久久乐国产精品| 你懂的视频欧美| 欧美精品久久久久久久久老牛影院| 欧美凹凸一区二区三区视频| 免费在线国产精品| 欧美精品导航| 欧美视频网址| 国产欧亚日韩视频| 伊人久久av导航| 亚洲精选视频在线| 亚洲一区国产精品| 久久国产精品第一页| 另类欧美日韩国产在线| 亚洲电影第三页| 99热这里只有成人精品国产| 亚洲免费网址| 麻豆久久精品| 国产精品盗摄久久久| 国产欧美一区二区三区沐欲 | 亚洲激情av在线| 亚洲视频精品在线| 久久成人在线| 亚洲国产二区| 亚洲少妇自拍| 久久免费精品日本久久中文字幕| 欧美激情二区三区| 国产欧美日韩一区| 亚洲欧洲一级| 香蕉视频成人在线观看| 免费中文字幕日韩欧美| 一区二区不卡在线视频 午夜欧美不卡' | 亚洲欧美另类国产| 久久久综合视频| 欧美午夜一区二区福利视频| 国内精品国产成人| 日韩一级在线观看| 久久精品一区中文字幕| 亚洲日本中文字幕免费在线不卡| 亚洲综合丁香| 欧美激情久久久| 国内精品久久久久影院薰衣草| 亚洲另类在线视频| 久久亚洲国产精品一区二区| 亚洲卡通欧美制服中文| 久久精品综合一区| 国产精品欧美日韩一区| 91久久精品国产91性色tv| 欧美在线不卡| 99re6热在线精品视频播放速度| 久久精品国产亚洲一区二区| 欧美日韩一区三区| 91久久精品国产91性色tv| 欧美在线观看网站| 日韩午夜在线视频| 免费观看国产成人| 国内精品亚洲| 欧美一级电影久久| 一区二区三区精品在线| 欧美+亚洲+精品+三区| 国内一区二区三区| 午夜精品久久久久久久久| 亚洲精品看片| 欧美成人69| 在线观看视频一区二区欧美日韩| 久久成年人视频| 亚洲在线视频免费观看| 欧美日韩免费一区| 亚洲精品国产精品国自产在线| 久久婷婷一区| 欧美在线视频免费观看| 国产日韩一区在线| 欧美一区二区啪啪| 亚洲女女做受ⅹxx高潮| 欧美性片在线观看| 亚洲一区二区三区久久| 99re热这里只有精品视频| 欧美国产日韩精品| 亚洲美女在线视频| 亚洲国产精品嫩草影院| 欧美大片在线看| 亚洲美女av网站| 亚洲欧洲精品一区二区| 欧美精品一区二区三区视频| 亚洲精品视频在线| 亚洲日韩第九十九页| 欧美日韩激情小视频| 亚洲桃花岛网站| 一区二区激情| 国产精品视频男人的天堂| 午夜视频久久久| 欧美一区二区免费观在线| 国产婷婷色一区二区三区| 久久国产毛片| 久久久在线视频| 亚洲美女av网站| 99v久久综合狠狠综合久久| 欧美图区在线视频| 欧美亚洲色图校园春色| 欧美一级在线视频| 在线观看欧美成人| 最新日韩在线视频| 国产精品a级| 久久婷婷蜜乳一本欲蜜臀| 久久午夜精品一区二区| 亚洲免费观看高清在线观看 | 欧美视频一区二区三区| 亚洲欧美激情四射在线日 | 亚洲国产精品女人久久久| 欧美日韩国产精品成人| 亚洲欧美电影在线观看| 欧美在线观看www| 亚洲精美视频| 亚洲四色影视在线观看| 国产亚洲精品久久久久婷婷瑜伽| 欧美粗暴jizz性欧美20| 欧美四级在线| 每日更新成人在线视频| 欧美日韩国产成人在线91| 久久成人国产精品|