第六章课后习题答案

//6.1
形参出现在函数定义的地方,形参规定了一个函数所接受的数据的类型和数量
实参出现在函数调用的地方,实参主要是为了初始化形参
//6.2
(a)函数体返回结果类型和返回值类型不一致且不能自动转换
(b)缺少返回值
(c)缺少左花括号
(d)缺少一对花括号
//6.3
int fact(int val)
{
	if (!val)
		return 1;
	return val * fact(val - 1);
}
//6.4
int fact(int val)
{
	if (!val)
		return 1;
	return val * fact(val - 1);
}
int main()
{
	int num;
	cin << "输入一个数:";
	cin >> num;
	cout << fact(num);
	return 0;
}
//6.5
int abs(int val)
{
	return val > 0 ? val : -val;
}
//6.6
形参和定义在函数体内的变量统称为局部变量,它们对函数来说是局部的
函数体内的局部变量又分为普通局部变量和静态局部变量
静态局部变量的生命周期贯穿函数调用及之后的时间
void add(int a, int b)
{
	int result = a + b;
	static int cnt = 0;
	++cnt;
	cout << "该函数被执行了" << cnt << "次\n";
}
//6.7
int ret()
{
	static int cnt = -1;
	++cnt;
	return cnt;
}
//6.8
#ifdef CHAPTER6_H_
#define CHAPTER6_H_

int fact(int);
int abs(int);

#endif //CHAPTER6_H_
//6.9
//fact.cc
#include "Chapter6.h"
using namespace std;
int fact(int val)
{
	if (!val)
		return 1;
	return val * fact(val - 1);
}
//factMain.cc
#include <iostream>
#include "Chapter6.h"
int main()
{
	int num;
	cin << "输入一个数:";
	cin >> num;
	cout << fact(num);
	return 0;
}
//6.10
void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int a, b;
	int *pa = &a, *pb = &b;
	cin >> a >> b;
	swap(pa, pb);
	cout << a << b << endl;
	return 0;
}
//6.11
void reset(int &i)
{
	i = 0;
}
//6.12
void swap(int &a, int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a, b;
	cin >> a >> b;
	swap(a, b);
	cout << a << b << endl;
	return 0;
}
使用引用更加方便,不需要额外声明指针,也避免了指针拷贝
//6.13
void f(T)形参采用传值方式,实参的值被拷贝给形参
void f(&T)采用传引用,改变形参的值即改变实参的值
//6.15
为了避免拷贝长字符串就使用引用类型,同时因为只执行查询操作而不改变字符串内容,所以声明为常量引用
c是char,占用1字节,拷贝代价很低所以不需要引用
occur需要改变实参的值,所以声明为引用而且不能是常量
//6.16
参数不进行修改,最好设为const,并且设为const接受的实参类型也更多
改为bool is_empty(const string &s) { return s.empty(); }
//6.17
bool isHaveUp(const string &s)
{
	for (int i = 0; i < s.size(); i++)
		if (s[i] >= 'A' && s[i] <= 'Z')
			return true;
	return false;
}
void change(string &s)
{
	for (int i = 0; i < s.size(); i++)
		s[i] = tolower(s[i]);
}
//6.18
(a)bool compare(const matrix&, const matrix&);
(b)vector<int>::iterator change_val(int, vector<int>::iterator);
//6.19
(a)不合法,函数声明只有一个参数,调用却提供两个
(b)合法,字面值常量可以作为常量引用形参的值
(c)合法
(d)合法
//6.20
如果需要修改参数内容则设置为普通引用类型,否则设为常量类型
不这么做会导致:
1.给使用者误导,即程序允许修改实参内容
2.限制了该函数所能接受的实参类型,不能把const对象,字面值常量等传递给普通的引用形参
//6.21
int swap(int a, int *b)
{
	return (a > *b) : a ? *b;
}
//6.22
//第一种交换,值传递方式使得改变局限于函数内部
void swap1(int *p, int *q)
{
	int *temp = p;
	p = q;
	q = temp;
}
//第二种虽然也是值传递,但是通过解引用访问了内存,所以有改变
void swap2(int *p, int *q)
{
	int temp = *p;
	*p = *q;
	*q = temp;
}
//通过引用交换了指针
void swap3(int *&p, int *&q)
{
	int *temp = p;
	p = q;
	q = temp;
}
//6.23
void print1(const int* p)
{
	cout << *p << endl;
}
void print2(const int arr[], size_t size)
{
	for (int i = 0; i < size; i++)
		cout << arr[i] << endl;
}
void print3(const int *b, const int *e)
{
	for (auto q = b; q != e; q++)
		cout << *q << endl;
}
//6.24
没有问题,但是传入的数组必须正好只存10个数
//6.25
int main(int argc, char **argv)
{
	string str;
	for (int i = 0; i != argc, i++)
		str += argv[i];
	cout << str << endl;
	return 0;
}
//6.26
int main(int argc, char **argv)
{
	for (int i = 0; i != argc, i++)
		cout << "argc[" << i << "]: " << argv[i] << endl;
	return 0;
}
//6.27
int count(initializer_list<int> il)
{
	int total = 0;
	for (auto it = il.begin(); it != il.end(); it++)
		total += *it;
	return total;
}
//6.28
const string&
//6.29
initializer_list对象的元素永远是常量值,所以不可能通过设定引用类型来更改循环控制变量的内容
只有当initializer_list对象的元素类型是引用类型或容器类型才有必要设为引用
//6.31
引用所引的是函数开始之前就存在的对象,则返回该引用是有效的。
如果引用的是函数的局部变量则无效
//6.32
合法,因为传入的arry不是局部对象的引用
//6.33
void output(vector<int> &vec, int index)
{
	if (index >= vec.size())
		return;
	cout << vec[index];
	output(vec, index + 1);
}
//6.34
如果输入负值将会无限递归
//6.35
val--先取值再减1
//6.36
string (&func())[10];
//6.37
1.
typedef string arr[10];
arr& func();
2.
auto func() -> string(&)[10];
3.
string arr[10];
decltype(arr) &func();
//6.38
int odd[] = {1, 3, 5, 7, 9};
int even[] = {2, 4, 6, 8};
decltype(odd) &arrPtr(int i)
{
	return (i % 2) ? odd : even;
}
//6.39
(a)有问题
顶层const不影响传入函数的对象,一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开
(b)有问题
重载函数必须在形参数量或者类型上有区别
不能通过返回值来区别
(c)可行
//6.40
(a)正确
(b)错误,第一个形参默认实参后面的所有形参都要有默认实参
//6.41
(a)第一个形参需要提供一个实参
(b)合法
(c)与初衷不符,第二个实参会被转为int赋给wd,但实际上程序员想让背景为*
//6.43
(a)放在头文件,因为内联函数的定义对编译器而言必须可见
(b)函数声明,放在头文件
//6.44
inline bool isShorter(const string &s1, const string &s2)
{
	return s1.size() < s2.size();
}
//6.45
6.11中的reset
inline void reset(int &i)
{
	i = 0;
}
6.21中的myCompare
inline int myCompare(const int val, const int *p)
{
	return (val > *p) ? val : *p;
}
//6.46
不能,constexpr函数的返回类似和所有形参类型都得是字面值类型
//6.48
有不合理之处,执行assert的原因有两个,一个是终止了输入,一个是s等于sought
如果用户终止了输入,则assert会执行,输出错误信息,这和程序原意不相符
//6.49
函数匹配第一步选定本次调用对应的重载函数集,即候选函数
第二部考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,即可行函数
//6.50
(a)有二义性
(b)f(int)
(c)f(int, int)
(d)f(double, double)
//6.52
(a)通过类型提升
(b)算术类型转换
//6.53
(a)合法, 通过引用的是否为常量来区分
(b)合法,通过指针指向的是否为指针来区分
(c)是非法的,这里想通过指针本身是否为const来区分,但指针为const属于顶层const
无法区分顶层const
//6.54
int func(int, int);
vector<decltype(func)* > vf;
//6.55
int func1(int a, int b) { return a + b; }
int func2(int a, int b) { return a - b; }
int func3(int a, int b) { return a * b; }
int func4(int a, int b) { return a / b; }

decltype(func1) *p1 = func1, *p2 = func2, *p3 = func3, *p4 = func4;
vector<decltype(func1)* > vf = {p1, p2, p3, p4};
//6.56
int i = 1, j = 2;
for (auto p : vf)
	cout << p(i, j) << endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值