c++primer第五版第六章练习

6.1

形参是函数与外界接受数据的一种方式,生命周期是该函数执行完毕前。

实参是在调用函数时的参数,传递给函数用于初始化形参


6.2

a 返回类型不匹配,修改为 string f()或是int s;

b 没有返回类型,修改为void f2(int)

c 形参名字形同、缺少"{",修改为int calc(int v1,int v2){/*...*/}

d 缺少"{}",修改为double square(double x){return x*x;}


6.3

int fact(int val)
{
	int ret = 1;
	while (val > 1)
		ret *= val--;
	return ret;
}

6.4

#include <iostream>
int fact(int val);
int main()
{
	using namespace std;
	int n;
	cin >> n;
	cout << fact(n) << endl;
	system("pause");
	return 0;
}
int fact(int val)
{
	int ret = 1;
	while (val > 1)
		ret *= val--;
	return ret;
}

6.5

template<class T>
void absolute_value(T a)
{
	std::cout << (a > 0 ? a : -a;);
}


6.6

在一个代码块内声明的变量是局部变量,在代码块结束时销毁

在函数参数列表声明的是形参,用于实参与形参之间的数据传递

局部静态变量在第一次声明时存在,在程序结束时销毁,不会随着代码块的结束而销毁

#include <iostream>
int add(int n,int m)
{
	static int sum = 1;
	++sum;
	std::cout << sum << std::endl;
	return n + m;
}
int main()
{
	int sum = 0;
	int a;
	while (std::cin >> a)
		sum=add(sum,a);
	std::cout << sum;
	system("pause");
	return 0;
}

6.7

#include <iostream>
int func()
{
	static int a = 0;
	return a++;
}

6.8

#ifndef _HEAD_H_
#define _HEAD_H_
int f();
void f2(int i);
int calc(int v1, int v2);
double square(double x);
int fact(int n);
template<class T>
void absolute_value(T a);
#endif

6.9

#include "Chapter6.h"
#include <iostream>

int main()
{
	std::cout << fact(10);
	return 0;
}


6.10

#include <iostream>
void swap(int *n, int *m);
int main()
{
	int a = 5, b = 9;
	std::cout << a << "-" << b << std::endl;
	swap(&a, &b);
	std::cout << "swap:\n" << a << "-" << b << std::endl;
	return 0;
}
void swap(int *n, int *m)
{
	*n -= *m;
	*m += *n;
	*n = *m - *n;
}

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

6.12

引用更容易,而且阅读起来更好

void swap(int &n, int &m)
{
	n -= m;
	m += n;
	n = m - n;
}

6.13

void f(T);函数无返回值,函数无法改变实参,因为是按值传递

void f(&)T;不知道书是否出错题,应该是void f(T&);函数无返回值,函数在改变形参时实参也会改变


6.14

例如上面的交换两个数的swap函数就应该是引用

不应为引用的例如,int fun(int a){a-=/=2;return a;},当形参时引用时将改变实参的值


6.15

字符串s本来就不应该被修改,所以是const,再来就是定义为引用时绑定的速度比把整个实参传递过来地要快

occurs是用来记录c出现的次数了,如果不是引用,那么将无法改变实参达到记录的目的,如果是const 那将无法变动

c怎么都行,但是最好还是const char


6.16

bool is_empty(const string &s)//如果函数不需要修改引用的值,那么要尽量使用const
{
    return s.empty();
}

6..17

bool is_upper(const std::string &s)
{
	for (auto x : s)
	{
		if (isupper(x))判断当前字符是否大小
			return true;
	}
	return false;
}
void conversion(std::string &s)
{
	for (auto &x : s)
	{
		if (isupper(x))
			x = tolower(x);//将x的小写返回
	}
}
如果conversion的形参是const,那么将无法修改实参的数据


6.18
bool compare(const matrix &m1,const matrix &m2);

vector<int>::iterator change_val(const int n,vector<int>::iterator iter);


6.19

a 不合法,不存在接受连个double值的calc函数

b 合法

c 合法,可以int转换为double

d 合法,double转换为int,但是精度回降低


6.20

在不需要修改引用形参时应该是const的

那么可能会通过形参改变实参的值


6.21

int max_val(int n, const int *p)
{
	return n > *p ? n : *p;
}

6.22

void swap_intp(int *p1, int *p2)
{
	int *temp = p1;
	p1 = p2;
	p2 = p1;
}


6.23

void print(const int *p, int n)
{
	for (int i = 0; i < n; ++i)
		std::cout << p[i];
}


6.24
函数是接受一个10个成员的int数组,然后进行输出

但是这里const int ia[10],和const int *ia是没有任何区别的,其实也可以是const int ia[3]都可以

如果想让函数之接受10个成员的int数组,那么需要修改为:

const int (&ia)[10];

按照先后顺序那就是(&ia)这是一个引用,是一个[10]10个元素的数组的引用,const int该数组的类型

那么现在函数void print(const int (&p)[10]);只能接受一个10个元素的int数组了:int a[10];


6.25

#include <iostream>
#include <string>
int main(int argc, char **argv)
{
	std::string str1 = argv[1], str2 = argv[2];
	str1 += str2;
	std::cout << str1;
	return 0;
}

6.26

#include <iostream>
int main(int argc, char **argv)
{
	for (int i = 0; i < argc; ++i)
	{
		std::cout << argv[i];
	}
	return 0;
}


6.27

int sum(std::initializer_list<int> init)
{
	int temp=0;
	for (auto x : init)
	{
		temp += x;
	}
	return temp;
}


6.28

string &


6.29

不建议,因为都是const副本,

但是建议声明为const引用

6.30

错误 1error C2561: “str_subrange”: 函数必须返回值f:\c++\c++学习例行代码\text\6.30\6.30\源.cpp 101 6.30


6.31

返回的是函数的局部变量的引用是无效的

6.32

合法,初始化数组为0~9

get返回一个索引指定的引用,然后通过返回值把i赋值给返回值达到修改数组中元素


6.33

#include <iostream>
#include <vector>
void printv(std::vector<int>::iterator beg, std::vector<int>::iterator end)
{
	if (beg != end)
	{
		std::cout << *beg;
		printv(std::next(beg), end);
	}
}
int main()
{
	std::vector<int> vi = { 1,2,3,4,5,6,7,8,9,0 };
	printv(vi.begin(), vi.end());
	system("pause");
	return 0;
}

6.34

一直运算到等于0时才停下,那么0乘所有数都是0

如果参数是负数,那么就是"死循环"


6.35

val--是把val的值的副本留下,然后在运算玩后才进行自减

那么函数的形参就没有变化了


6.36

string (&func(string (&str)[10))[10];


6.37

using str = string[10];
str& func1(str &ar);


auto func2(str& ar)->string(&)[10];


string str[10];
decltype(str)& func3(str &arr);

第一种比较好,容易理解


6.38

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

6.39

a 非法,重复的声明

b 非法,重复的声明,返回值不能用于区分函数

c 合法


6.40

b是错误的,默认参数必须在后面,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值


6.41

a非法,形参ht密友实参

b正确

c初衷不符,'*'号被转换为ascii码初始化wd


6.42

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

6.43

都应该放在头文件,一个是内联,一个是声明


6.44

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


6.45

6.38和6.42可以作为内联,但是6.4节的不应该是内联,因为他只被调用了一次,然而代码也很多


6.46

不行,无法确认函数中所有的值


6.47

#include <iostream>
#include <vector>
void printv(std::vector<int> &vec)
{
	if (vec.size())
	{
		auto temp = vec.back();
#ifndef NDEBUG
		std::cout << __FUNCTION__ << ":" << __FILE__ << std::endl;
#endif
		vec.pop_back();
		printv(vec);
		std::cout << temp;
	}
}
int main()
{
	std::vector<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	printv(vi);
	system("pause");
	return 0;
}


6.48
cin>>s&&s!=sought,表示除非输入错误(错误的类型等)和s与sought相等时结束

assert(cin)检查输入流是否异常。就是说检查是否是因为输入错误而结束的


6.49

候选函数:与被调用函数同名,其声明在调用点可见

可行函数:形参数量与本次调用提供的实参数量相等,每个实参对应的形参的类型相同或者可以进行转换


6.50

a 二义性,可匹配的函数有f(int,int)和f(double,double)

b f(int)

c f(int,int)

d f(double,double)

6.51

#include <iostream>
using namespace std;
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)
{
	cout << "f(double, double)" << endl;
}
int main()
{
	f(2.56, 42); //错误,有二义性
	f(42);
	f(42, 0);
	f(2.56, 3.14);
	system("pause");
	return 0;
}

6.52

a 第三级,'z'被提升,对应的ascii码

b 第四级,dobj被转换为int


6.53

a 当对象是const时调用,不是时优先使用int&

b 同上

c 二义性


6.54

int func(int, int);
using psum = decltype(func) *;
vector<psum> vpsum;


6.55

int fadd(int a, int b){ return a + b; }
int freduction(int a, int b){ return a - b; }
int ftake(int a, int b){ return a*b; }
int faddition(int a, int b){ return a != 0 ? a / b : 0; }

6.56

vector<psum> pf{ fadd, freduction, ftake, faddition };
	for (auto f : pf)
		cout << f(10, 5);


2015年11月13日20:48:28 什么都不想说了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
《C Primer》是一本针对C语言初学者的经典教材,第五版第六章主要介绍了函数的基本概念和用法。 在第六章中,教材首先介绍了函数的定义和调用。函数是具有独立功能的代码块,可以通过函数名来调用。函数由函数头、参数、函数体和返回值组成。函数头包括函数类型、函数名和参数类型,参数用于接收传递给函数的值,返回值用于将结果返回给调用者。 接着,教材详细介绍了函数的参数传递方式,包括按值传递、按引用传递和按指针传递。按值传递是指将参数的值复制给形参,按引用传递是指将参数的引用传递给形参,而按指针传递是将参数的地址传递给形参。不同的传递方式在函数内部对参数进行操作时,会对应不同的结果。 此外,教材还讲解了函数的返回值和函数的调用顺序。函数的返回值类型由函数头中的类型确定,可以是任意类型。当函数需要返回多个值时,可以使用结构体或指针进行返回。函数的调用顺序决定了函数执行的顺序,即哪个函数先执行,哪个函数后执行。 在函数的实现过程中,教材介绍了函数的定义和声明、局部变量和全局变量、递归等内容。通过这些知识点的学习,读者可以了解到函数的具体细节和一些实践技巧。 总的来说,第五版第六章通过清晰的语言和丰富的例子,循序渐进地讲解了函数的基本概念和用法。学完这一章,读者将能够理解函数的定义、调用、参数传递、返回值和实现等方面的知识,为之后的学习和实践打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值