C++ Primer Plus课后编程练习第8章参考代码

(C++ Primer Plus课后编程练习第8章参考代码)

声明:

作者入门小白,将学习过程中的代码做一些分享,仅供大家参考,欢迎大家交流指正。全部编译运行过,水平有限,不喜勿喷。

环境:

Windows 10操作系统,Dev C++ 5.11,TDM-GCC 4.9.2 64-bit Release

1.编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数(int类型),且参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的一些技术。在一个简单的程序中使用该函数,以演示该函数是如何工作的。

代码:

#include <iostream>

using namespace std;

int count = 0;								//统计函数被调用的次数 

void print( const char * str )				//打印字符串函数 
{
	cout << str << endl;
}
void print( const char * str, int n )		//函数重载 
{
	count++;								//每调用一次,count加1 
	for( int i=0; i<count; i++ )			//函数被累计调用多少次,就将字符串显示多少次 
		cout << str << "\t";
	cout << endl;
}

int main()
{
	print("abcd");
	print("xyz", 2);
	print("uvw", 5);
	print("opq", 8);
	
	return 0;
}

结果:
图8.8.1

2.CandyBar结构包含3个成员。第一个成员存储candy bar的品牌名称;第二个成员存储candy bar的重量,即将CandyBar的引用、char指针、double和int作为参数,并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为“Millennium Munch”、28.5和350.另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。

代码:

#include <iostream>
#include <cstring>					//使用strcpy函数需包含此头文件

using namespace std;

struct CandyBar
{
	char name[20];					//品牌名称
	float weight;					//重量
	int colories;					//热量
};

//函数第一个参数为CandyBar对象的引用,三个参数均有默认值
void SetValue( struct CandyBar & cb, const char * str="Millennium Munch", const float we=2.85, const int clo=350 )
{
	strcpy(cb.name, str);			//修改名称
	cb.weight = we;					//修改重量
	cb.colories = clo;				//修改热量
	cout << "finished" << endl;
}
void Show( const struct CandyBar & cb )				//显示结构内容的函数
{
	cout << "name: " << cb.name << endl;
	cout << "weight: " << cb.weight << endl;
	cout << "colories: " << cb.colories << endl;
}

int main()
{
	struct CandyBar ocb1={"Jack", 3.2, 5};			//创建结构体变量并初始化
	SetValue(ocb1);									//设置初值
	Show(ocb1);										//显示
	SetValue(ocb1, "Bob", 3.5, 468);				//设置特定值
	Show(ocb1);										//显示
	
	return 0;
} 

结果:
图8.8.2

3.编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,为此可以使用表6.4描述的函数toupper()。然后编写一个程序,它通过使用一个循环让您能够用不同的输入来测试这个函数,该程序的运行情况如下:

图8.8.3
代码:

#include <iostream>
#include <cctype>							//使用toupper函数需包含此头文件
#include <string>

using namespace std;

void Up( string & str )								//将字符串转换为大写
{
	for( int i=0; str[i]; i++ )
	{
		str[i] = toupper(str[i]);
	}
}

int main()
{
	string s1;
	cout << "Enter a string (q to quit): ";
	//使用cin获取一个输入放在s1中,以换行符为结束标志 
	getline(cin, s1, '\n');	
	while( s1!="q" )								//输入q时退出
	{
		Up(s1);
		cout << s1 << endl;
		cout << "Next string (q to quit): ";
		getline(cin, s1, '\n');
	}
	cout << "Bye." << endl;

	return 0;
}
4.根据给出的程序框架,提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每个都使用默认参数。请尽可能使用const参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器。)

代码:

#include <iostream>
#include <cstring>

using namespace std;

struct stringy
{
	char * str;				//指向字符串的指针 
	int ct;					//字符串的长度 
};

void set( struct stringy & osy, const char arr[] ) 
{
	char * psy = new char[strlen(arr)+1];		//根据传入字符串的长度(包含'\0')申请空间 
	osy.str = psy;								//osy.str指向新空间 
	strcpy(osy.str, arr);						//将字符串拷贝到对应空间内 
	osy.ct = strlen(osy.str);					//获取字符串长度 
}
void show( const struct stringy & osy, const int n=1 )
{
	for( int i=0; i<n; i++ )
		cout << osy.str << endl;
}
void show( const char str[], const int n=1 )
{
	for( int i=0; i<n; i++ )
		cout << str << endl;
}

int main()
{
	stringy beany;
	char testing[] = "Reality isn't what it used to be.";
	
	set(beany, testing);					//以testing的内容为beany做初始化 
	show(beany);
	show(beany, 2);							//显示beany的内容 
	testing[0] = 'D';						//修改testing中元素的值 
	testing[1] = 'u';
	show(testing);							//显示testing的内容 
	show(testing, 3);
	show("Done!");
	
	return 0;
} 

结果:
图8.8.4

5.编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序中使用该函数,将T替换为一个包含5个int值的数组和一个包含5个double值的数组,以测试该函数。

代码:

#include <iostream>

using namespace std;

template <typename T>					//函数模板 
T max5( T arr[5] )						//返回值为 T,参数为包含5个 T类型元素的数组 
{
	T tmp = arr[0];						//将第一个元素作为最大值 
	for( int i=1; i<5; i++ )			//遍历剩余所有元素 
	{
		if( arr[i]>tmp )				//tmp存储最大值 
			tmp = arr[i];
	}
	return tmp;							//返回最大值 
}

int main()
{
	int a1[5] = {27, 6, 82, 15, 64};
	double a2[5] = {15.2, 24.3, 8.07, 59.73, 3.14};
	
	cout << "The max int: " << max5(a1) << endl;
	cout << "The max double: " << max5(a2) << endl;
	
	return 0;
} 

结果:
图8.8.5

6.编写函数模板maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个double元素的数组来调用该函数。程序还包含一个具体化,它将char指针数组和数组中的指针数量作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使用由5个字符串指针组成的数组来测试该具体化。

代码:

#include <iostream>
#include <cstring>

using namespace std;

template <typename T>						//函数模板 
T maxn( T arr[], int n )					//返回值为T类型,参数为T类型的数组、数组的元素个数 
{
	T tmp = arr[0];
	for( int i=1; i<n ; i++ )
	{
		if( arr[i]>tmp )
			tmp = arr[i];
	}
	return tmp;								//返回最大值 
}

template<> const char * maxn( const char * astr[], int n )		//const char*具体化 
{
	const char * pt = astr[0];									//默认第一个字符串最长 
	for( int i=1; i<n; i++ )									//遍历剩余其他字符串 
	{
		if( strlen(astr[i])>strlen(pt) )						//pt指向长度最大的字符串 
		{
			pt = astr[i];
		}
		else if( strlen(astr[i])==strlen(pt) )					//若两个字符串长度相同, 
		{
			continue;											//跳过该字符串,与下一个字符串对比 
		}
	}
	return pt;													//返回最长字符串的地址 
}

int main()
{
	int a1[6] = {27, 6, 82, 15, 64, 53}; 
	double a2[4] = {15.2, 24.3, 8.07, 59.73};
	cout << "The max int: " << maxn(a1, 6) << endl;				//测试 int maxn( int[], int ); 
	cout << "The max double: " << maxn(a2, 4) << endl;			//测试 double maxn( double[], int ); 
	
	const char * strings[5] = 
	{
		"Fight!", "Hello", "Bob", "Jack..", "Hello"
	};
	for( int i=0; i<(sizeof(strings)/sizeof(strings[0])); i++ )		//输出所有字符串 
	{
		cout << strings[i] << endl;
	}
	cout << "The max string: " << maxn(strings, sizeof(strings)/sizeof(strings[0])) << endl;
	
	return 0;
} 
注意:sizeof(strings) / sizeof(strings[0]) = (sizeof(const char *)*5) / (sizeof(const char *)) = 5

结果:
图8.8.6

7.修改程序清单8.14,使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显示数组的内容。程序应显示thing的总和以及所有debt的总和。

代码:

#include <iostream>

using namespace std;

template <typename T>
T SumArray( T arr[], int n );						//change

template <typename T>
T SumArray( T * arr[], int n );					//change

struct debts
{
	char name[50];
	double amount;
};

int main()
{
	int things[6] = {13, 31, 103, 301, 310, 130};
	struct debts mr_E[3] = 
	{
		{"Ima Wolfe", 2400.0},
		{"Ura Foxe", 1300.0},
		{"Iby Stout", 1800.0}
	};
	double * pd[3];
	
	for( int i=0; i<3; i++ )
		pd[i] = &mr_E[i].amount;

	cout << "Listing Mr.E's counts of things:\n";
	cout << SumArray(things, 6) << endl;			//显示thing的总和 
	cout << "Listing Mr.E's debts:\n";
	cout << SumArray(pd, 3) << endl;				//显示debt的总和 
	
	return 0;
}

template <typename T>
T SumArray( T arr[], int n )						//change
{
	cout << "template A\n";
	T total = 0;
	for( int i=0; i<n; i++ )
		total += arr[i];							//累加求和 
	return total;
}

template <typename T>
T SumArray( T * arr[], int n )						//change
{
	cout << "template B\n";
	T total = 0.0;
	for( int i=0; i<n; i++ )
		total += *arr[i];							//累加求和 
	return total;
}

结果:
图8.8.7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值