练习4.1
表达式 5 + 10 * 20 / 2 的求值结果是多少?
105
练习4.2
根据4.12节中的表,在下述表达式的合理位置添加括号,使得添加括号后运算对象的组合顺序与添加括号前一致。
- (a) *vec.begin()
- (b) *vec.begin() + 1
(a)(vec.begin());
(b)((vec.begin())) + 1。
练习4.3
C++语言没有明确规定大多数二元运算符的求值顺序,给编译器优化留下了余地。这种策略实际上是在代码生成效率和程序潜在缺陷之间进行了权衡,你认为这可以接受吗?请说出你的理由。
可以接受,效率是C++最大的优势。我们要做的是避免类似代码的产生。
练习4.4
在下面的表达式中添加括号,说明其求值过程及最终结果。编写程序编译该(不加括号的)表达式并输出结果验证之前的推断。
12 / 3 * 4 + 5 * 15 + 24 % 4 / 2
(((12/3)4)+(515))+((24%4)/2)
91
练习4.5
写出下列表达式的求值结果。
-30 * 3 + 21 / 5 // -90+4 = -86
-30 + 3 * 21 / 5 // -30+63/5 = -30+12 = -18
30 / 3 * 21 % 5 // 10*21%5 = 210%5 = 0
-30 / 3 * 21 % 4 // -10*21%4 = -210%4 = -2
(a)-86 (b)-18
(c)0 (d)-2
练习4.6
写出一条表达式用于确定一个整数是奇数还是偶数。
i % 2 == 0 ? “even” : “odd”
练习4.7
溢出是何含义?写出三条将导致溢出的表达式。
short svalue = 32767; ++svalue; // -32768
unsigned uivalue = 0; --uivalue; // 4294967295
unsigned short usvalue = 65535; ++usvalue; // 0
练习4.8
说明在逻辑与、逻辑或及相等性运算符中运算对象的求值顺序。
逻辑与、逻辑或运算符都是先求左侧运算对象的值再求右侧运算对象的值,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。
逻辑与:当且仅当左侧运算对象为真时才对右侧运算对象求值。
逻辑或:当且仅当左侧运算对象为假时才对右侧运算对象求值。
相等性运算符:求值顺序不明确。
练习4.9
解释在下面的if语句中条件部分的判断过程。
const char *cp = "Hello World";
if (cp && *cp)
当指针cp不为空时,才判断解引用cp的值。
我们知道,cp不为空,&&左侧为true;*cp为’H’,右侧也为真,所以if语句为真。
练习4.10
为while 循环写一个条件,使其从标准输入中读取整数,遇到 42 时停止。
while(cin >> i && i != 42)
练习4.11
书写一条表达式用于测试4个值a、b、c、d的关系,确保a大于b、b大于c、c大于d。
a > b && b > c && c > d
练习4.12
假设i、j 和k 是三个整数,说明表达式 i != j < k 的含义。
根据4.12运算符优先级表我们得到<的优先级大于!=,所以j < k得到bool值,bool值再与i比较是否不等。等价于:i != (j < k)
练习4.13
在下述语句中,当赋值完成后 i 和 d 的值分别是多少?
int i; double d;
d = i = 3.5; // i = 3, d = 3.0
i = d = 3.5; // d = 3.5, i = 3
(a)i=3,d=3 (b)i=3,d=3.5
练习4.14
执行下述 if 语句后将发生什么情况?
if (42 = i) // 编译错误。赋值运算符左侧必须是一个可修改的左值。而字面值是右值。
if (i = 42) // true.
非法操作;
if判断为真。
练习4.15
下面的赋值是非法的,为什么?应该如何修改?
double dval; int ival; int *pi;
dval = ival = pi = 0;
pi改为*pi
练习4.16
尽管下面的语句合法,但它们实际执行的行为可能和预期并不一样,为什么?应该如何修改?
if (p = getPtr() != 0)
if (i = 1024)
(a)if((p = getPtr()) != 0);(b)if(i == 1024)。
练习4.17
说明前置递增运算符和后置递增运算符的区别。
前置递增运算符:将运算对象加1,然后将改变后的对象作为求值结果;
后置递增运算符:将运算对象加1,但是求值结果是运算对象改变之前那个值的副本。
练习4.18
如果132页那个输出vector对象元素的while循环使用前置递增运算符,将得到什么结果?
循环第一次解引用第二个地址;循环到最后一次时,将会解引用vector最后一个地址的后一个位置(等同于v.end())
练习4.19
假设 ptr 的类型是指向 int 的指针、vec 的类型是vector、ival 的类型是int,说明下面的表达式是何含义?如果有表达式不正确,为什么?应该如何修改?
(a) ptr != 0 && *ptr++
(b) ival++ &&