C++ Primer 中文第 5 版练习答案 第 4 章 表达式(1~38)

C++ Primer 中文版(第 5 版)练习解答合集

自己写的解答,如有错误之处,烦请在评论区指正!


  1. 105
  2. a. *(vec.begin())
    b. (*(vec.begin())) + 1
  3. 可以接受,就个人习惯而言,大多数情况下,“改变对象的值”和“让对象参与运算”这两件事情是不发生在同一个语句的,除了一些常见的安全做法,例如a[cnt++] = val;或者*p++ = *q++;等等。
  4. 12 / 3 * 4 == 4 * 4 == 16
    5 * 15 == 75
    24 % 4 / 2 == 24 % 2 == 0
    12 / 3 * 4 + 5 * 15 + 24 % 4 / 2 == 16 + 75 + 0 == 91
  5. a. -86
    b. -18
    c. 0
    d. -2
  6. x % 2或者x & 1,结果是0就是偶数,否则奇数。
  7. 溢出指计算结果超过了该数据类型所能表示的范围。例如:
char ch = '0';
int a = 99999999
ch += a;
a *= a;
a *= -a;
  1. 逻辑与:先求&&左边的表达式,如果返回值是true,再求右边的,如果左边的返回值是false,右边的就不求了;
    逻辑或:先求||左边的表达式,如果返回值是false,再求右边的,如果左边的返回值是true,右边的就不求了;
    相等性运算符:先求右边,再求左边。
  2. 先判断cp != nullptr
    a. 如果为true再判断*cp != '\0',如果还是true就执行if后面的语句块;
    b. 如果为false就直接跳过if后面的语句块。
  3. while ((cin << input) && input != 42)
  4. a > b && b > c && c > d
  5. 如果j < k返回值是true,该语句等价于判断i的值是否是1
    如果j < k返回值是false,该语句等价于判断i的值是否是0
  6. a. i的值:3d的值:3.0
    b. i的值:3d的值:3.5
  7. if (42 = i)会报错,42不是一个左值;
    if (i = 42)会给i赋值42,且该条件判断永远正确,因为赋值运算返回左侧运算对象i,值是42,即true
  8. 指针类型无法转换为int类型,改为dval = ival = 0; pi = 0;
  9. a. 赋值运算符=的优先级比!=低,改成if ((p = getPtr()) != 0)或者if (p = getPtr())
    b. 不要混用赋值运算符和相等运算符,改成if (i == 1024)
  10. 前置递增运算符的求值结果是递增后的值,后置递增运算符的求值结果是递增前的值。并且理论上后置递增运算符更加消耗资源。
  11. 首先v[0]不会被输出,其次会试图解引用尾后指针,造成越界行为。
  12. a. 含义:ptr不是空指针且ptr递增前所指对象的值不是0,顺便将ptr指向下一个vector<int>元素;
    b. 含义:先判断ival递增前不是0并将其递增,如果递增前不是0的话再判断递增后不是0
    c. 无法保证<=两侧的求值顺序,改成vec[ival] <= vec[ival + 1]; ++ival;
  13. a. 合法,iter递增,并解引用其递增前的iter
    b. 不合法,原意为将iter所指对象递增,但是iter所指对象是string类型,没有++运算符;
    c. 不合法,iter是个迭代器,没有名为empty的成员,改为(*iter).empty()
    d. 合法,等价于(*iter).empty()
    e. 不合法,iter所指对象是string类型,没有++运算符;
    f. 合法,将iter递增,并调用递增前所指对象的empty成员。
#include <iostream>
#include <vector>
using namespace std;
int main() {
	vector<int> ivec = {1, 2, 3, 555, 6666};
	for (auto &i : ivec)
		i = i % 2 ? 2 * i : i;
	for (auto i : ivec)
		cout << i << endl;
	return 0;
} 
  1. 当嵌套层数不多的时候,条件运算符更简洁,嵌套层数多的时候if-else可读性更好。在这里更倾向于用if-else
// 条件运算符
finalgrade = (grade > 90) ? "high pass"
						  : (grade < 60) ? "fail" 
						  				 : (grade < 75) ? "low pass" : "pass";

// if-else if
if (grade > 90)
	finalgrade = "high pass";
else if (grade < 60)
	finalgrade = "fail";
else if (grade < 75)
	finalgrade = "low pass";
else
	finalgrade = "pass";
  1. 问题在于条件运算符的优先级要比赋值高,所以应该加括号:
    string pl = (s + s[s.size() - 1] == 's' ? "" : "s");
  2. 用括号来表示左结合律的求值顺序:
finalgrade = ((grade > 90) ? "high pass" : (grade < 60)) ? "fail" : "pass";
  1. 二进制0100 0000的值是十进制的64,即@
  2. 只有 16 位,但是有 30 个学生,空间不够。
  3. a. 3
    b. 7
    c. true
    d. true
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main(){
	cout << "sizeof(string): " << sizeof(string) << endl;
	cout << "sizeof(char): " << sizeof(char) << endl;
	cout << "sizeof(short): " << sizeof(short) << endl;
	cout << "sizeof(int): " << sizeof(int) << endl;
	cout << "sizeof(unsigned int): " << sizeof(unsigned int) << endl;
	cout << "sizeof(long): " << sizeof(long) << endl;
	cout << "sizeof(long long): " << sizeof(long long) << endl;
	cout << "sizeof(float): " << sizeof(float) << endl;
	cout << "sizeof(double): " << sizeof(double) << endl;
	cout << "sizeof(vector<int>): " << sizeof(vector<int>) << endl;
	cout << "sizeof(vector<string>): " << sizeof(vector<string>) << endl;
	return 0;
} 

本地输出:

sizeof(string): 8
sizeof(char): 1
sizeof(short): 2
sizeof(int): 4
sizeof(unsigned int): 4
sizeof(long): 4
sizeof(long long): 8
sizeof(float): 4
sizeof(double): 8
sizeof(vector<int>): 24
sizeof(vector<string>): 24

  1. 输出分别是102,因为sizeod(数组名)会返回整个数组的大小,sizeof(p)会返回指针本身的大小,sizeof(*p)指向指针指向的空间的大小。
#include <iostream>
using namespace std;
int main(){
	int x[10];
	int *p = x;
	cout << sizeof(x)/sizeof(*x) << endl;
	cout << sizeof(p)/sizeof(*p) << endl;
	return 0;
} 
  1. a. (sizeof x) + y
    b. sizeof ((p->mem)[i])
    c. (sizeof a) < b
    d. sizeof (f())
  2. 因为理论上后置版本更消耗资源(不考虑优化的前提下,编译器需要先暂时保存对象递增 / 递减前的值,在递增 / 递减后返回之前的值),这个程序写成前置后置在语法上并无所谓。后置版本代码:
vector<int>::size_type cnt = ivec.size();
for (vector<int>::size_type ix = 0; ix != ivec.size(); ix++, cnt--)
	ivec[ix] = cnt;
  1. 同时用下标和指针遍历数组。在循环体中,ia[ix]*ptr指的都是当前正在遍历的元素。
  2. 等同于这个加上括号的写法:
    (someValue ? (++x, ++y) : --x), --y
  3. a. float转成bool
    b. ival先转成float,相加的结果再转成double
    c. cval转成int,相乘的结果再转成double
  4. a. 'a'先转成int,相加结果再转成char
    b. 注意,书 P36 页提到浮点型字面值默认是double类型。所以ival先转成doubleui先转成int再转成double,最终赋值运算符右侧的运算结果转成float
    c. ui先转成int再转成float,最终赋值运算符右侧的运算结果转成double
    d. ival转成float,左侧+的运算结果转成double=右侧的运算结果转成char
  5. i *= static_cast<int>(d);
  6. a. pv = reinterpret_cast<void*>(const_cast<string*>(ps)); 注意要先去掉const属性再转换,否则报错;
    b. i = static_cast<int>(*pc);
    c. pv = static_cast<void*>(&d);
    d. pc = reinterpret_cast<char*>(pv);
  7. 定义doouble类型的变量slope,并对其初始化:将j/i的结果强制转换成double类型后再赋给slope
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值