赋值运算符的左侧运算对象必须是一个可修改的左值,如果给定
int i=0,j=0,k=0; //初始化而非赋值
const int ci=i; //初始化而非赋值
则下面的赋值语句都是非法的:
1024=k ; //错误:字面值是右值
i+j=k; //错误:算术表达式是右值
ci=k;//错误:ci是常量(不可修改的)左值
赋值运算的结果是它的左侧运算对象,并且是一个左值。相应的,结果的类型就是左侧运算对象的类型。如果赋值运算符的左右两个运算对象类型不同,则右侧运算对象将转会成左侧运算对象的类型:
k=0; //结果:类型是int,值是0
k=3.1415926; //结果:类型是int,值死3
C++11新标准允许使用花括号括起来的初始值列表作为赋值语句的右侧运算对象:
k={3.14}; //错误:窄化转换
vector<int> vi; //初始为空
vi={0,1,2,3,4,5,6,7,8,9}; //vi现在含有10个元素了,值从0到9
如果左侧运算对象时内置类型,那么初始化列表最多只能包含一个值,而且该值即使转换的话其所占空间也不应该大于目标类型的空间。
赋值运算满足右结合性
赋值运算符满足右结合性,这一点与其他二元运算符不大一样:
int ival,jval;
ival=jval=0; //正确:都被赋值为0
因为赋值运算符满足右结合性,所以靠右的赋值运算符jval=0作为靠左的赋值运算符的右侧运算对象。又因为赋值运算符返回的是其左侧运算对象,所以靠右的赋值运算的结果被赋给了ival。
递增和递减运算符
注意:这两种运算符必须作用于左值运算对象。前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回。
在一条语句中混用解引用 和递增运算符
后置递增运算符的优先级高于解引用运算符,因此*pbeg++等价于*(pbeg++).pbeg++把pbeg的值加1,然后返回pbeg的初始值的副本作为其求值得结果,此时解引用运算符的运算对象时pbeg未增加之前的值。最终,这条语句输出pbeg开始时指向的那个元素,并将指针向前移动一个位置。