• <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>

            CG@CPPBLOG

            /*=========================================*/
            隨筆 - 76, 文章 - 39, 評論 - 137, 引用 - 0
            數據加載中……

            數組類型、函數類型到左值和右值的轉換

            1、左值和右值

            表達式的左值是它的地址,右值是該地址所存儲的內容。比如下面代碼:

            = x + 1;

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

            一個表達式究竟是取左值還是右值,需要結合上下文,大多數表達式同時具有左值和右值。

            2、指針類型、數組類型和函數類型

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

            T* a; 

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

            T arr[100];

            聲明一個變量arr,它的類型是 T[100](一維,維長100,元素類型為T的數組)。

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

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

            特別要強調的是,arr 的類型和 f 的類型都不是指針。這兩個類型的表達式沒有右值。

            3、&、* 操作符

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

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

            4、左值到右值的轉換

            C++ 標準轉換包含 左值到右值的轉換。因為數組類型和函數類型的表達式沒有右值,所以特別這里要說明數組類型和函數類型到右值的轉換。比如上文所說 arr ,當它作為賦值操作符的操作數時,它需要轉換為 T* 類型的指針(注意類型是指針!!),其值等于第一個元素的地址。而上文中所說的 f,當它作為賦值操作符的操作數時,它需要轉換為 T(*)(void) 的指針(注意類型是指針!!),它指向f的地址。

            5、對數組類型或者函數類型施加&、*操作符

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

             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 }

            運行結果如下:

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

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

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

            因為*func 和 func 是等價的,所以可以這樣調用 func:

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

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

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

            至于 arr、*arr、&arr 因為類型不同,不可混用,當然用來 memset 的話,表達式 arr 和 &arr 的值都為第一個元素的地址,最終都被轉換為 void* 。




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

            評論

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            給樓上的糾兩個錯:

            “左值:返回一個可修改對象的表達式稱為左值”

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

            “右值:返回一個不可修改對象的表達式稱為右值”

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

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @raof01

            1、我并非說我的左值右值描述是定義,但是你的依靠是否可修改的判斷卻反而是錯的,一個const變量x,表達式 x 仍然有右值,但是不代表 x 可修改。關于左值和右值,ISO C++ 98版標準這樣說:

            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 這樣說:

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

            左值代表了一個可被程序尋址的對象,可以從該對象讀取一個值,除非該對象被聲明為const,否則它的值也可以被修改。相對來說,右值只是一個表達式,它表示了一個值,或一個引用了臨時對象的表達式,用戶不能尋址該對象,也不能改變它的值。

            2、我承認對于 * 操作符用于左值的描述有問題,應該說 解引用操作符 用于指針類型,但 & 操作符的確只能應用于有左值的表達式,看C++ 標準這樣說:

            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.

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

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

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

            2008-04-08 21:44 | cuigang

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            哪個是對的,不要誤解人
            2008-04-09 16:14 | 我愛你

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @cuigang
            想太多反而會把問題搞復雜。

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

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

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

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

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

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            我覺得不嚴謹的理解,左值就是程序員有權知道其地址的object;右值則是雖然知道這個object的存在,但是它的地址對程序員是無意義的。

            至于左值/右值的準確含義,還是參考標準吧;書畢竟是面向大眾的,通常不會像標準那樣給出完整、嚴謹、天書般的定義

            @iwong

            建議參考水木社區Cplusplus版的FAQ,解釋的很詳細

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

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @嘯天豬

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @ww

            嘯天豬的鏈接你看一下,&只能對左值表達式取址。我就不用再廢話了。
            2008-04-10 22:20 | cuigang

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @嘯天豬
            @cuigang

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

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

            在VC中編譯時對后兩行都會提示“++需要左值”。

            如果相信這篇文章的話,那么這個結果是很令人費解的。
            2008-04-12 14:30 | iwong

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @iwong

            你需要區分概念:左值分為兩類──可修改的左值和不可修改的左值。通常提到的左值都指的是前者──例如上面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的地址對程序員無意義──它的地址對編譯器有用,對程序員是沒用的

            modifibale lvalue 意味著object的地址對程序員有意義,且可以用這個lvalue對object進行修改

            unmodifiable lvalue意味著object的地址對程序員有意義,但若通過這個lvalue對object進行修改,也是無意義的(編譯報錯或者運行出錯)

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

            而標準規定,前綴/后綴增量的操作對象必須是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!“++出錯的原因在于這里發生了string literal 到 pointer的自動轉換,”hello wolrd“轉換為類型為char *的rvalue。對于一個built-in type的rvalue執行增量操作,肯定是不合法的


            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: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            “但 & 操作符的確只能應用于有左值的表達式”——你是對的,我的錯誤。

            “至于你鏈接的文章,請恕我未能洞悉,不知里面哪里提到 解引用操作符可以用于右值,或者隱含此意味。”——實際我想說明的就是“但是間接尋址(indirection)反而說明了你的觀點,它是將指針變量的右值作為地址來訪問指向物,類似的有‘.’,‘->’運算符。”,因為我把指針當作對象的一種。

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

            ——向你的認真致敬!呵呵
            2008-04-17 13:42 | raof01

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @raof01

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

            謝謝你捧場。
            2008-04-17 13:54 | cuigang

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @raof01

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @cuigang
            我始終不同意這句話:“表達式的左值是它的地址,右值是該地址所存儲的內容。”因為無論地址還是內容,都是對象。而且按照你這句話,x = x + 1;第一個x是個地址,第二個x是其內容,假設x是T類型,那么上述表達式就應該理解為=左邊是個地址,也就是T*,對吧?矛盾就來了,你把T類型的值賦給了T*。
            “雖然言語之中仍然為自己辯護,不過大家觀點畢竟更加接近了”——剛才又仔細看了一遍你的文章,我堅持我第一個評論里的觀點,除了“&操作符能作用于左值和右值”這個錯誤。
            我認為:因為你的第一個觀點是全文的核心,所以我們之間還存在巨大的分歧。
            2008-04-18 10:19 | raof01

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @raof01

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

            現在,我解釋一下為什么 x + 1 中的 x 是右值, 首先要明確對于一個表達式,究竟是左值還是右值, 取決于它在表達式中的位置, 它并不是一定為左值或者右值,這一點你可以去看c++標準,如果你對這點都不認同,我們其實已經無法再繼續討論了。

            其次,對于一個表達式,它都會有一個對象和它對應,無論它是一個變量,還是能產生一個臨時對象,或者是一個字面常量(自演算表達式). 這一點你應該是同意的. 那么一個對象, 其實是一個映射關系, 它實際存在在內存中(或者寄存器中), 它一定有位置信息和值信息(當然得到值還需要類型信息), 符號表是在編譯時轉換用的,運行時雖然沒有這個表存在,但這個映射關系是存在的. 變量就表示了這層關系.

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

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

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

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

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

            對于非命令式語言, 就沒有左右值的煩惱, 命令式語言著實的麻煩. 怎么做的,解釋起來都費勁.

            呵呵.

            2008-04-18 11:01 | cuigang

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @cuigang
            仔細查閱了一些資料,發現對于lvalue和rvlaue的說明各有不同。找了兩個比較經典的說法,共同參考一下。下面是在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/

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

            看來俺還得多看看標準啊。
            我的C++標準丟了,給發一個?raof01@gmail.com。
            2008-04-18 14:13 | raof01

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @raof01

            C++03 標準
            http://www.newsmth.net/bbsanc.php?p=335-15-1-4-2

            我覺得有必要再羅嗦幾句

            關于數組名是不是左值,C++標準中我沒找到具體條目,不過在C中,《Expert C Programming》4.3.1 確實提到”Hence,arrayname is a lvalue but not modifiable lvalue“

            我把左值理解為”object with a name“,數組名在此范圍之內



            右值這個概念,本質上是與可修改沒有關聯的

            關于rvalue,常見的誤解是”不可修改“。并不是這樣的,右值并不是根據“不可修改”這個性質來定義的

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

            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.”

            也就是說,對于UDT,右值是否可修改要看這個右值是否被限定為const

            舉個例子

            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,對const rvalue調用non-const member function
            func2().fooc(); //OK

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

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

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            @raof01

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

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            如果:
            “* 操作符應用與左值表達式,以表達式左值為地址,取出表達式類型的值,作為右值返回。”

            那么:
            int foo(int *p)
            {
            return (*p)++; // Or *p += 1;
            }
            如何解釋?
            2008-07-28 14:46 | raof01

            # re: 數組類型、函數類型到左值和右值的轉換[未登錄]  回復  更多評論   

            表達式的lvalue是不可修改的,可修改的只有其rvalue。因為當一個表達式具有lvalue時,它在內存中的位置是固定的,也就是lvalue是固定的。所謂修改表達式的值只是通過其lvalue來修改其rvalue。
            比如
            int i = 10;
            假定i的地址為0x1000,那么i的lvalue是0x1000,rvalue是10,
            i = 100;
            則表示0x1000存放的內容也就是rvalue被修改成100,而不是i的lvalue——0x1000被修改成別的值,其內容為100。
            2008-07-28 15:21 | raof01

            # re: 數組類型、函數類型到左值和右值的轉換  回復  更多評論   

            @raof01

            這句話說得確實有問題,應該是把表達式的值(右值)作為地址(但不是表達式的左值),取出內容。

            謝謝指正。
            2008-08-03 13:45 | cuigang
            久久伊人五月天论坛| 99久久国产热无码精品免费久久久久| 精品熟女少妇a∨免费久久| 色婷婷狠狠久久综合五月| 久久亚洲欧美日本精品| 久久99精品久久久久久久不卡| 精品久久亚洲中文无码| 色狠狠久久综合网| 一本一道久久a久久精品综合| 久久婷婷人人澡人人| 久久久精品人妻无码专区不卡| 久久精品国产精品亚洲| 久久se精品一区精品二区国产| 久久se精品一区二区影院| 久久久久亚洲?V成人无码| 日本精品一区二区久久久| 久久中文字幕无码专区| 亚洲人成网站999久久久综合| 狠狠色丁香久久婷婷综合蜜芽五月| 怡红院日本一道日本久久| 国产成人精品久久一区二区三区av | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久96国产精品久久久| 欧美亚洲国产精品久久蜜芽| 色综合合久久天天综合绕视看| 国产精品99久久不卡| 欧美粉嫩小泬久久久久久久 | 亚洲乱亚洲乱淫久久| 久久精品中文字幕有码| 精品熟女少妇AV免费久久| 欧美大香线蕉线伊人久久| 青青草原综合久久| 欧洲性大片xxxxx久久久| 久久天天躁夜夜躁狠狠躁2022| 久久精品中文无码资源站| 亚洲伊人久久大香线蕉苏妲己| 久久久久无码精品| 久久精品国产亚洲AV无码麻豆| 91久久精品国产91性色也| 久久福利资源国产精品999| 大伊人青草狠狠久久|