赋值运算符、左值与右值

来源:互联网 发布:确定性的终结 知乎 编辑:程序博客网 时间:2024/05/16 17:51

一、赋值运算符

C++的赋值运算符为“=“,其意义是将复赋值号右边的值送到左边变量所标识的内存单元中。

左操作数称为“左值”,必须放在内存中可以访问且可以合法修改值的存储单元中,通常只能是变量名;右操作数称为“右值”,可以是常量、变量或者表达式,但一定能取得确定的值。

int a=5+6;

int d=c=b=a+1; //将a+1的值12赋给b,再将表达式(b=a+1)的值12赋给c,再将表达式(c=b=a+1)的值12赋给d,则整个表达式的值为12

参考点击打开链接的解释:

左值:可以出现在赋值语句的左边或右边,它不光有值,还有一个存储地址。右值:只能出现在赋值语句的右边,认为它只有一个值的大小,没有存储地址,只关心它的值。

二、自增和自减操作符

C++提供两个具有赋值功能的单目运算符:++(自增)和--(自减)。在使用时分运算符前置和运算符后置。

1、对于单独的自增和自减表达式,如i++和++i的运算结果完全一样。

2、前自增操作符具有的左值性质,++i,它不仅返回i自增后的值,还返回i的存储单元地址;而后自增操作符具有的是右值性质,i++,它返回的只是i的原值,没有这个i的存储单元的地址。
int i = 0;
++(i++);//这个语句编译会报错~因为i++返回的是个常量值,前自增不知道在哪个存储单元进行自增操作(i++)++也一样编译通不过,道理一样。
而(++i)++;//这个语句就能通过编译,因为++i还返回的i的存储地址,所以后自增知道是在哪个存储单元进行操作
int i = 0

3、参与其他运算时,运算符前置和后置有区别。

[cpp] view plaincopy
  1. int i=5,j=5,m,n;  
  2. m=i++;  //相当于m=i;i++;结果m=5,i=6  
  3. n=++j; //相当于j++;n=j;结果n=6,j=6  

有这样一个表达式:++a++=5,通过加括号的方式,

1)++(a++) = 5; 错误信息如下:error:  '++' needs l-value 。a++是右值,于是的话再次进行前置++的操作就是错误的,因为前置++操作需要的表达式是左值表达式。
2)(++a)++ = 5;错误信息如下: error: left operand must be l-value。其实++a是左值表达式,那么后面的那个++操作就是一个错误了,赋值的时候,等号的左边不是左值表达式,因为括号外的是一个后置的++运算符。

相关知识:建议使用前自增操作。因为前置操作需要做的工作更少,只需加1后返回加1后的结果。而后置操作符则必须先保存操作数原来的值,以便返回未加1前的值作为操作的结果。对于int型和指针,编译器可优化掉这项额外工作,但对于更多的复杂迭代器类型,这种额外工作会花费更大的代价。

三、函数返回值作为左值

一个声明为返回值为引用的函数可以作为左值。只要返回变量不是临时变量或生命期已结束的局部量,就可以作为左值。对于非引用返回 ,返回的是临时变量,不可能作为左值。

#include <iostream>#include <string>using namespace std;//string str("a value");/*char &get_val(string::size_type ix){       return str[ix];}*/char &get_val(string &str, string::size_type ix){       return str[ix];} int main(){       string str("a value");       cout << str << endl;       get_val(str,0)='A';     //get_val(0) = 'A';          cout << str << endl;   system("pause");       return 0;}


0 0