今天读了C++Primer中的表达式一章,特来整理有关运算符的知识要点。
首先是算术运算符:
所有的表达式的运算顺序与三点有关:求值顺序、优先级、结合律。
其中优先级和结合律在书中147页可以查到,至于求值顺序目前书中还没有细讲,暂且不做描述。
溢出:造成溢出有两个原因:
其一是因为数学性质本身(例如除数是0)
其二是当计算结果超出该类型所能表示的范围是就会产生溢出
运算符%:取模/取余运算符
m%n = m - (m/n)*n
参与取余运算的运算对象必须是整数类型。
我记得当初自己学C语言的时候规定的是:取模运算中的商是向负无穷取整的
但是C++11新标准规定商一律向0取整。
如果m%n不等于0,则他的符号和m相同,除了-m导致溢出的特殊情况,其他时候(-m)/n 和 m/(-n)都等于 -(m/n), m%(-n)等于m%n, (-m)%n = - (m%n)。
逻辑和关系运算符:
短路求值:对于逻辑与和逻辑或运算符来说,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。
书中在这一部分有一句话,说:因为text的元素是string对象,可能非常大,所以将s声明成引用类型可以避免对元素的拷贝
因为使用范围for循环遍历输出text中每一个元素时,如果不使用引用,则编译器会生成一个临时变量,临时变量的初始值是元素的值,再将临时变量赋值给cout,效率非常低,而使用引用则不会有创建临时变量这一过程。
类似的,书中在相等性测试中也有提到:不要使用if(val == true)这一形式,会增加一个布尔类型向其他类型转换的过程。
复合运算符会求值一次,而普通运算符会求值两次。
递增和递减运算符:
前置版本是将运算结果返回,而后置版本是运算对象的副本作为结果返回后再进行递增/递减操作。
sizeof运算符:
sizeof运算符返回一条表达式或一个类型名字所占的字节数,所得的值是一个size_t类型的常量表达式。
sizeof的运算符有两种形式:
sizeof(类型)
sizeof 表达式
其中对char 类型会得到1 ;
对数组进行sizeof运算,则是将数组中每个元素进行sizeof运算后求和。
对指针执行sizeof运算,得到的是指针本身所占空间的大小,其中64位机器所占的是8字节,32位机器所占的是4字节