C++ Primer(第五版)|练习题答案与解析(第四章:表达式)
本博客主要记录C++ Primer(第五版)中的练习题答案与解析。
参考:C++ Primer
C++ Primer
练习题4.1
表达式5+10*20/2的值是多少?
105,P122
练习题4.2
根据4.12节,在下述表达式的合理位置添加括号,使得添加括号后运算对象的组合顺序与添加前一致。
(a) *vec.begin()
–> (*vec.begin())
(b) *vec.begin() + 1
--> (*vec.begin() + 1)
练习题4.4
在下列表达式添加括号,说明求值过程,编写代码验证
表达式:12 / 3 * 4 + 5 * 15 +24 % 4 / 2
–>(12 / 3 * 4) + (5 * 15) +(24 % 4 / 2)=91
练习题4.5
写出下列表达式求值结果
(a)-30 * 3 + 21 / 5 = -86
(b)-30 + 3 * 21 / 5 = -18
(c)30 / 3 * 21 % 5 = 0
(d)-30 / 3 * 21 % 4 = -2
练习题4.6
写出一个表达式,确定一个整数是奇数还是偶数
int num = 10;
num % 2 == 1 ? cout << "odd" << endl : cout << "even" << endl;
练习题4.7
溢出是何含义,写出三条会溢出的表达式。
溢出,当计算结果超出该类型所能表示的范围就会产生溢出。
表达式:short c = (short)65538; // print c = 2, overflow
练习题4.8
说明在逻辑与、逻辑或及相等运算符中运算对象求值的顺序。
&& (逻辑与) 优先级高于||(逻辑或),执行短路求值。相等性运算符则正常计算两个运算对象的值。
练习题4.9
解释下面的if语句中条件部分的判断过程。
const char *cp = "Hello World";
if (cp && *cp);
// cp是一个地址,不为0。再取*cp的值,为一个字符串,是"Hello World",不为0.最后两者相与,值为True。
练习题4.10
为while循环写一个条件,使其从标准输入中读取整数,遇到42时停止。
代码:
#include <iostream>
using namespace std;
int main()
{
int number = 0;
while (cin >> number)
{
if (42 == number)
{
break;
}
}
}
测试:
1
2
42
练习题4.11
书写一条表达式用于测试4个值a, b, c, d的关系,确保a大于b,b大于c,c大于d。
表达式:if ((a>b) && (b>c) && (c>d))
练习题4.12
假设i,j和k是三个整数,说明表达式i != j < k。
含义:“先取i值,再计算j < k是否成立,成立为大于0的数,否则为0。再计算i != (j < k) 。”
练习题4.13
下述语句中,赋值完i和d的值分别是多少?
语句:int i; double d;
(a)d = i = 3.5;
i = 3, d = 3; i = 3.5, 将3.5隐式转化为整型。
(b)i = d = 3.5;
d = 3.5, i = 3,因为i是整型。
练习题4.14
执行下述if语句会发生什么情况
(a)if (42 = i)
会报错,42是常量,不能赋值。
(b)if (i = 42)
将42赋值给i,if条件为真。
练习题4.15
下面的赋值是非法的,为什么,应该如何修改?
double dval; int ival; int *pi;
dval = ival = pi = 0
pi是地址,不能把指针的值赋值给int(P129)
修改为:dval = ival = *pi = 0;
练习题4.16
尽管下面的语句合法,但它们实际执行的行为可能和预期不一样,为什么?应如何修改?
(a)if (p = getPtr() != 0){}
这是因为赋值运算优先级较低(P130),可能会先判断!=, 再把结果赋值给p,修改为:if ((p = getPtr) != 0)
(b)if (i = 1024)
会把1024赋值给i,再进行判断,改为if (i == 1024)
练习题4.17
说明前置递增运算符和后置递增运算符的区别。
前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回(P132)。
练习题4.18
如果132页那个输出vector对象元素的while循环使用前置递增运算符,会得到什么结果?
会先向后移动一个元素,再输出移动后的值。输出范围为第二个元素到最后一个元素的下一个元素。由于最后一个元素的下一个元素未知,所以会访问到未知内存。
练习题4.19
假设ptr的类型是指向int的指针,vec的类型是vector、ival的类型是int,说明下面的表达式是何含义?如果有表达式不正确,为什么?应该如何修改?
(a)ptr != 0 && *ptr++;
判断ptr是否为空,并且ptr指向的值是否为0;
(b)ival ++ && ival;
判断ival及ival++是否为空。运算的顺序为,根据短路求值,先判断ival,再计算++,再进行&&
(c)vec[ival++] <= vec[ival];
运算顺序未知,比如ival = 1,编译器有可能先算vec[ival++],得到ival=2,再计算vec[ival],这样就得不到预期结果(P133)。因此改成vec[ival+1] <= vec[ival];
练习题4.20
假设iter的类型是vector::iterator, 说明下面的表达式是否合法,如果合法,表达式的含义是什么?如果不合法,错在何处?
(a)*iter++;
合法,先对iter+1,再返回iter初始值的副本,再对该副本进行解引用
(b)(*iter)++;
不合法,不能对string类型进行++操作。
(c)*iter.empty();
不合法,不能对指针指向的值判空。可改为(*iter).empty();
(d)iter->empty();
合法
(e)++*iter;
不合法,先求*iter,在进行++操作,不能对string类型做++操作,可改为 *(++iter);
(f)iter++->empty();
合法,++和->的优先级一样,所以遵循自左向右结合,先算iter++的值,返回iter初始值的副本,再进行empty()判断。iter->empty等价于(*iter).empty
练习题4.21
编写程序,使用条件运算符从vector中找到哪些元素是奇数,然后将奇数翻倍。
代码:
#include <iostream>
#