您好,欢迎访问代码之道!登录后台查看权限
  • 欢迎大神光临
  • 有朋自远方来 不亦悦乎

C++:左值、右值、将亡值

C/C++ dz2015 2017-10-30 1072 次浏览 0个评论

相关知识扫盲

具名的

可通过名称访问的函数、变量等。

表达式

字面量和变量是基本的表示式、表示式和操作符的组合也是表达式。比如0、false、a+b、c=a+b、a==b等等都统称为表达式,

表达式的返回

不带操作符号的表达式比如字面量变量的返回是表达式自身;带赋值操作(+=、-=、前自增、前自减)的表达式返回是左操作数;比较运算返回的true或者false,等同字面量;加减乘除位操作等返回匿名变量...表达式的返回和计算结果有时候是不一样的,比如i++,其计算结果导致i的值加1,返回却是i的旧值的一份临时拷贝

值:值强调的是表达式运算后的结果。

左值、右值、将亡值

根据表达式返回的特性返回用于强调表达式最终返回的是“谁”,关心的是值存储的位置,而不是值本身是多少。

左值

能够用&取地址的表达式是左值(表达式),也就是左值的内存应该是程序员可访问的。

比如:具名的变量、解引用(取指针变量指向的值)、函数都是左值;表达式最终返回的是具名变量的也是左值;字符串字面量并不具名,但是可以用&取地址所以也是左值,函数调用返回左值引用是左值。

例 通过&判断表达式是否左值

void func1(){}

std::string str1;

const std::string & func2() {
    return str1;
}

int main() {
    int i = 0;
    std::cout<< &i << std::endl;
    //std::cout<< &i++ << std::endl; // i++的结果是存放在一个临时内存中,返回的是不具名变量,因此不是左值
    std::cout<< &*p << std::endl; //*p或者*&i都是,它们等同于i,解引用表达式是左值
    std::cout<< &++i << std::endl; // ++i将运算结果存放到i并返回i,
    std::cout<< &(i+=1) << std::endl; // i+=1是,对左值赋值的表达式也是左值
    std::cout<< &"test string" << std::endl; // 字符串字面量是,字符串字面量比较特殊,编译期就被分配了固定内存,存在于整个程序声明周期,其地址是可取的
    //std::cout<< &false << std::endl; // 0、‘a’、true、false等字面量都不是,除了字符串的的字面量都不是
    std::cout<< (void *)&func1 << std::endl; // func1是左值,注意是函数本体,不是函数调用,func1和func1()是两条不同的表达式
    std::cout<< &str1 << std::endl;
    std::cout<< &func2() << std::endl;
    return 0;
}

纯右值

不严格来说,纯右值(表达式)就是不可用&取地址的表达式。除字符串的字面量都是右值;后自增自减返回的是原变量的一份拷贝,因此是右值;取地址表达式是右值;加减乘除移位比较等运算表达式右值。

将亡值

对右值的引用导致右值的生命周期延长,这种特殊的右值就是将亡值。

已有 1072 位网友参与,快来吐槽:

发表评论