C++ Primer 中文第 5 版练习答案 第 6 章 函数(27~56)

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

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


#include <iostream>
#include <initializer_list>
using namespace std;
int sum(initializer_list<int> list) {
	int sum = 0;
	for (auto it = list.begin(); it != list.end(); ++it)
		sum += *it;
	return sum;
} 
int main() {
	cout << sum({1,2,3,4,5}) << endl;
	return 0;
} 
  1. const string&类型
  2. 应该声明成引用,避免拷贝。
  3. 返回局部对象的引用无效。返回属于局部对象的常量的引用无效。(总之,如果要返回引用,引用的对象应当在被调函数之前就存在,或者是静态全局变量)
  4. 合法。为ia中的元素分别赋值 0 ~ 9
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int> &nums, int index) {
	if (index == nums.size())	return;
	cout << nums[index] << endl; 
	print(nums, index + 1);
} 
int main() {
	vector<int> nums = {1, 2, 3, 4, 5};
	print(nums, 0); 
	return 0;
}
  1. 参数是正数的话比原来多递归一层并得到正确答案;参数是负数的话无限递归。
  2. val--返回的是递减前的值,如果一定要用递减的话,可以用--val
  3. string (&func(void))[10];
  4. 当确定返回值类型和现有变量相同的时候我选decltype,否则选尾置返回类型。
// 类型别名:
typedef string arrT[10];
using attT = string[10]; // 和上一行等价
arrT& func(void);

// 尾置返回类型
auto func(void) -> string(&)[10]

// decltype 关键字
string whatever[10];
decltype(whatever) &func(void);
decltype(odd) &arrPtr(int i) {
	return (i % 2) ? odd : even;
}
  1. a. 非法。顶层const是重复声明;
    b. 非法。只有返回类型不同不足以实现重载;
    c. 合法。
  2. a. 正确;
    b. 错误。默认实参只能出现在后面,要么改变参数顺序,要么三个参数都写上默认实参。
  3. a. 非法,形参ht没有被初始化;
    b. 合法。
    c. 和初衷不符,'*'被传递给形参wd,并且发生了隐式的类型转换。
#include <iostream>
#include <string>
using namespace std;

string make_plural(size_t ctr, const string &word, const string &ending = "s") {
	return (ctr > 1) ? word + ending : word; 
} 

int main() {
	cout << make_plural(1, "success", "es") << endl; 
	cout << make_plural(1, "failure") << endl; 
	cout << make_plural(2, "success", "es") << endl; 
	cout << make_plural(2, "failure") << endl; 
	return 0;
} 
  1. a. 内联函数的定义和声明都放在头文件中;
    b. 声明一般放在头文件中。
inline bool isShorter(const string &s1, const string &s2) {
	return s1.size() < s2.size();
}
  1. 简单且非递归的函数可以写成内联函数,一般较长的函数和递归函数不应该写成内联函数。(但是写了也没关系,这只是个请求,最终在实现上是不是内联还是编译器决定的)
  2. 不能。形参的类型const string&并不是字面值类型。
  3. 我写的递归函数中vector长度不发生变化,所以就每次递归显示当前的下标。
#include <iostream>
#include <vector>
using namespace std;

//#define NDEBUG

void print(vector<int> &nums, int index) {
#ifndef NDEBUG
	cout << "index = " << index << endl;
#endif
	if (index == nums.size())	return;
	cout << nums[index] << endl; 
	print(nums, index + 1);
} 
int main() {
	vector<int> nums = {1, 2, 3, 4, 5};
	print(nums, 0); 
	return 0;
}
  1. 循环的含义:不断地用字符串s接收输入数据,直到s == sought或者cin到达EOF为止。
    assert使用不合理,如果cin到达EOF的话程序就会在此处终止运行,应该用assert(s == sought || !cin)更好
  2. 候选函数是一类函数的集合,这类函数具备两个特征:一是与被调用的函数同名,二是其声明在调用点可见;
    可行函数也具有两个特征:一是其形参数量与本次调用提供的实参数量相等,二是每个实参的类型与对应的形参类型相同,或者能转换成形参的类型。
  3. a. 不合法。调用具有二义性;
    b. 合法。void f(int);是最佳匹配;
    c. 合法。void f(int, int);是最佳匹配;
    d. 合法。void f(double, double = 3.14);是最佳匹配;
#include <iostream>
using namespace std;

void f() {
	cout << "I am f()" << endl; 
}
void f(int) {
	cout << "I am f(int)" << endl; 
} 
void f(int, int) {
	cout << "I am f(int, int)" << endl; 
} 
void f(double, double = 3.14) {
	cout << "I am f(double, double = 3.14)" << endl; 
} 

int main() {
//	f(2.56, 42);	// illegal
	f(42);
	f(42, 0);
	f(2.56, 3.14); 
	return 0;
}
  1. a. 3. 通过类型提升实现的匹配;
    b. 4. 通过算数类型转换实现的匹配。
  2. a. 合法,实现函数重载。(因为是底层const所以合法)
    b. 合法,同上;
    c. 非法,顶层const的区别不足以实现函数重载。
#include <iostream>
#include <vector>
using namespace std;
int myAdd(int a, int b){
	return a+b;
} 
int mySub(int a, int b){
	return a-b;
} 
int myMul(int a, int b){
	return a*b;
} 
int myDiv(int a, int b){
	return a/b;
} 
int main(){
	using p = int (*)(int a, int b);
	vector<p> cal = {myAdd, mySub, myMul, myDiv};
	int a = 2, b = 3;
	for (auto f : cal)
		cout << f(a,b) << endl; 
	return 0;
} 
  1. 见 54
  2. 见 54
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值