《C++ primer》第五版习题答案整理——第六章 函数

P184

练习6.1

对于实参和形参的区别,可以简单的理解为:

形参:函数定义的时的参数—也就是无赋值的变量(作用是说明参数的类型)

实参:调用函数时使用的参数—也就是有赋值的变量(函数实际操作的对象)

练习6.2

  1. 返回类型不匹配;
  2. 函数没有表明返回类型
  3. 两个v1,参数应不同
  4. 需要使用花括号

练习6.3

#include <iostream>
using namespace std;
int fact(int n)
{
	int ret = 0;
	for (int i = 1; i <= n; ++i)
	{
		ret += i;
	}
	return ret;
}
int main()
{
	cout << fact(10) << endl;
	return 0;
}

练习6.4

#include <iostream>
using namespace std;
int fact(int n)
{
	int multi = n;
	while (--n)
	{
		multi*= n;
	}
	return multi;
}
int main()
{
	int a;
	cout << "请输入一个数字:" << endl;
	cin >> a;
	if (a > 0) 
	{
		cout << a << "的阶乘为:" << fact(a) << endl;
	}
	else {
		cout << "无" << endl;
	}
	return 0;
}

练习6.5

#include <iostream>
#include<string>
using namespace std;
int fact(int n)
{
	n = abs(n);
	return n;
}
int main()
{
	int a;
	cout << "请输入一个数字:"<< endl;
	cin >> a;
	cout <<"|"<< a << "| =" << fact(a) << endl;
	return 0;
}

P185

练习6.6

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

#include<iostream>
using namespace std;
// example
size_t count_add(int n)       // n is a parameter and local variable.
{
	static size_t ctr = 0;    // ctr is a static variable.
	ctr += n;
	return ctr;
}

int main()
{
	for (size_t i = 0; i != 10; ++i)  // i is a local variable.
		cout << count_add(i) << endl;

	return 0;
}

练习6.7

#include<iostream>
using namespace std;
int hanshu()
{
	static int a = 0;
	return a++;
}
int main()
{
	for (int i = 0; i < 2;++i)
		cout << hanshu() << endl;
	return 0;
}

 P186

联习6.8

#pragma once
#include <iostream>
using namespace std;

int fact(int n);

P187

练习6.9

//Chapter6.h
#ifndef _6_9_h
#define _6_9_h

int func();

#endif

//fact.cc
#include "6_9.h"

int func()
{   
    static int x;

    return ++x;
}
//factMain.cc
#include <iostream>
#include "6_9.h"

int main()
{
    std::cout << func() << std::endl;

    return 0;
}

 P188

练习6.10

#include <iostream>

using namespace std;

void func(int *x, int *y)
{
    int p = *x;
    *x = *y;
    *y = p;
}

int main()
{
    int n = 10, m = 20;

    func(&n, &m);

    cout << n << " " <<  m << endl;

    return 0;
}


 P190

练习6.11

#include <iostream>

using namespace std;

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

int main()
{
    int x = 30;
    reset(x);

    cout << x << endl;

    return 0;
}

练习6.12

#include <iostream>

using namespace std;

void func(int& x, int& y)
{
    int p = x;
    x = y;
    y = p;
}

int main()
{
	int n = 10, m = 20;
	func(n, m);
	cout << n << " " << m << endl;
	return 0;
}

 引用更易于使用:

  • 传参时无需加取地址符&,方便阅读;
  • 被调用函数内部修改参数值无需解引用;
  • 引用效率更高;

练习6.13

一个是值传递,一个是引用传递。

练习6.14

  • 返回多个值使用引用类型;
  • 参数数据类型很大时需要使用引用类型;
  • 只改变实参的值而不改变形参的值时不能使用引用类型;

练习6.15

  • const string &s 避免拷贝且不用改变s的值,故是常量引用;
  • char c 不需要改变c的值且char类型占空间更小,故最好不用引用;
  • string::sizetype &occurs 需要改变occurs的值,故是普通引用;
  • 若s是普通引用:有可能改变其值,若实参定义为常量则无法传递;
  • occurs为常量引用:若改变其值会报错;

P192

练习6.16


// 1.给调用者造成可以修改实参的误导
//2.不能传常量
//改善:加 const
bool is_empty(const string &s) { return s.empty(); }

练习6.17

#include <iostream>
#include <string>

using namespace std;

bool my_isupper(const string& s)
{
    for (const auto& c : s)
    {
        if (isupper(c))
        {
            cout << "is upper" << endl;
            return true;
        }
    }
    cout << "is not upper" << endl;
    return false;
}

void my_toupper(string& s)
{
    for (auto& c : s)
    { 
        c=toupper(c);
    }
    cout << s << endl;
}

int main()
{
    string s("aA bB cC");
    my_isupper(s);
    my_toupper(s);
    return 0;
}

P193

练习6.18

bool compare(const matrix&, const matrix&);
vector<int>::iterator change_val(int, vector<int>::iterator);

练习6.19

  1. a 形参个数不匹配;
  2. b合法 常量引用传递 值传递;
  3. c 合法 值传递;
  4. d vec 不是 vector<int> 时不合法;

练习6.20

不需改变实参的值时,应设为为常量引用;实参为常量时,应设为常量引用;

若实参为常量会报错;

练习6.21

#include <iostream>
#include <string>

using namespace std;

int compare(int a, const int* b)
{
	if (a > *b)
		return a;
	else
		return *b;
}

int main()
{
	int a = 1;
	int b = 2;
	cout<<compare(a, &b)<<endl;
	return 0;
}

6.22

#include <iostream>
#include <string>

using namespace std;

void change(int* pa, int* pb)
{
	int temp;
	temp = *pa;
	*pa = *pb;
	*pb = temp;
}

int main()
{
	int a = 1;
	int b = 2;
	change(&a, &b);
	cout << "a = " << a << "	b = " << b << endl;
	return 0;
}

6.23

#include <iostream>
#include <string>

using namespace std;

void print(const int *beg,const int *end)
{
	while (beg != end)
	{
		cout << *beg++ << endl;
	}
}

void print(const int& i)
{
	cout << i << endl;
}

int main()
{
	int i = 0;
	int j[2] = { 0,1 };
	print(i);
	print(begin(j), end(j));
	return 0;
}

6.24

当数组作为实参的时候,会被自动转换为指向首元素的指针。因此函数形参接受的是一个指针。如果要让这个代码成功运行,可以将实参改为数组的引用

void print(const int (&ia)[10])
{
  for (size_t i = 0; i != 10; ++i)
    cout << ia[i] << endl;
}

6.25

#include <iostream>
#include <string>

int main(int argc, char **argv)
{
 std::string str;
 for (int i = 1; i != argc; ++i)
  str += std::string(argv[i]) + " ";

 std::cout << str << std::endl;
 return 0;
}

6.26

#include <iostream>
#include <string>

int main(int argc, char **argv)
{
 std::string str;
 for (int i = 1; i != argc; ++i)
  str += std::string(argv[i]) + " ";

 std::cout << str << std::endl;
 return 0;
}

6.27

#include <iostream>
#include <string>

using namespace std;

int Sum(initializer_list<int> il)
{
	int sum = 0;
	for (const auto& i : il)
		sum += i;
	return sum;
}

int main()
{
	cout << Sum({1,2,3}) << endl;
	return 0;
}

6.28

const std::string&

6.29

应该,因为initializer_list中的对象都是常量。

6.30

6.31

返回的引用时局部对象的引用,返回的常量引用是局部常量对象的引用时。

6.32

合法,将数组元素赋值为对应的下标。

6.33

#include <iostream>
#include <vector>
using namespace std;

void print(vector<int>::const_iterator beg, vector<int>::const_iterator end)
{
	if (beg!= end)
	{
		cout << *beg << " ";
		print(++beg, end);
	}
	else
	{
		cout << endl;
		return;
	}
}
int main()
{
	vector<int> ivec = { 1,2,3 };
	print(ivec.begin(), ivec.end());
	return 0;
}

6.34

如果实参为大于等于0,函数将会多乘以一个1。

6.35

val--会返回未修改的val内容,使程序陷入无限循环。

6.37

string(&func())[10];

6.38

using arrT=string[10];
arrT &func();

auto func()->string(&)[10];

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

using最好,易读。

6.39

a)合法,但是重复声明;

b)非法,返回值类型不同;

c)合法。

6.40

a)合法;

b)非法,前面的形参有默认值,后面所有的形参都要有默认值;

6.41

a)非法,形参ht无默认值,需要传参;

b)合法;

c)合法,但初衷不符,形参wd被实参‘*’转为int赋值;

6.42

#include <iostream>
#include <string>

using std::string;

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

int main()
{
	std::cout << make_plural(1, "success", "es") << std::endl;
	std::cout << make_plural(1, "failure") << std::endl;
	std::cout << make_plural(2, "success", "es") << std::endl;
	std::cout << make_plural(2, "failure") << std::endl;
}

6.43

a)头文件,这是一个内联函数的定义;

b)头文件,这是一个函数声明;

6.44

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

6.45

内联机制用于优化规模小、流程直接、频繁调用的函数;

对于规模大、调用不频繁的函数不应使用内联;

6.46

不能,constexpr函数的返回值类型及所有形参都应是字面值类型;

6.47

#include <iostream>
#include <vector>
//#define NDEBUG
using namespace std;

void print(vector<int>::const_iterator beg, vector<int>::const_iterator end)
{
#ifndef NDEBUG
	cout << "vector size: " << end - beg <<" func :"<< __func__ << " file :" << __FILE__ << " line :"
		<< __LINE__ << " time :" << __TIME__ << " date :" << __DATE__ << endl;
#endif
	if (beg != end)
	{
		cout << *beg << " ";
		print(++beg, end);
	}
	else
	{
		cout << endl;
		return;
	}
}
int main()
{
	vector<int> ivec = { 1,2,3 };
	print(ivec.begin(), ivec.end());
	return 0;
}

6.48

循环含义:当输入的string等于sought时,停止循环。

assert(cin)用在这里语法正确,但不太合理;

此处while循环后,若标准输入流中不为0则程序继续,而此处while循环保证了标准输入流中不为0;

在windows下输出在调试窗口输入ctrl+z,可触发assert(cin)使程序终止,但ctrl+z本身就可以终止程序。

6.49

候选函数:本次调用对应的重载函数集中的函数,与被调用函数同名,声明在调用点可见;

可行函数:候选函数中选出能被这组实参调用的函数,形参数量与本次调用提供的实参数量相等,每个实参的类型与对应的形参类型相同。

6.50

a) 不合法,有二义性;

b) void f(int);

c) void f(int,int);

d) void f(double,double=3.14);

6.51

略。

6.52

a) 等级3,类型提升;

b) 等级4,算术类型转换;

6.53

a) 合法;

b) 合法;

c) 合法,顶层const,声明重复(可以重复声明,不可重复定义)。

6.54

int fun(int, int);
vector<decltype(fun)*> vfun;

6.55 & 6.56

#include <iostream>
#include <vector>

using namespace std;

int fun(int, int);
vector<decltype(fun)*> vfun;

int f_add(int a, int b)
{
	return a + b;
}

int f_sub(int a, int b)
{
	return a - b;
}

int f_multib(int a, int b)
{
	return a * b;
}

int f_divis(int a, int b)
{
	if (b)
		return a / b;
	else
		return 0;
}

int main()
{
	vfun.push_back(f_add);
	vfun.push_back(f_sub);
	vfun.push_back(f_multib);
	vfun.push_back(f_divis);
	for (const auto& i : vfun)
		cout << i(3, 2) << endl;
	return 0;
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值