一、左值右值
当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
一个重要的原则(有一种例外情况,待写。。。)在需要右值的地方可以用左值来代替,但是不能把右值当初左值使用。当一个左值被当成右值使用时,实际使用的是它的内容。
要用到左值的几种运算符:
1、赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
2、取地址符作用于一个左值运算符,返回一个指向该运算对象的指针,这个指针是一个右值。
3、内置解引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算的求值结果都是左值。
4、内置类型和迭代器的递增递减运算符作用于左值对象,其前置版本所得的结果也是左值。
二、优先级和结合律
表达式最终的值依赖于其子表达式的组合方式。高优先级运算符的运算对象比低优先级运算符的运算对象更为紧密地组合在一起。如果优先级相同,则其组合规则由结合律确定。算数运算符满足左结合律,意味着如果运算符的优先级相同,将按照从左到右的顺序组合运算对象。括号无视优先级和结合律。
三、求值顺序
对于那些没有指定运算对象执行顺序的运算符来说,如果表达式执行并修改了同一个对象,将会引发错误并产生未定义的行为。有4种运算符明确规定了运算对象的求值顺序,逻辑与(&&)运算符规定先求左侧运算对象的值,只有当左侧运算对象的值为真时才继续求右侧运算对象的值。另外3种分别是逻辑或(||)运算符,条件(?:)运算符,逗号(,)运算符。
运算对象的求值顺序与优先级和结合律无关,在一条形如f()+g()*h()+j()的表达式中。优先级规定,g()和h()的返回值相乘;结合律规定,f()的返回值先与g()和h()的乘积相加,所得结果再与j()的返回值相加;对于这些函数的调用顺序没有明确规定。
注意:如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。除非改变运算对象的子表达式本身就是另外一个子表达式的运算对象。例如*++iter就不会有问题。