一、简洁可以成为一种美德
cout<<*iter++<<endl;
等价于:
cout<<*iter<<endl;
++iter;
运算对象可按任意顺序求值
for(auto it = s.begin();it != s.end() && !isspace(*it); ++it)
*it = toupper(*it);
在上述程序中,我们把解引用it和递增it两项任务分开来完成。如果用一个看似等价的while循环进行替代:
while(beg != s.end() && !isspace(*beg))
*beg = toupper(*beg++);
将产生未定义的行为。问题在于:赋值运算符左右两端的运算对象都用到了beg,并且右侧的运算对象还改变了beg的值,所以该赋值语句是未定义的。编译器可能按照下面任意一种思路处理该表达式:
*beg = toupper(*beg); // 如果先求左侧的值
*(beg+1) = touopper(*beg); // 如果先求右侧的值
二、运算符
2.1成员访问运算符:
ptr->mem等价于(*ptr).mem;
2.2条件运算符:
cond ? expr1: expr2;
string finalgrade = (grade < 60) ? "fail": "pass";
2.3位运算符:
~ : 位求反 ~expr
<<: 左移 expr1 << expr2
>>: 右移 expr1 >> expr2
&: 位与 expr1 & expr2
^: 位异或 expr1 ^ expr2
|: 位或 expr1 | expr2
2.4sizeof运算符:
sizeof运算符返回一条表达式或一个类型名字所占的字节数。sizeof运算符满足右结合律,其所得的值使一个size_t类型的常量表达式。
sizeof(type)
sizeof expr
2.5类型转换
隐式转换:类型之间可以自动转换,无需程序员。
显式转换:
static_cast任何具有明确定义的类型转换,只要不包含底层const都可以使用static_cast:
double slope = static_cast<double>(j) / i;
const_cast,const_cast只能改变运算对象的底层const:
const char *pc;
char *p = const_cast<char*>(pc);
reinterpret_cast通常未运算对象的位模式提供较低层次上的重新解释。!!!使用reinterpret_cast是非常危险的!!!