2010/11/4
关键字:算术表达式
零散知识点
1. 短路求值,&&和||.
2. bool字面值的true为1,flase为0
if (val) //正确
...
if (val == true)//错误
...
3. 位操作符操作signed的整型时,系统无法确保如何处理其操作数的符号位.所以强烈建议使用unsigned类型.
int n = -23;
n = n << 2; //有符号整型移位操作时可能会插入符号位的副本或0,视具体实现而定
4. 移位操作的右操作数不可以是负数,而且必须是严格小于左操作数位数的值.否则,操作的效果未定义.
int i = 1 << -3; //移位操作的右操作数不能为负数,VC8下编译警告
char c = 1 >> 9; //右操作数不能大于左操作数的最大位数,运算效果未定义,VC8下为0
c = 1 << 9; //右操作数不能大于左操作数的最大位数,VC8下运算结果为0
5. 建议使用bitset代替低级位操作.bitset对象不受unsigned数的位数影响,并且更容易阅读、书写,减少出错的机会.
6. 不用刻意去记操作符的优先级,用()搞定,唯一的问题是不够简洁.
7. 前置自增和自减操作符效率高于后置的.尽量使用前置,也可以减少出错的机会.
8. 逗号表达式的结果是最右边表达式的值.
int j = i=0, i=5; //j为5
sizeof
sizeof有三种语法形式
sizeof(type name)、sizeof(expr)、sizeof expr
sizeof计算结果依赖于所涉及的类型:
char *p = "123";
int i = sizeof p; //指针的大小4
i = sizeof *p; //指针所指向的对象的大小,4
i = sizeof "123"; //常量表达式的大小4,别忘了null
i = sizeof fun(); //函数返回值类型的大小
i = sizeof &fun; //函数地址的大小4
int &ref = i;
i = sizeof ref; //引用的大小即为对象的大小4
i = sizeof char; //错误
i = sizeof(char); //正确1
int array[10];
i = sizeof array; //数组实际占的内存的大小4*10
i = sizeof(*array); //数组第一个元素的大小,及元素类型的大小4
i = sizeof(array) / sizeof(*array); //数组内元素个数10
操作符计算顺序
C++中规定了操作数计算顺序的操作符有4个:&&、||、条件操作符(?:)、逗号操作符.其他都未定义.如果操作符顺序未定,必须避免操作符的操作数涉及同一对象并改变其值的情况.
典型的陷阱:
int array[10];
int i = 0;
if (array[i++] > array[i])
//...
有两种顺序执行,视具体编译器:
1. 先左后右.实际是array[i]与array[i+1]比较,详细的计算顺序为
a. 计算array[i](左边)
b. i自增
c. 计算array[i](右边)
d. 比较左边和右边
2. 先右后左.实际是array[i]与array[i]比较,详细的计算顺序为
a. 计算array[i](右边)
b. 计算array[i](左边)
c. i自增
d. 比较左边和右边
调整后的语句:
int array[10];
int i = 0;
if (array[i+1] > array[i])
//...
++i;
处理复合表达式的建议
1. 使用圆括号()控制操作符的顺序和优先级
2. 如果要修改操作数的值,不要在同一语句的其他地方使用该操作数,可以用分开两个独立语句的方式避免.
第2条建议有个例外,如果一个子表达式修改操作数的值,结果会作用域另一个表达式,则是被允许的.例如*++iter,不过使用圆括号更好*(++iter).