C++ primer Plus(第六版)第八章函数探幽编程答案

// 第八章.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <iostream>//预编译,使用iostream文件在编译前替代这行代码
#include <array>
#include <string>
#include <iomanip>
#include<typeinfo>

const int SIZE = 101;
static int flag = 0;

using namespace std;//将使用std命名空间中的定义
	/*  编写一个通常接受一个参数(字符串的地址),并打印该字符串的函数。
    然而,如果提供了第二个参数(int)类型,且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数。
   (注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。
   是的,这是一个非常可笑的函数(我怎么不觉得可笑,手动微笑),但它能让您使用本章介绍的一些技术。
   在一个简单的程序中使用该函数,以演示该函数是如何工作的。  
*/
void print(string str,int n=0);
void print(string str, int n)
{
	flag++;
	cout << "第" << flag << "次调用print函数:\n";
	if (n!=0)
	{		
		for (int i = 0; i < flag; i++)
		{
			cout <<str << endl;
		}			
	}
	else
		cout << str << endl;
	
}

void Xiti1()//
{
	string str;
	int n=1;
	while (n!=0)
	{
		cout << "输入字符串:";
		cin.get();
		getline(cin, str);
		cout << "输入一个整数:";
		
		if (cin >> n)
		{
			cout << "输入了字符和数字,执行双参数\n";
			print(str, n);
		}
		else
		{
			cout << "仅输入字符,执行默认值\n";
			print(str);
		}
	}
	
	return;
}
/*. CandyBar结构包含3个成员。第一个成员存储candy bar的品牌名称;第二个成员存储candy bar的重量(有可能有小数);
第三个成员存储candy bar的热量。请编写一个程序,它使用一个这样的函数,即将CandyBar的引用、char指针、double和int作为参数,
并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为"Millennium Munch"、2.85 和350。
另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。
。*/
struct CandyBar
{
	char pinpai[30];
	double weight;
	int reliang;
};
void setting(CandyBar &cb ,const char*pp="Millennium Munch",const double weight=2.85,const int reliang=350);
void setting(CandyBar &cb, const char*pp, const double weight,const int reliang)
{
	strcpy_s(cb.pinpai, pp);
	cb.reliang = reliang;
	cb.weight = weight;	
}
void display(const CandyBar &cb);

void display(const CandyBar &cb)
{
	cout << "品牌为:" << cb.pinpai<<endl;
	cout << "重量为:" << cb.weight << endl;
	cout << "热量为:" << cb.reliang << endl;
}

void Xiti2()//
{
	CandyBar cb;
	char pinpai[30];
	double weight;
	int reliang;
	setting(cb);
	cout << "默认值\n";
	display(cb);
	cout << "输入品牌:\n";

	cin.get();
	cin.getline(pinpai, 30);
	cout << "输入重量:";
	cin >> weight;
	
	cout << "输入热量:\n";
	cin >> reliang;
	setting(cb, pinpai, weight, reliang);
	display(cb);
	setting(cb);
	cout << "默认值\n";
	display(cb);


	return;
}
/*编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,
为此可使用cctype中的字符函数toupper()。然后编写一个程序,他通过使用一个循环让您能够用不同的输入来测试这个函数。
该程序的运行情况如下:
Enter a string (q to quit): go away
Go AWAY
Next string (q to quit): good grief!
GOOD grief!
Next string (q to quit): q
Bye.


					*/
void toup(string & str);
void toup(string & str)
{
	for (unsigned int i = 0; i < str.size(); i++)
	{
		str[i]=toupper(str[i]);
	}
}
void Xiti3()//简述:
{
	cout << "输入一个字符串:\n";
	string str;
	cin.get();
	getline(cin, str);
	while ('q'!=str[0])
	{
		toup(str);
		cout << str<<endl;
		cout << "来,下一个";
		getline(cin, str);
	}
	cout << "bye!";
	return;
}
/*.请提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每一个都使用默认参数。
请尽可能使用const参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。
(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器)
			   */
struct stringy {
	char * str; // points to a string
	int ct; // length of string (not counting '\0')
};
void set(stringy & be,const char * str);
void set(stringy & be, const char * str)
{
	be.str = new char[strlen(str) + 1];
	strcpy_s(be.str, strlen(str)+1, str);
	be.ct = strlen(str) + 1;
}

void show(stringy&be, int n=1);
void show(stringy&be, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << be.str << endl;
	}
	cout << endl;
}
void show(char *str, int n=1);
void show(char *str, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << str << endl;
	}
	cout << endl;
}
void Xiti4()//
{
	stringy beany;
	char testing[] = "Reality isn't what it used to be.";

	set(beany, testing);// first argument is a reference,
								// allocates space to hold copy of testing, 
								// sets str member of beany to point to the new block,
								// copies testing to new block, and sets ct member of beany
								//第一个参数是一个引用,分配空间来保存testing副本,
								//设置beany的str成员指向新块,将testing复制到新块,
								//并设置beany的ct成员
	show(beany); // prints member string once 
	show(beany, 2);// prints member string twice 
	testing[0] = 'D';
	testing[1] = 'u';
	show(testing);// prints testing string once 
	show(testing, 3);// prints testing string thrice 
	show("Done!");

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

*/
template <typename T>
T max5(T * pp);
template <typename T>
T max5(T * pp)
{
	T a = pp[0];
	for (int i = 1; i < 5; i++)
	{
		if (a < pp[i]) a = pp[i];
	}
	return a;
}
void Xiti5()//
{
	int arr[5] = { 1,2,3,4,5 };
	double arr2[5] = { 1.1,2.2,3.3,4.4,5.5 };
	cout << max5(arr);
	cout << max5(arr2);
	return;
}
/*编写模板函数maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。
   在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个double元素的数组来调用该函数。
   程序还包含一个具体化,它将char指针数组和数组中指针数量作为参数,并返回最长的字符串的地址。
   如果有多个这样的字符串,将返回其中第一个字符的地址。使用由5个字符串指针组成的数组来测试该具体化。

							。*/

template<typename T>
T maxn(T *arr, int n);
template<typename T>
T maxn(T *arr,int n)
{
	T a = arr[0];
	for (int i = 1; i < n; i++)
	{
		if (a<arr[i]) a = arr[i];		
	}
	return a;
}
template <> char*maxn(char * arr[], int n);
template <> char*maxn(char * arr[], int n)
{
	char *a = arr[0];
	for (int i = 1; i < n; i++)
	{
		if (strlen(a)<strlen(arr[i]))
		{
			a = arr[i];
		}
	}
	return a;
}
void Xiti6()//简述:
{
	int arr[6] = { 1,2,3,4,5,6 };
	double arr1[4] = { 1.1,2.2,3.3,4.4 };
	char *arr3[5] = { "asdf","sdghgj","sdfahg","agrgfjnfgj","sdfaew" };
	char *arr4[5] = { "wtesgasdg","awerawegfa","werwagads","wr3gfd","wersdg" };
	cout << maxn(arr, 6) << endl;
	cout << maxn(arr1, 4) << endl;
	cout << maxn(arr3, 5) << endl;
	cout << maxn(arr4, 5) << endl;

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

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

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

struct debts
{
	char name[50];
	double amount;
};
template <typename T>
void SumArray(T arr[], int n)
{
	using namespace std;
	cout << "template A\n";
	T sum = 0;

	for (int i = 0; i < n; i++)
		sum += arr[i];
		cout << sum;
	cout << endl;
}

template <typename T>
void SumArray(T * arr[], int n)
{
	using namespace std;
	cout << "template B\n";
	T sum = 0;
	for (int i = 0; i < n; i++)
		sum += *arr[i];
		cout << sum;
	cout << endl;
}
void Xiti7()//
{
	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];

	// set pointers to the amount members of the structures in mr_E
	for (int i = 0; i < 3; i++)
		pd[i] = &mr_E[i].amount;

	cout << "Listing Mr. E's counts of things:\n";
	// things is an array of int
	SumArray(things, 6);// uses template A
	cout << "Listing Mr. E's debts:\n";
	// pd is an array of pointers to double
	SumArray(pd, 3);// uses template B (more specialized)
						   // cin.get();

	return;


}
/* 在不使用array类的情况下完成程序7.15 所做的工作,编写这样的两个版本:
   a. 使用 const char* 数组存储表示季度名称的字符串,并使用double数组存储开支。
      b. 使用 const char*数组存储表示季度名称的字符串,并使用一个结构,该结构只有一个成员——一个用于存储开支的数组。
	    这种设计与使用array类的基本设计类似。
		程序7.15 如下:
		。
		*/


void Xiti8()//
{
	return;
}
/* 这个练习让您编写处理数组和结构的函数。
下面是程序框架,请提供其中描述的函数,以完成该程序。
。*/


// getinfo() has two arguements:a pointer to the first element of an array of student structures 
// and an int representing the number of element of the array.
// getinfo()有两个参数:指向student结构数组的第一个元素的指针和一个表示数组元素个数的int。  
// The function solicits and stores data about students. 
// 该函数征求并存储有关学生的数据。
// It terminates input upon filling the array pr upon encountering a blank line for the student name. 
// 它在遇到学生姓名的空行时填写数组pr时终止输入。
// The function returns the actual number of array element filled.
// 该函数返回填充的数组元素的实际数量。


// display1() takes a student structures as an argument and displays its contents
// display1() 将student结构作为参数并显示其内容 




// display3() takes the address of the first element of an array of student structures and 
// the number of number of array element as arguements and displays the contents of the structures
// display3()将student结构数组的第一个元素的地址和数组元素的数量作为参数,并显示结构的内容

void Xiti9()//
{
	
	return;
}
/*
设计一个名为calculate()的函数,接受两个double值和一个指向函数的指针,而被指向的函数接受两个double参数,并返回一个double值。
calculate()函数的类型也是double,并返回被指向的函数使用calculate()的两个double参数计算得到的值。例如,假设add()函数的定义如下:
double add(double x, double y)
    {
	        return x + y;
			    }
				 则下述代码中的函数调用将导致calculate()把2.5 和10.4 传递给add()函数,并返回add()的返回值(12.9):
				 double q = calculate(2.5, 10.4, add);
				 请编写一个程序,它调用上述两个函数和至少另一个与add()类似的函数。该程序使用循环来让用户成对地数入数字。
				 对于每一个数字,程序都使用calculate()来调用add()和至少一个其他的函数。
				    

					如果读者爱冒险,可以尝试创建一个指针数组,其中的指针指向add()样式的函数,并编写一个循环。                                           使用这些指针连续让calculate()调用这些函数。
					    提示:声明这种指针数组的方式为: double (*pf[3])(double, double);    其中包含三个指针
						    可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。

							*/


void Xiti10()//
{
	

	return;
}
void Xiti10_2()//
{
	
	return;
}
int main()
{
	int XitiNo = 1;//输入习题编号
	cout << "第四章编程练习答案:\n";

	cout << "请输入习题编号或按(0)退出:\n";
	cin >> XitiNo;
	while (XitiNo != 0)

	{
		if (cin)//输入合法则执行
		{

			if (XitiNo >= 0 && XitiNo <= 10)
			{
				switch (XitiNo)
				{
				case 0:
				{
					cout << "即将退出程序啦!\n";

				}break;
				case 1:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti1();

				}break;
				case 2:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti2();
				}break;
				case 3:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti3();

				}break;
				case 4:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti4();
				}break;
				case 5:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti5();
				}break;
				case 6:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti6();


				}break;
				case 7:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti7();
				}break;
				case 8:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti8();
				}break;
				case 9:
				{
					cout << "第" << XitiNo << "题如下:\n";
					Xiti9();
				}break;
				case 10:
				{
					cout << "第" << XitiNo << "题如下:\n";
					//Xiti10();
					Xiti10_2();
				}break;
				default:
				{

					cout << "即将退出程序啦\n";
					XitiNo = 0;
				}
				break;
				}

				cout << "继续查看请输入习题编号或按(0)退出:\n";
				cin >> XitiNo;
			}
			else
			{
				cout << "没有这样的编号\n继续查看请输入习题编号或按(0)退出:\n";
				cin >> XitiNo;
			}

		}
		else//输入不合法则重新输入
		{
			XitiNo = 0;
		}
	}
	system("pause");//为了程序能够停下看看。
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泽龙先生~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值