p131~p135:
1、除非必要否则不使用后缀加加(减减),会有额外的性能开销。
2、混用解引用和递增运算符。*pointer++,后缀运算符优先于解引用运算符。
3、运算对象可按任意顺序求值,即使是在赋值号两侧也无法确定究竟哪边先求。
p133
1、点运算符和箭头运算符。ptr->mem等价于(*ptr).mem。
2、解引用运算符*优先级低于点运算符.!!!别写*p.size()这样的表达式。(等价于*(p.size()))
p134
1、条件运算符。cond ? expr1 : expr2;先判断cond的真假,然后根据真假决定计算哪一条表达式。
2、嵌套条件运算符。
#include<iostream> int main() { int grade; std::cin >> grade; std::cout << ((grade > 90) ? "high pass" : (grade < 60) ? "fail" : "pass") << std::endl; return 0; }
3、条件运算符满足右结合律。
4、条件运算符的优先级非常低,通常要在两段加括号:(cond ? expr1 : expr2)。
练习 4.17
练习 4.18
跳过第一个元素,从第二个元素开始输出。
练习 4.19
(a)确保ptr指针非空,判断ptr指向元素非零,最后将ptr移动到下一位。
(b)假设ival的值为0,则原式等价与“0 && 1”。
(c)前两个表达式属于短路求值,运算顺序确定,而这个表达试的行为是未定义的:无法确定运算顺序。
改为:vec[ival+1] <= vec[ival]
练习 4.20
a 合法,访问*iter后iter移动到下一个元素。
b 非法,访问*iter,之后将*iter这个元素+1,由于是字符串所以加1操作非法。
c 非法,点运算符优先级高,应该改为(*iter).empty()。
d 合法
e 非法
f 合法
练习 4.21
#include<iostream> #include<vector> int main() { std::vector<int> ivec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; for (int &x : ivec) { (x % 2 == 1) ? x *= 2 : x; } for (int &x : ivec) { std::cout << x << std::endl; } return 0; }
练习 4.22
1
#include<iostream> int main() { int grade; std::cin >> grade; std::cout << ((grade > 90) ? "high pass" : (grade > 75) ? "pass" : (grade > 60) ? "low pass" : "fail") << std::endl; return 0; }
2
#include<iostream> using std::cout; using std::endl; int main() { int grade; std::cin >> grade; if (grade > 90) { cout << "high pass" << endl; } else if (grade > 75) { cout << "pass" << endl; } else if (grade > 60){ cout << "low pass" << endl; } else { cout << "fail" << endl; } return 0; }
版本2更容易理解一些。
练习 4.23
#include<iostream> #include<string> using std::string; int main() { string s = "word"; // 错误的表达式:string pl = s + s[s.size() - 1] == 's' ? "" : "s"; // 下标运算符[]的优先级最高,最先计算,之后是+、==、?:、= // 之所以会错是因为按照这个运算顺序会把字符串s + (s[s.size() - 1]和字符's'比较,这是非法的。 string pl = s + (s[s.size() - 1] == 's' ? "" : "s"); std::cout << pl << std::endl; return 0; }
练习 4.24
布吉岛。