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

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

靜心學習,好好珍惜身邊的人。

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

搜索

  •  

積分與排名

  • 積分 - 3919
  • 排名 - 1713

最新評論

閱讀排行榜

評論排行榜

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) 評論(0)  編輯 收藏 引用 所屬分類: 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久久香蕉国产 | 一本色道久久综合| 午夜欧美大片免费观看| 日韩视频免费在线观看| 久久国产精品久久国产精品| 亚洲视频综合| 欧美另类高清视频在线| 麻豆亚洲精品| 国产一区激情| 午夜精品久久久久影视 | 久久一区激情| 国产欧美一区二区三区久久 | 欧美日韩国产成人高清视频| 美日韩精品免费观看视频| 国产欧美精品xxxx另类| 亚洲香蕉成视频在线观看| 在线一区欧美| 欧美色欧美亚洲另类二区 | 欧美成人精品一区| 黑人巨大精品欧美一区二区| 亚洲欧美国产高清va在线播| 亚洲一区在线免费| 国产精品99一区二区| 洋洋av久久久久久久一区| 亚洲视频综合在线| 欧美日韩中文字幕在线视频| 亚洲精品三级| 亚洲小说欧美另类社区| 欧美午夜精品久久久| 亚洲一区二区伦理| 午夜天堂精品久久久久| 国产麻豆一精品一av一免费| 午夜精品在线看| 久久久99免费视频| 亚洲大胆av| 欧美精品久久一区二区| 亚洲人www| 日韩亚洲欧美中文三级| 欧美新色视频| 午夜久久tv| 免费在线观看一区二区| 亚洲国产欧美一区二区三区丁香婷| 噜噜噜躁狠狠躁狠狠精品视频 | 国产精品国产三级国产aⅴ无密码| 99国产精品久久久久久久成人热| 亚洲午夜久久久| 国产视频一区在线| 久久精品国内一区二区三区| 欧美激情按摩在线| 亚洲视频在线观看免费| 国产欧美日韩一区二区三区| 销魂美女一区二区三区视频在线| 男女精品视频| 中日韩视频在线观看| 国产欧美一区二区三区在线老狼 | 精品二区视频| 欧美日本一区二区三区| 亚洲一区尤物| 欧美黑人一区二区三区| 亚洲综合色视频| 1204国产成人精品视频| 欧美日韩免费区域视频在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 美女黄色成人网| 亚洲在线一区| 亚洲国产婷婷综合在线精品| 国产精品久久久久久妇女6080| 久久成人免费网| 日韩视频在线观看| 久久综合久久久| 亚洲在线观看| 亚洲人成7777| 国产综合视频在线观看| 欧美日韩另类在线| 久久亚洲综合| 性做久久久久久| 亚洲免费观看| 亚洲二区在线观看| 久久久久成人精品| 亚洲欧美久久久| 亚洲日本视频| 在线观看日产精品| 国产乱码精品一区二区三区忘忧草| 久久亚洲捆绑美女| 欧美在线影院在线视频| 一本久久综合亚洲鲁鲁| 欧美成人xxx| 久久综合久久综合这里只有精品| 亚洲视频一区二区免费在线观看| 亚洲大片av| 国内精品久久久久久| 国产精品久久久久一区二区三区共| 欧美黄色影院| 卡通动漫国产精品| 久久久av毛片精品| 欧美专区在线观看一区| 亚洲一区日韩| 亚洲专区在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲乱码国产乱码精品精| 欧美激情小视频| 欧美成人资源网| 免费在线成人| 欧美成人中文| 亚洲福利视频一区| 亚洲国产欧美不卡在线观看| 欧美大片免费观看| 亚洲成人在线免费| 国产欧美在线看| 国产精品手机在线| 国产精品资源| 国产亚洲第一区| 国产综合久久| 尤物视频一区二区| 亚洲成人资源网| 亚洲精品在线观| 99精品视频一区| 亚洲一级电影| 性欧美超级视频| 久久av资源网站| 久久久久免费视频| 欧美jizz19性欧美| 亚洲国产合集| 一区二区三区欧美在线| 亚洲一区成人| 久久久国产亚洲精品| 久久亚洲国产精品日日av夜夜| 久久亚裔精品欧美| 欧美精品在线观看播放| 欧美日韩一区二区三区视频 | 久久国产精品久久久久久久久久| 久久精品亚洲一区二区| 久久中文字幕一区| 91久久久久久国产精品| 在线午夜精品| 久久国产手机看片| 欧美理论片在线观看| 国产精品素人视频| 亚洲大片免费看| 亚洲一区日韩在线| 蜜臀av国产精品久久久久| 亚洲人成人一区二区在线观看| 亚洲午夜av| 免费久久精品视频| 国产精品久久久久7777婷婷| 国模套图日韩精品一区二区| 亚洲日本欧美| 久久国产欧美| 日韩午夜精品| 久久综合国产精品| 国产精品美女午夜av| 亚洲国产精彩中文乱码av在线播放| 一区二区三区精品视频| 免播放器亚洲一区| 亚洲综合精品四区| 欧美成人一区二区三区| 国产午夜久久| 亚洲一级影院| 亚洲七七久久综合桃花剧情介绍| 欧美一区二区福利在线| 欧美日韩的一区二区| 在线观看亚洲| 羞羞答答国产精品www一本 | 一区二区欧美日韩视频| 久久电影一区| 国产乱人伦精品一区二区| 亚洲人成久久| 免费国产一区二区| 午夜欧美不卡精品aaaaa| 欧美日韩精品二区| 亚洲欧洲午夜| 欧美成人资源网| 久久大香伊蕉在人线观看热2| 国产精品狠色婷| 一本久久综合亚洲鲁鲁| 欧美黄色片免费观看| 久久久国产精品一区| 国产一区二区久久久| 欧美一区二区视频在线观看2020| 99精品黄色片免费大全| 欧美精品久久久久久久久老牛影院 | 亚洲国产精品久久久久秋霞不卡 | 日韩一级视频免费观看在线| 免费视频一区二区三区在线观看| 午夜精品视频| 国产亚洲在线| 久久九九免费视频| 欧美一级艳片视频免费观看| 国产精品午夜av在线| 午夜在线观看欧美| 亚洲午夜激情网页| 国产精品一区二区女厕厕| 香蕉成人久久| 性xx色xx综合久久久xx| 国产日韩在线不卡| 久久婷婷成人综合色| 久久成年人视频| 亚洲成人原创| 亚洲国产精品热久久| 欧美精品首页|