《C++ Primer》第4章 4.5节习题答案

《C++ Primer》第4章 表达式

4.5节 递增运算符

练习4.17:说明前置递增运算符和后置递增运算符的区别。
【出题思路】
C++实现了两种递增(递减)运算符:即前置版本和后置版本,二者的工作机理有所区别,一般来说前置版本是更好的选择。
【解答】
递增和递减运算符有两种形式:前置版本和后置版本。前置版本首先将运算对象加1(或减1),然后把改变后的对象作为求值结果。后置版本也将运算对象加1(或减1),但是求值结果是运算对象改变之前那个值的副本。这两种运算符必须作用于左值运算对象。前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回。
我们的建议是,除非必须,否则不用递增(递减)运算符的后置版本。前置版本的递增运算符避免了不必要的工作,它把值加1后直接返回改变了的运算对象。与之相比,后置版本需要将原始值存储下来以便于返回这个未修改的内容。如果我们不需要修改之前的值,那么后置版本的操作就是一种浪费。对于整数和指针类型来说,编译器可能对这种额外的工作进行了一定的优化;但是对于相对复杂的迭代器类型来说,这种额外的工作就消耗巨大了。建议养成使用前置版本的习惯,这样不仅不需要担心性能问题,而且更重要的是写出的代码会更符合编程人员的初衷。

练习4.18:如果第132页那个输出vector对象元素的while循环使用前置递增运算符,将得到什么结果?
【出题思路】
前置递增运算符先将运算对象加1,然后把改变后的对象作为求值结果;后置递增运算符也将运算对象加1,但是求值结果是运算对象改变之前那个值的副本。简言之,如果在一条表达式中出现了递增运算符,则其计算规律是:++在前,先加1,后参与运算;++在后,先参与运算,后加1。
【解答】
基于上述分析,本题不应该把while循环的后置递增运算符改为前置递增运算符。如果这样做了,会产生两个错误结果:一是无法输出vector对象的第一个元素;二是当所有元素都不为负时,移动到最后一个元素的地方,程序试图继续向前移动迭代器并解引用一个根本不存在的元素。

练习4.19:假设ptr的类型是指向int的指针、vec的类型是vector<int>、ival的类型是int,说明下面的表达式是何含义?如果有表达式不正确,为什么?应该如何修改?
(a)ptr != 0 && *ptr++            (b)ival++ && ival
(c)vec[ival++] <= vec[ival]
【出题思路】
本题旨在考查递增运算符与关系运算符、逻辑运算符、解引用运算符的优先级关系,读者也需要理解后置递增运算符的计算规则。
【解答】
(a)的含义是先判定指针ptr是否为空,如果不为空,继续判断指针ptr所指的整数是否为非0数。如果非0,则该表达式的最终求值结果为真;否则为假。最后把指针ptr向后移动一位。该表达式从语法上分析是合法的,但是最后的指针移位操作不一定有意义。如果ptr所指的是整型数组中的某个元素,则ptr可以按照预期移动到下一个元素。如果ptr所指的只是一个独立的整数变量,则移动指针操作将产生未定义的结果。(b)的含义是先检查ival的值是否非0,如果非0继续检查(ival+1)的值是否非0。只有当两个值都是非0值时,表达式的求值结果为真;否则为假。在4.1.3节中我们学习到,如果二元运算符的两个运算对象涉及同一个对象并改变对象的值,则这是一种不好的程序写法,应该改写。所以按照程序的原意,本式应该改写成ival &&(ival + 1)。
(c)的含义是比较vec[ival]和vec[ival + 1]的大小,如果前者较小则求值结果为真,否则为假。与(b)式一样,本式也出现了二元运算符的两个运算对象涉及同一个对象并改变对象值的情况,应该改写为vec[ival] <= vec[ival + 1]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值