C++Primer 第五版 习题答案 第六章 函数

6.1

形参在函数声明中定义
实参是形参的初始值

6.2

a)返回类型错误,应改为 string

string f()
{
string s;
//...
return s;
}

b)应该加上函数声明

void f2(int i){/**/}

c) 形参的名字不能相同

int calc(int v1,int v2)
{
/* */
}

d)需要花括号(块)

double square(double x)
{
return x*x;
}

6.3

#include

int fact(int i)
{
	int res = 1;
	while (i>1)
	{
		res *= i--;
	}
	return res;
}

int main()
{
	int j =fact(5);
	std::cout << j << std::endl;
	return 0;
}

6.4

#include

int fact(int i)
{
	int res = 1;
	while (i>1)
	{
		res *= i--;
	}
	return res;
}

int main()
{
	std::cout << "input a intNum" << std::endl;
	int n;
	std::cin >> n;
	std::cout << fact(n) << std::endl;
	return 0;
}

6.5

#include

int absolute(int i)
{
	return (i > 0) ? i : (-i);	
}

int main()
{
	std::cout << absolute(-2) << std::endl;
}

6.6

形参是局部变量的一种
形参和函数体内部定义的变量称为局部变量
局部静态变量的生命周期贯穿函数调用以及之后的周期

size_t count_call(int n)
{
static size_t ctr =0;
ctr+=n;
return ctr;
}
int main()
{
for(size_t i =0;i<10;++i)
	cout <<count_call(i)<<endl;
return 0;
}

6.7

size_t count_call()
{
static size_t ctr =0;
return ++ctr;
}

6.8

#ifndef CHAPTER6.h
#define CHAPTER6.h
int fact(int n);
int absolute(int n);
#endif

6.9

fact.cpp

#include "Chapter6.h"

int fact(int n)
{
	int ret = 1;
	for(int i = 1;i <= n;++i)
	{
		ret *= i;
	}
	return ret;
}

int absolute(int n)
{
	return (n > 0) ? n : -n;
}

factMain.cpp

#include 
#include "Chapter6.h"

int main()
{
	std::cout << fact(5) << std::endl;

	return 0;
}

6.10

#include
using std::cout;
using std::endl;

void swap(int * i,int  *j)
{
	int tmp = *i;
	*i = *j;
	*j = tmp;
}

int main()
{
	int i = 1, j = 2;
	cout << "i=" << i << " j=" << j << endl;
	swap(&i, &j);
	cout << "i=" << i << " j=" << j << endl;
}

6.11

#include 

void reset(int& i)
{
	i = 0;
}

int main()
{
	int i = 100;
	std::cout << i << std::endl;
	reset(i);
	std::cout << i << std::endl;
	return 0;
}

6.12

#include
using std::cout;
using std::endl;

void swap(int &i, int &j)
{
	int tmp = i;
	i = j;
	j = tmp;
}

int main()
{
	int i = 1, j = 2;
	cout << "i=" << i << " j=" << j << endl;
	swap(i, j);
	cout << "i=" << i << " j=" << j << endl;
}

引用更易于使用,不用考虑传递的是指针

6.13

void f(T)
将实参的值拷贝赋值给形参,不能通过改变形参的值来改变实参
void f(T&)
将引用的形参绑定在实参上,可以通过改变实参来改变形参

6.14

形参是引用的例子

void rest(&i)
{
	i=0;
}

形参不是引用的例子
有关容器迭代器的形参不能是引用

void print(std::vector<int>::iterator begin, std::vector<int>::iterator end)
{
        for (std::vector<int>::iterator iter = begin; iter != end; ++iter)
                std::cout << *iter << std::endl;
}

6.15

s不需要改变实参,occurs需要改变实参
s可能很大,occurs需要改变实参,c没有以上两个需求
如果s是普通形参可能会改变实参
occurs是常量引用不能改变实参,++occurs报错

6.16

无需改变实参,设置为const较好,这样可以传递const类型字符串,或者字符串字面值

bool is_empty(const string &s){return s.empty();}

6.17

#include
#include

using std::string;

bool isUpper(const  string& s)
{
	for (auto c : s)
	{
		if (isupper(c)) return true;
	}
	return false;
}

void  toUpper(string& s)
{
	for (auto &c : s)
	{
		c = toupper(c);
	}
}

int main()
{

	string s("dasfasfASADSAF");
	std::cout << (isUpper(s) ? "is upper" : "is not upper") << std::endl;
	toUpper(s);
	std::cout << s << std::endl;
}

不一样 一个使用常量引用,不需要改变实参;第二个使用非常量引用,需要改变实参。

6.18

bool compare(matrix &m1, matrix &m2);
vector<int>::iterator change_val(int i,vector<int>::iterator);

6.19

a) 不合法,只能有一个形参
b) 合法
c)合法
d)合法

6.20

无需改变实参的时候应该使用常量引用;
可能会改变实参发生错误;

6.21

#include

int compare(int i, int* j)
{
	return i > * j ? i : *j;
}

int main()
{
	int i = 0, j = 1;
	std::cout << compare(i, &j) << std::endl;
}

6.22

#include

void swap_intp(int *&i,int *&j) 
{
	int *tmp;
	tmp = i;
	i = j;
	j = tmp;
}

int main()
{
	int i = 0, j = 1;
	int *pi = &i, *pj = &j;
	std::cout << pi << " " << pj<< std::endl;
	swap_intp(pi, pj);
	std::cout << pi << " " << pj << std::endl;
	return 0;
}

6.23

#include

using std::cout;
using std::endl;
using std::begin;
using std::end;

void printf(const int* pi)
{
	cout << *pi << endl;
}

void printf(const int* beg, const int* end)
{
	while (beg!=end)
	{
		cout << *beg++ << " ";
	}
	cout << endl;
}
void printf(const int ia[], size_t size)
{
	for (size_t i = 0; i != size; i++)
	{
		cout << ia[i] << " ";
	}
	cout << endl;
}

void printf(const int(&arr)[2])
{
	for (auto c : arr)
		cout << c << " ";
	cout << endl;
}

int main()
{
	int i = 0, j[2] = { 0,1 };
	printf(&i);
	printf(begin(j), end(j));
	printf(j, end(j) - begin(j));
	printf(j);
}

6.24

函数传递的不是const int*,如果传入的不是10元素的int类型数组,可能会导致for循环越界

void print(const int (&ia)[10]){/* */}

6.25

#include 

int main(int argc, char const* argv[])
{
	const std::string s1 = argv[1], s2 = argv[2];
	std::cout << s1 + s2 << std::endl;
	return 0;
}


6.26

#include 

int main(int argc, char const *argv[])
{
	std::string s;

	for(int i = 0; i != argc; ++i)
		s += std::string(argv[i]) + " ";
	std::cout << s << std::endl;

	return 0;
}


6.27

#include 
#include 

int counter_int(std::initializer_list<int> il)
{
	int cnt_i = 0;
	for(auto e : il)
		cnt_i += e;
	return cnt_i;
}

int main(int argc, char const *argv[])
{
	std::cout << counter_int({1,2,3,4,5}) << std::endl;

	return 0;
}

6.28

const std::string &

6.29

如果拷贝代价小,无需设置为引用类型;
如果拷贝代价大,可以设置为引用类型。

6.30

错误1 函数必须有返回值
错误2 控制流未返回就结束 (编译器未检测出来

6.31

返回局部对象的引用无效
返回的常量是局部对象的引用

6.32

合法 返回数组ia[0] -ia[10]

6.33

#include 
#include

using std::vector;
using std::cout;
using std::endl;

void print_vi(vector<int>::const_iterator itBegin, vector<int>::const_iterator itEnd)
{
	if (itBegin != itEnd)
	{
		cout << *itBegin << " ";
		return print_vi(++itBegin, itEnd);
	}
	else
	{
		cout << endl;
		return ;
	}
}
int main()
{
	vector<int>v{ 1,2,3,4,5 };
	print_vi(v.begin(), v.end());
}

6.34

如果实参大于1 会多乘一个1
如果实参小于0 函数将不断调用自己直到程序栈空间耗尽

6.35

val–会返回未修改的val,使得程序陷入无限循环;
val–会修改val的值,使程序结果不符合预期

6.36

std::string (&fun(std::string (&arrs)[10])) [10]

6.37

using ARR =std::string[10];
ARR &fun(Arr &arrs);

auto fun(std::string (&arr)[10])->std::string (&)[10];

std::string arrs1[10];
decltype(arrs1) &fun(decltype(arrs1) &arr)

6.38

decltype(arrPtr)& arrPtr(int i)
{
return (i%2)?odd:even;
}

6.39

a)合法,重复声明可以;
b)非法,仅返回值类型不同不可以;
c)合法

6.40

a)正确
b) 错误,默认实参不在形参列表结尾

6.41

a)非法,函数第一个形参没有默认值,必须给出实参;
b)合法;
c) 合法 char ‘*’ 被转化为int ,但与初衷不同。

6.42

#include 
#include

using std::string;
using std::cout;
using std::endl;


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

int main()
{
	cout << make_plural(2, "sucess", "es") << endl;
	cout << make_plural(2, "failure") << endl;
	cout << make_plural(1, "people");
}

6.43

a) 放在头文件中,内联函数在程序中可以多次定义,但多个定义必须保持一致,因为放在头文件里较好
b)放在源文件里,声明放在头文件里

6.44

inline bool isshorter(const string &s1, const string &s2)
{
return s1.size()<s2.size();
}

6.45

6.38和6.4应该是内联函数;
6.4不是,规模不小,调用不频繁。

6.46

不能,因为 std::string.size()不是一个常量表达式函数,s1.size()==s2.size()不是一个常量表达式。

6.47

#include 
#include

using std::vector;
using std::cout;
using std::endl;
using std::cerr;

void print_vi(vector<int>::const_iterator itBegin, vector<int>::const_iterator itEnd)
{
#ifndef NDEBUG
	cerr << itEnd - itBegin << __func__ << " " << __FILE__ << " " << __LINE__ << " " << __TIME__ << " " << __DATE__ << endl;
#endif // !NDEBUG

	if (itBegin != itEnd)
	{
		cout << *itBegin << " ";
		return print_vi(++itBegin, itEnd);
	}
	else
	{
		cout << endl;
		return;
	}
}
int main()
{
	vector<int>v{ 1,2,3,4,5 };
	print_vi(v.begin(), v.end());
}

6.48

合理,当输入结束时终止输出。

6.49

重载函数集,有两个特征,一是与被调用函数同名,二是其声明在调用点可见。

6.50

a)二义性
b)void f(int)
c)void f(int,int)
d) void f(double, double =3.14)

6.51

#include 
using std::cout; 
using std::endl;

void f()
{
    cout << "f()" << endl;
}

void f(int)
{
    cout << "f(int)" << endl;
}

void f(int, int)
{
    cout << "f(int, int)" << endl;
}

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

int main()
{
    //f(2.56, 42); // error: 'f' is ambiguous.
    f(42);
    f(42, 0);
    f(2.56, 3.14);
    return 0;
}

6.52

a)3等级,同过类型提升实现匹配
b) 4等级,通过算术类型转换

6.53

a)合法,实参可以为const int;
b) 合法,实参可以为 const char*
c) 合法,顶层const,声明重复(可以重复声明,但不可以重复调用)

6.54

vector<int (*)(int, int)> vf;

//others:
int func(int a, int b);

using pFunc1 = decltype(func) *;
typedef decltype(func) *pFunc2;
using pFunc3 = int (*)(int a, int b);
using pFunc4 = int(int a, int b);
typedef int(*pFunc5)(int a, int b);
using pFunc6 = decltype(func);

std::vector<pFunc1> vec1;
std::vector<pFunc2> vec2;
std::vector<pFunc3> vec3;
std::vector<pFunc4*> vec4;
std::vector<pFunc5> vec5;
std::vector<pFunc6*> vec6;

6.55

int add(int a,int b){return a+b;}
int subract(int a, int b){return a-b;}
int multiply(int a,int b){return a*b;}
int divide(int a, int b){return b =0? 0:a/b;}

6.56

#include 
#include

using std::vector;
using std::cout; 
using std::endl;

int add(int a, int b) { return a + b; }
int subract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b = 0 ? 0 : a / b; }

int main()
{
	vector<int (*)(int, int)> vf{ add,subract,multiply,divide };
	for (auto c : vf)
		cout << c(4, 2)<<" ";
	cout << endl;
}

你可能感兴趣的:(C++,c++)