C++ primer Plus(第六版)第七章函数 编程

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

#include "stdafx.h"
#include //预编译,使用iostream文件在编译前替代这行代码
#include 
#include 
#include 

const int SIZE = 101;

using namespace std;//将使用std命名空间中的定义
/*  编写一个程序,不断要求用户输入两个数,直到其中一个为0。
    对于每两个数,程序将使用一个函数来计算他们的调和平均数,并将结果返回给main(),而后者将报告结果。
    调和平均数指的是倒数平均值的倒数。计算公式为: 调和平均数=2.0*x*y/(x+y)。*/
double tiaohe(double, double);
double tiaohe(double x, double y)
{
	double z;
	z = 2.0*x*y / (x + y);
	return z;
}


void Xiti1()//
{
	double d1, d2;
	while (cin>>d1>>d2&&(d1!=0||d2!=0))
	{
		//d3=tiaohe(d1, d2);
		cout << "调和平均数为:"<<tiaohe(d1, d2) << endl;
	}

	return;
}
/*. 编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存储在一个数组中。
   程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。
   请使用3个数组处理函数来分别进行输入、显示和计算平均成绩。。*/
int input(double chengji[], int time);
double avge(double chengji[],int time);
void display(double chengji[], int time, double avge);
const int SIZE1 = 10;
int input(double chengji[],int time)
{
	int i;
	for ( i = 0; i < time;i++)
	{
		if(!(cin >> chengji[i])) break;
	}	
	return i;
}
double avge(double chengji[], int time)
{
	int i;
	double sum=0;
	for ( i = 0; i < time; i++)
	{
		sum += chengji[i];
	}
	return sum / time;
}
void display(double chengji[], int time, double avge)
{
	int i;
	for ( i = 0; i < time; i++)
	{
		cout << chengji[i]<<" ";
	}
	cout <<"平均值:" <<avge << endl;
}
void Xiti2()//
{
	double *grade = new double[SIZE1];
	double average;
	int time=SIZE1;
	time=input(grade,time);
	average = avge(grade,time);
	display(grade,time,average);
	return;
}
/*下面是一个结构声明
struct box
{
    char maker[40];
    float height;
    float width;
    float length;
    float volume;
};
a. 编写一个函数,按值传递box结构,并显示每一个成员的值
b. 编写一个函数,传递box结构的地址,并将volume成员设置为其他三维长度的乘积
c. 编写一个使用这两个函数的简单程序

				  */
struct box
{
	char maker[40];
	float height;
	float width;
	float length;
	float volume;
};
void display(box bb);
void display(box bb)
{
	cout <<  "高度:"<<bb.height<<endl<<"长度:" << bb.length<<endl<<"宽度:" << bb.width <<"体积:"<< bb.volume<<endl;
}
void tiji(box*point);
void tiji(box*pp)
{
	cout << "输入长度:";
	cin >> pp->length;
	cout << "输入宽度:";
	cin >> pp->width;
	cout << "输入高度:";
	cin >> pp->height;
	pp->volume = pp->height*pp->length*pp->width;
}
void Xiti3()//简述:
{
	box changfang;
	tiji(&changfang);
	display(changfang);
	return;
}
/*.许多州的彩票发行机构都使用如程序清单7.4 所示的简单彩票玩法的变体。
   在这些玩法中,玩家从一组被称为域号码(field number)的号码中选择几个。
   例如,可以从域号码1~47 中选择5个号码;还可以从第二个区间(如1~27 )选择一个号码(称为特选号码)。
   要赢得头奖,必须正确猜中所有的号码。中头奖的几率是选中所有域号码的几率与选中特选号码几率的乘积。
   例如,在这个例子中,中头奖的几率是从47个号码中正确选择5个号码的几率与从27个号码中正确选择一个号码几率的乘积。
   请修改程序清单7.4, 以计算中得这种彩票头奖的几率。


																			*/
double jilv(unsigned number, unsigned pick);
double jilv(unsigned number, unsigned pick)
{
	double result=1;
	unsigned m, p;
	for (m = number,p=pick; p >0;m--,p--)
	{
		result = result*m / p;	
	}
	return result;
}
void Xiti4()//
{
	cout << "输入第一组号码总数和选取的数:";
	unsigned total1, piack1, total2, piack2;
	double jj,kk;
	
	while ((cin >> total1  >> piack1 >> total2>> piack2)&&piack1 <= total1)
	{
		jj = jilv(total1, piack1);
		kk = jilv(total2, piack2);
		cout<<"获奖几率:"<<jj*kk<<"中选1";
	}
	return;
}
/*.定义一个递归函数,接受一个整数参数,并返回该函数的阶乘。前面讲过,3的阶乘写作3!,等于3*2!,
   以此类推;而0!被定义为1.通用的公式是,如果n大于零,则n!=n*(n-1)!。在程序中对该函数进行测试,
   程序使用循环让用户输入不同的值,程序将报告这些值的阶乘。
*/
double jiecheng(int);
double jiecheng(int num)
{
	//unsigned result;
	if (num < 2)  return 1;
	else 	return num*jiecheng(num - 1);
	
}
void Xiti5()//
{
	
	int money;
	
	while (cin >> money)
	{
		
		cout <<money<< "的阶乘为:" << jiecheng(money) << endl;
	}
	return;
}
/*编写一个程序,它使用下列函数:
    Fill_array()将一个double数组的名称和长度作为参数。
    它提示用户输入double的值,并将这些值存储到数组中。
    当数组被填满或者或用户输入了非数字时,输入将停止,并返回实际输入了多少数字。
    Show_array()将一个double数组的名称和长度作为参数,并显示该数组的内容。
    Reverse_array()将一个double数组的名称的长度作为参数,并将存储在数组中的值的顺序反转。
    程序将使用这些函数来填充数组,然后显示数组;反转数组,然后显示数组;
    反转数组中除第一个和最后一个元素之外的所有元素,然后显示数组。

					 。*/
int Fill_array(double arr[],int size);
int Fill_array(double arr[], int size)
{
	int i=0;
	cout << "输入" << size << "个double型数据\n";
	for ( i = 0; i < size; i++)
	{
		if (cin >> arr[i]&& (i != size - 1))
		{
			
			cout << "还需要输入" << size - 1 - i << "个double数据\n";			
		}
	}
	
	return i;
}
void Show_array(double arr[], int size);
void Show_array(double arr[], int size)
{
	for (int i = 0; i < size; i++)
	{
		cout << arr[i]<<" ";
	}
	cout << endl;
}
void Reverse_array(double arr[], int size);
void Reverse_array(double arr[], int size)
{
	double temp;
	for (int i = 1; i < size/2; i++)
	{
		temp = arr[i];
		arr[i] = arr[size - 1 - i];
		arr[size - 1 - i] = temp;
	}
}

void Xiti6()//简述:
{
	cout << "输入数组的长度:\n";
	int num;
	//double *pp;
	if (cin >> num)
	{
		double * pp = new double[num];
		cin.get();

		cout << "一共" << Fill_array(pp, num)<<"个数据。";
		Show_array(pp, num);
		cout << "翻转一下子啊:\n";
		Reverse_array(pp, num);
		Show_array(pp, num);
		//delete pp;
	}
	else cout << "输入不规范!\n";
	
	return;
}
/*修改程序清单7.7 中的3个数组处理函数,使之使用两个指针参数来表示区间。
   fill_array()函数不返回实际读取了多少个数字,而是返回一个指针,该指针指向最后被填充的位置;
   其他函数可以将该指针作为第二个参数,以标识数据结尾。
   程序清单7.7 如下:

				*/
double* fill_array1(double ar[], int limit);
void show_array(const double ar[], double*lastpoint); 
void revalue(double r, double ar[], double*lastpoint);

const int Max = 5;
double* fill_array1(double ar[], int limit)
{
	
	double temp;
	int i;
	for (i = 0; i < limit; i++)
	{
		cout << "Enter value #" << (i + 1) << ": ";
		cin >> temp;
		if (!cin) 
		{
			cin.clear();
			while (cin.get() != '\n')
				continue;
			cout << "Bad input; input process terminated.\n";
			break;
		}
		else if (temp < 0) 
			break;
		ar[i] = temp;
	}
	return ar+i;
}


void show_array(const double ar[], double*lastpoint)
{
	using namespace std;
	for (int i = 0; i < lastpoint-ar; i++)
	{
		cout << "Property #" << (i + 1) << ": $";
		cout << ar[i] << endl;
	}
}


void revalue(double r, double ar[], double*lastpoint)
{
	for (int i = 0; i < lastpoint - ar; i++)
		ar[i] *= r;
}

void Xiti7()//
{
	double properties[Max];

	double*size= fill_array1(properties, Max);
	show_array(properties, size);
	if (size > properties)
	{
		cout << "Enter revaluation factor: ";
		double factor;
		while (!(cin >> factor))
		{
			cin.clear();
			while (cin.get() != '\n')
				continue;
			cout << "Bad input; Please enter a number: ";
		}
		revalue(factor, properties, size);
		show_array(properties, size);
	}
	cout << "Done.\n";
	return;


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

//const array Snames =
//{ "Spring", "Summer", "Fall", "Winter" };
const char*Snames[Seasons]= { "Spring", "Summer", "Fall", "Winter" };
struct mys
{
	double mypp[Seasons];
};
void fill(mys *shuju);
void show(mys *shuju);
void fill(mys *shuju)
{
	for (int i = 0; i < Seasons; i++)
	{
		cout << "Enter " << Snames[i] << " expenses: ";
		cin >> shuju->mypp[i];
	}
}

void show(mys *shuju)
{
	double total = 0.0;
	cout << "\nEXPENSES\n";
	for (int i = 0; i < Seasons; i++)
	{
		cout << Snames[i] << ": $" << shuju->mypp[i] << '\n';
		total += shuju->mypp[i];
	}
	cout << "Total: $" << total << '\n';
}

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

struct student {
	char fullname[SLEN];
	char hobby[SLEN];
	int ooplevel;
};

// 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.
// 该函数返回填充的数组元素的实际数量。

int getinfo(student pa[], int n);
int getinfo(student pa[], int n)
{
	int i;
	for ( i = 0; i < n; i++)
	{
		cout << "输入第" << i + 1 << "个学生的信息\n";
		cout << "姓名:";
		cin.getline(pa[i].fullname, SLEN);
		cout << "爱好:";
		cin.getline(pa[i].hobby, SLEN);
		cout << "ooplevel:";
		cin >> pa[i].ooplevel;
		cin.get();
	}
	return i;
}

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

void diaplay1(student st);
void diaplay1(student st)
{
	cout << "display1 学生姓名:" << st.fullname << endl;
	cout << "display1 爱好:" << st.hobby << endl;
	cout << "display1 ooplevel:" << st.ooplevel << endl;	
}

// display2() take the address of student structure as an arguement and displays the structure's contents
// display 2() 以学生结构的地址为参数,显示结构的内容
void display2(const student * ps);
void display2(const student * ps)
{
	cout << "display2 学生姓名:" << ps->fullname << endl;
	cout << "display2 爱好:" << ps->hobby << endl;
	cout << "display2 ooplevel:" << ps->ooplevel << endl;

}


// 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 display3(const student pa[], int n);

void display3(const student pa[], int n)
{
	for (const student* stu_point = pa; stu_point != pa + n; stu_point++)
	{
		cout << "display3 学生姓名:" << stu_point->fullname << endl;
		cout << "display3 爱好:" << stu_point->hobby << endl;
		cout << "display3 ooplevel:" << stu_point->ooplevel << endl;
	}
}
void Xiti9()//
{
	cout << "Enter class size:";
	int class_size;
	cin >> class_size;
	while (cin.get() != '\n')
		continue;
	student * ptr_stu = new student[class_size];
	int entered = getinfo(ptr_stu, class_size);
	for (int i = 0; i < entered; i++)
	{
		diaplay1(ptr_stu[i]);
		display2(&ptr_stu[i]);
	}
	display3(ptr_stu, entered);
	delete[] ptr_stu;
	cout << "Done\n";
	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);    其中包含三个指针
												      可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。
													 
*/
double add(double x, double y);
double mul(double x, double y);
double sub(double x, double y);
double div(double x, double y);
double calculate(double x, double y,double (*ppp)(double,double));
double add(double x, double y)
{
	return x + y;
}
double mul(double x, double y)
{
	return x*y;
}
double sub(double x, double y)
{
	return x - y;
}
double div(double x, double y)
{
	return x / y;
}
double calculate(double x, double y, double(*ppp)(double, double))
{
	return ppp(x,y);
}

void Xiti10()//
{
	cout << "请输入2个数字用空格隔开:\n";
	double x, y;
	char choose;
	while (cin >> x >> y)
	{
		cin.get();
		cout << "请输入运算符:+-*/\n";
		if (cin.get(choose))
		{
			switch (choose)
			{
			case '+': cout << x << choose << y << "=" << calculate(x, y, add) << endl;
				break;
			case '-': cout << x << choose << y << "=" << calculate(x, y, sub) << endl;;
				break;
			case '*': cout << x << choose << y << "=" << calculate(x, y, mul) << endl;;
				break;
			case '/': cout << x << choose << y << "=" << calculate(x, y, div) << endl;;
				break;
			default:
				cout << "输入错误!\n";
				break;
			}
			
		}
		cout << "请输入2个数字用空格隔开:\n";
		
	}

	return;
}
void Xiti10_2()//
{
	cout << "请输入2个数字用空格隔开:\n";
	double x, y;
//	char choose;
	double(*pf[4])(double, double) = {add,sub,mul,div};
	while (cin >> x >> y)
	{
		cin.get();
		for (int i = 0; i < 4; i++)
		{
			cout << calculate(x, y, pf[i])<<endl;
		}
		cout << "请输入2个数字用空格隔开:\n";

	}

	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;
}

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