• “左值和右值”的思考


    起源于C语言

    左值和右值都是从继承C语言继承过来的,那么为什么C语言中要创造“左值和右值”,在C语言中又是怎么定义的呢?

    在Kernighan Kernighan和Ritchie创造了左值这个术语来区分某些表达与其他表达。在《The C Programming Language 》中他们写到"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.",换句话说运算符“=”左边一定是个左值,它最初只是用来做一些区分,编译器报错的时候,我们也会常见到它的身影。

    例如:

    int n;
    n = 4;

    这里n指向一个整形对象,是一个右值,所以没有错。但是假如我们换成:

    4 = n;

    编译器就会报错:“error: lvalue required as left operand of assignment 4 = n”;这里4是只是一个常量,不能作为一个左值。

    所以,左值和右值可以帮助我们和一些表达式做一些很好的区分,在C语言中,不懂“左值和右值”好像并不影响我们编程,但是它有助于我们深入理解一些内置运算符。

    基本的概念

    我们已经有几种常用的运算符用到左值,下面我们来看看:

    int n;
    n = 4;

    赋值运算符需要一个(非常量)左值作为左侧运算对象,得到的结果仍然是一个左值。

    int n = 1, m = 2;
    n = m + 1; // success
    m + 1 = n; // error 

    因为“+”运算符等级高于“=”,所以m+1 = n 等价于 (m + 1) = n ,这里报错,因为m + 1是右值。

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

    这里,“&”地址运算符得到的结果也是右值。

    int a[N];
    int *p = a;
    ...
    *p = 3;     // ok
    *(p + 1) = 4;    // ok

    这里,“*”解引用运算符得到的结果是左值,所以正确。

    到这里,我们可以看出,当一个对象被用作右值的时候,用的是对象的值(内容),而对象被用作左值的时候,用的是对象的地址,如果一个对象没有地址(无法取地址),也就无法作左值。

    左值和右值的转化

    int a = 1;     // a is an lvalue
    int b = 2;     // b is an lvalue
    int c = a + b; // + needs rvalues, so a and b are converted to rvalues
                   // and an rvalue is returned

    一般来说,需要右值的地方可以用左值来代替,但是不能把右值当成左值来用,但是这里有个例外,下面我们来看:

    int i = 42;
    int &&rr2 = i; // error can't bind a rvalue ference to an lvalue
    int &&rr2 = i *42; // ok

    我们可以将一个右值引用绑定到一个表达式上,但是不能讲一个右值引用绑定到一个左值上。

    参考:

    1. http://ieng9.ucsd.edu/~cs30x/Lvalues%20and%20Rvalues.htm
    2. http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/
    3. <C++ Primer>
  • 相关阅读:
    Variable OR State Visiblity:Stale Data, Locking and Visiblity and Volatile(So many Unnoticed aspect in MultiThread)
    WCF 4 Behavior
    The Atomic classes in Java 5: AtomicInteger and AtomicLong,AtomicReference etc.
    Servlet Only One Instance In Container?
    Lock and Reentrant
    JAVA Final KeyWord And Thread Safety
    c#之基础语法 event 如何触发回调事件
    c#基础语法之 解读delegate create by lee
    Create project Django ( python framework ) wrote by lee
    invade mysql 初学者学习mysql create by lee
  • 原文地址:https://www.cnblogs.com/vczf/p/6839118.html
Copyright © 2020-2023  润新知