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

隨筆 - 10  文章 - 0  trackbacks - 0
<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

靜心學(xué)習(xí),好好珍惜身邊的人。

常用鏈接

留言簿(1)

隨筆分類(lèi)

隨筆檔案

搜索

  •  

積分與排名

  • 積分 - 3919
  • 排名 - 1713

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

If you've been programming in either C or C++ for a while, it's likely that you've heard the terms lvalue (pronounced "ELL-value") and rvalue (pronounced "AR-value"), if only because they occasionally appear in compiler error messages. There's also a good chance that you have only a vague understanding of what they are. If so, it's not your fault.

Most books on C or C++ do not explain lvalues and rvalues very well. (I looked in a dozen books and couldn't find one explanation I liked.) This may be due to of the lack of a consistent definition even among the language standards. The 1999 C Standard defines lvalue differently from the 1989 C Standard, and each of those definitions is different from the one in the C++ Standard. And none of the standards is clear.

Given the disparity in the definitions for lvalue and rvalue among the language standards, I'm not prepared to offer precise definitions. However, I can explain the underlying concepts common to the standards.

As is often the case with discussions of esoteric language concepts, it's reasonable for you to ask why you should care. Admittedly, if you program only in C, you can get by without understanding what lvalues and rvalues really are. Many programmers do. But understanding lvalues and rvalues provides valuable insights into the behavior of built-in operators and the code compilers generate to execute those operators. If you program in C++, understanding the built-in operators is essential background for writing well-behaved overloaded operators.

Basic concepts
Kernighan and Ritchie coined the term lvalue to distinguish certain expressions from others. In The C Programming Language (Prentice-Hall, 1988), they wrote "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."

In other words, the left and right operands of an assignment expression are themselves expressions. For the assignment to be valid, the left operand must refer to an object-it must be an lvalue. The right operand can be any expression. It need not be an lvalue. For example:

int n;

declares n as an object of type int. When you use n in an assignment expression such as:

n = 3;

n is an expression (a subexpression of the assignment expression) referring to an int object. The expression n is an lvalue.

Suppose you switch the left and right operands around:

3 = n;

Unless you're a former Fortran programmer, this is obviously a silly thing to do. The assignment is trying to change the value of an integer constant. Fortunately, C and C++ compilers reject it as an error. The basis for the rejection is that, although the assignment's left operand 3 is an expression, it's not an lvalue. It's an rvalue. It doesn't refer to an object; it just represents a value.

I don't know where the term rvalue comes from. Neither edition of the C Standard uses it, other than in a footnote stating "What is sometimes called 'rvalue' is in this standard described as the 'value of an expression.'"

The C++ Standard does use the term rvalue, defining it indirectly with this sentence: "Every expression is either an lvalue or an rvalue." So an rvalue is any expression that is not an lvalue.

Numeric literals, such as 3 and 3.14159, are rvalues. So are character literals, such as 'a'. An identifier that refers to an object is an lvalue, but an identifier that names an enumeration constant is an rvalue. For example:

enum color { red, green, blue };
color c;
...
c = green;    // ok
blue = green;    // error

The second assignment is an error because blue is an rvalue.

Although you can't use an rvalue as an lvalue, you can use an lvalue as an rvalue. For example, given:

int m, n;

you can assign the value in n to the object designated by m using:

m = n;

This assignment uses the lvalue expression n as an rvalue. Strictly speaking, a compiler performs what the C++ Standard calls an lvalue-to-rvalue conversion to obtain the value stored in the object to which n refers.

Lvalues in other expressions
Although lvalues and rvalues got their names from their roles in assignment expressions, the concepts apply in all expressions, even those involving other built-in operators.

For example, both operands of the built-in binary operator + must be expressions. Obviously, those expressions must have suitable types. After conversions, both expressions must have the same arithmetic type, or one expression must have a pointer type and the other must have an integer type. But either operand can be either an lvalue or an rvalue. Thus, both x + 2 and 2 + x are valid expressions.

Although the operands of a binary + operator may be lvalues, the result is always an rvalue. For example, given integer objects m and n:

m + 1 = n;

is an error. The + operator has higher precedence than the = operator. Thus, the assignment expression is equivalent to:

(m + 1) = n;    // error

which is an error because m + 1 is an rvalue.

As another example, the unary & (address-of) operator requires an lvalue as its operand. That is, &n is a valid expression only if n is an lvalue. Thus, an expression such as &3 is an error. Again, 3 does not refer to an object, so it's not addressable.

Although the unary & requires an lvalue as its operand, it's result is an rvalue. For example:

int n, *p;
...
p = &n;    // ok
&n = p;    // error: &n is an rvalue

In contrast to unary &, unary * produces an lvalue as its result. A non-null pointer p always points to an object, so *p is an lvalue. For example:

int a[N];
int *p = a;
...
*p = 3;     // ok

Although the result is an lvalue, the operand can be an rvalue, as in:

*(p + 1) = 4;    // ok

Data storage for rvalues
Conceptually, an rvalue is just a value; it doesn't refer to an object. In practice, it's not that an rvalue can't refer to an object. It's just that an rvalue doesn't necessarily refer to an object. Therefore, both C and C++ insist that you program as if rvalues don't refer to objects.

The assumption that rvalues do not refer to objects gives C and C++ compilers considerable freedom in generating code for rvalue expressions. Consider an assignment such as:

n = 1;

where n is an int. A compiler might generate named data storage initialized with the value 1, as if 1 were an lvalue. It would then generate code to copy from that initialized storage to the storage allocated for n. In assembly language, this might look like:

one: .word 1
...
mov (one), n

Many machines provide instructions with immediate operand addressing, in which the source operand can be part of the instruction rather than separate data. In assembly, this might look like:

mov #1, n

In this case, the rvalue 1 never appears as an object in the data space. Rather, it appears as part of an instruction in the code space.

On some machines, the fastest way to put the value 1 into an object is to clear it and then increment it, as in:

clr n
inc n

Clearing the object sets it to zero. Incrementing adds one. Yet data representing the values 0 and 1 appear nowhere in the object code.

posted on 2008-12-15 10:43 GLORY 閱讀(549) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++ Specification
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩精品一区二区天天拍小说 | 韩日欧美一区二区| 亚洲高清一区二| 亚洲综合99| 亚洲国产精品久久人人爱蜜臀| 国产精品99久久久久久www| 亚洲第一黄网| 欧美在线亚洲综合一区| 亚洲欧美日韩中文在线制服| 另类天堂av| 毛片一区二区| 国产主播一区| 欧美一二三区精品| 午夜在线精品偷拍| 欧美日韩中文字幕在线| 亚洲黄色一区二区三区| 亚洲国产精品久久久久秋霞影院 | 午夜免费在线观看精品视频| 一区二区黄色| 欧美日产国产成人免费图片| 欧美黄网免费在线观看| 一区三区视频| 久久男人av资源网站| 久久久久一区| 尤物九九久久国产精品的特点| 亚洲欧美日韩在线高清直播| 午夜精品久久久久久| 欧美视频一区二区在线观看| 99热在这里有精品免费| 亚洲一区在线视频| 美女露胸一区二区三区| 欧美不卡视频一区发布| 亚洲黄色影院| 欧美乱在线观看| 夜夜嗨av色一区二区不卡| 亚洲一区精彩视频| 国产欧美日韩视频在线观看| 欧美在线视频二区| 欧美aⅴ99久久黑人专区| 亚洲国产欧美久久| 欧美精品三级在线观看| 中国亚洲黄色| 久久久亚洲人| 亚洲精品一区中文| 国产精品卡一卡二| 欧美在线免费看| 欧美激情女人20p| 亚洲午夜精品一区二区| 国产日韩精品一区二区三区在线| 久久国产精品72免费观看| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲日韩第九十九页| 欧美系列电影免费观看| 欧美中文在线观看国产| 亚洲黄色成人网| 性欧美大战久久久久久久久| 国产一区二区三区日韩| 男同欧美伦乱| 亚洲欧美日韩精品久久| 欧美福利在线| 欧美一区二区三区在线免费观看 | 亚洲国产成人av| 亚洲欧美国产日韩中文字幕| 国产在线乱码一区二区三区| 欧美激情一区二区三区成人 | 一区二区三区三区在线| 久久中文久久字幕| 亚洲一区久久| 亚洲精品一区中文| 国产真实精品久久二三区 | 欧美成人一品| 欧美一区二区精品| 一本久久青青| 亚洲福利视频二区| 久久免费视频在线观看| 亚洲欧美日韩精品在线| 亚洲精品1区2区| 国内成人精品一区| 国产精品乱看| 欧美日韩一区二| 欧美jizz19hd性欧美| 篠田优中文在线播放第一区| 亚洲精品国产精品国自产在线| 久久九九热免费视频| 亚洲女人天堂av| 在线亚洲一区二区| 亚洲精品偷拍| 亚洲精品日韩综合观看成人91| 国内在线观看一区二区三区| 国产精品视频你懂的| 欧美小视频在线| 欧美日韩国产精品一区二区亚洲| 久久婷婷蜜乳一本欲蜜臀| 性欧美暴力猛交69hd| 亚洲一区在线免费观看| 一本久道综合久久精品| 99国产精品久久久久久久| 亚洲国产欧美一区二区三区同亚洲| 久久在线免费观看| 久久婷婷国产综合精品青草| 久久大香伊蕉在人线观看热2| 亚洲影院污污.| 亚洲一区二区在线视频| 亚洲午夜国产成人av电影男同| 一本久久综合亚洲鲁鲁五月天| 亚洲人成人一区二区在线观看| 亚洲大片av| 亚洲国产日韩在线| 亚洲精品老司机| 日韩午夜剧场| 亚洲小少妇裸体bbw| 亚洲永久免费av| 午夜国产精品视频| 久久不射网站| 久热精品视频在线观看一区| 免费成年人欧美视频| 欧美大片va欧美在线播放| 欧美/亚洲一区| 亚洲国产天堂久久国产91| 亚洲日本在线观看| 国产精品99久久久久久久vr| 亚洲一区二区高清| 欧美综合二区| 免费成人av在线看| 欧美日韩小视频| 国产精品欧美在线| 国内在线观看一区二区三区 | 日韩视频免费| 性久久久久久久| 欧美jizz19性欧美| 日韩视频一区二区| 新片速递亚洲合集欧美合集| 久久免费视频这里只有精品| 欧美激情综合五月色丁香| 国产精品成人在线观看| 国产一区日韩一区| 亚洲精品黄网在线观看| 午夜精品久久久久久99热软件| 久久精品国产综合| 亚洲激情欧美| 欧美一区二区精美| 欧美日韩成人一区| 国产一区二区三区丝袜 | 久久精品国产免费看久久精品| 美日韩免费视频| 一区二区三区视频观看| 久久精品一区二区三区中文字幕 | 免费成人av在线| 一区二区欧美激情| 久久久在线视频| 国产精品久久久久久亚洲调教 | 亚洲人成人一区二区在线观看 | 一区二区三区视频在线看| 久久本道综合色狠狠五月| 欧美精品一区二区久久婷婷| 国产日韩视频| 中文av字幕一区| 欧美成人免费网| 亚洲欧美日本精品| 欧美日韩国产黄| 亚洲国产99精品国自产| 欧美影院成人| 一区二区三区高清在线 | 久热精品视频| 国产主播一区二区三区四区| 亚洲视频一二| 最新亚洲激情| 久久午夜羞羞影院免费观看| 国产精品丝袜久久久久久app| 亚洲精品一区中文| 蜜桃av一区二区| 欧美一区亚洲二区| 国产精品一区二区欧美| 亚洲私人影吧| 亚洲毛片av在线| 欧美激情中文字幕乱码免费| 在线免费观看日本欧美| 久久国内精品自在自线400部| a4yy欧美一区二区三区| 欧美国产日韩一区二区| 亚洲风情在线资源站| 久久全球大尺度高清视频| 亚洲欧美在线aaa| 国产精品一页| 欧美一区二区三区婷婷月色| 一区二区三区国产盗摄| 欧美日韩一区二区高清| 一区二区三区日韩精品视频| 最新精品在线| 欧美日韩另类字幕中文| 亚洲视频在线一区观看| 99伊人成综合| 国产精品久久久久久久久久免费 | 国产女人aaa级久久久级| 亚洲免费视频观看| 这里只有视频精品| 国产精品一区二区三区四区五区 | 中文有码久久| 亚洲视频导航| 国产日韩欧美高清免费|