C++ Primer Plus (第六版)编程练习记录(chapter7)

1.编写一个程序,不断要求用户输入两个数,直到其中的一个为0。对于每两个数,程序将使用一个函数来计算它们的调和平均数,并将结果返回给main( ),而后者将报告结果。调和平均数指的是倒数平均值的倒数,计算公式如下:
调和平均数=2.0h’b’h

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/03
* 描述:
************************************************* */
#include 
double ave(double x, double y);//函数声明
int main()
{
	using namespace std;

	cout << "Enter two numbers,return harmonic average.\n";
	double num1, num2;
	cin >> num1 >> num2;
	while ((num1 != 0) && (num2 != 0))
	{
		cout << "The harmonic average is " << ave(num1, num2) << ".\n";
		cin >> num1 >> num2;
	}
	return 0;
}
double ave(double x, double y)//函数原型
{
	double average = 2.0 * x * y / (x + y);
	return average;
}

2.编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存储在一个数组中。程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。请使用3个数组处理函数来分别进行输入、显示和计算平均成绩。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/03
* 描述:
************************************************* */
#include 

using namespace std;

void inputScore(double in[], int limit);
void outputScore(const double out[], int limit);//本函数只要求显示,故用const
double calScore(double num[], int limit);

int main()
{

	cout << "Enter your score.\n";
	double score[10];
	inputScore(score, 10);
	outputScore(score, 10);
	cout<<"Average: "<<calScore(score, 10);
	return 0;
}
void inputScore(double in[], int limit)
{
	cout << "Enter 'q' to quit.\n";
	double temp;
	int i = 0;
	cin >> temp;
	while ((temp != 'q') && ( i<limit ))
	{
		in[i]=temp;
		i++;
		cin >> temp;
	}
}
void outputScore(const double out[],int limit)
{
	for (int i = 0;i < limit;i++)
	{
		cout << out[i] << "  ";
	}
	cout << endl;
}
double calScore(double num[], int limit)
{
	double ave;
	double total = 0;
	for (int i = 0;i < limit;i++)
		total += num[i];
	ave = total / limit;
	return ave;
}

3.下面是一个结构声明:
C++ Primer Plus (第六版)编程练习记录(chapter7)_第1张图片
a.编写一个函数,按值传递box结构,并显示每个成员的值。
b.编写一个函数,传递box结构的地址,并将volume成员设置为其他三维长度的乘积。
c.编写一个使用这两个函数的简单程序。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/03
* 描述:
************************************************* */
#include 
using namespace std;

struct box
{
	char maker[40];
	float height;
	float width;
	float length;
	float volume;
};
void display(const box obj);
void calcuVolume(box *obj);

int main()
{	
	box squ1 = { "China",100,50,80 };
	display(squ1);
	calcuVolume(&squ1);//传递的是结构的地址
	display(squ1);
	return 0;
}
void display(const box obj)
{
	cout << "Maker: "<< obj.maker << endl;
	cout << "Height: "<<obj.height << endl;
	cout << "Width: "<<obj.width << endl;
	cout << "Length: " << obj.length << endl;
	cout << "Volume: " << obj.volume << endl;
};
void calcuVolume(box *obj)
{
	obj->volume = obj->height * obj->width * obj->length;
};

4.许多州的彩票发行机构都使用如程序清单7.4所示的简单彩票玩法的变体。在这些玩法中,玩家从一组被称为域号码(field number)的号码中选择几个。例如,可以从域号码1~47中选择5个号码;还可以从第二个区间(如1~27)选择一个号码(称为特选号码)。要赢得头奖,必须正确猜中所有的号码。中头奖的几率是选中所有域号码的几率与选中特选号码几率的乘积。例如,在这个例子中,中头奖的几率是从47个号码中正确选取5个号码的几率与从27个号码中正确选择1个号码的几率的乘积。请修改程序清单7.4,以计算中得这种彩票头奖的几率。
C++ Primer Plus (第六版)编程练习记录(chapter7)_第2张图片

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/03
* 描述:
************************************************* */

#include 
using namespace std;

long double probability(unsigned number1,unsigned number2, unsigned pick1,unsigned pick2);
int main()
{	
	double fieldNum,specialNum, fieldChoices,specialChoices;//函数声明
	cout << "Enter the total number of choices(field number and special number) on the game card\n "
		"and the number of picking allowed(field number and special number):\n";
	while ((cin >> fieldNum >> specialNum>> fieldChoices>>specialChoices) && (fieldChoices <=fieldNum)&&(specialChoices<=specialNum))
	{
		cout << "You have one chance in ";
		cout << probability(fieldNum, specialNum, fieldChoices, specialChoices);//函数调用
		cout << " of winning.\n";
		cout << "Next two numbers (q to quit).\n";
	}
	cout << "bye.\n";
	return 0;
}
long double probability(unsigned number1, unsigned number2, unsigned pick1, unsigned pick2)//函数原型,增加number2和pick2来处理特殊号码
{
	long double result1 = 1.0;
	long double result2 = 1.0;
	long double result = 1.0;
	long double n;
	unsigned p;

	for (n = number1, p = pick1;p > 0;n--, p--)
		result1 = result1 * n / p;
	for (n = number2, p = pick2;p > 0;n--, p--)
		result2 = result2 * n / p;
	result = result1 * result2;
	return result;
}

5.定义一个递归函数,接受一个整数参数,并返回该参数的阶乘。前面讲过,3的阶乘写作3!,等于32!,依此类推;而0!被定义为1。通用的计算公式是,如果n大于零,则n!=n(n−1)!。在程序中对该函数进行测试,程序使用循环让用户输入不同的值,程序将报告这些值的阶乘。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/03
* 描述:
************************************************* */

#include 
using namespace std;

long double factorial(int num);
int main()
{	
	cout << "Enter a number,return factorial('886' to quit).\n";
	int num;
	long double result;
	while ((cin >> num) && (num != 886))
	{
		result = factorial(num);
		cout << "Its factorial is " << result << "." << endl;
	}
	return 0;
}
long double factorial(int num)
{
	long double result;
	if (num == 0)
		result=1;
	else
		result = num * factorial(num - 1);
	return result;
}

6.编写一个程序,它使用下列函数:
Fill_array( )将一个double数组的名称和长度作为参数。它提示用户输入double值,并将这些值存储到数组中。当数组被填满或用户输入了非数字时,输入将停止,并返回实际输入了多少个数字。
Show_array( )将一个double数组的名称和长度作为参数,并显示该数组的内容。
Reverse-array( )将一个double数组的名称和长度作为参数,并将存储在数组中的值的顺
序反转。
程序将使用这些函数来填充数组,然后显示数组;反转数组,然后显示数组;反转数组中除第一个和最后一个元素之外的所有元素,然后显示数组。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:
************************************************* */
#include 
using namespace std;

bool Fill_array(double ar[], int length);
void Show_array(const double ar[], int length);
void Reverse_array(double ar[], int length);

int main()
{	
	double arr[10];
	if (Fill_array(arr, 10) != 0)//输入正确执行下列变化代码,否则不执行
	{
		Show_array(arr, 10);
		Reverse_array(arr, 10);
		Show_array(arr, 10);
		Reverse_array(arr + 1, 8);
		Show_array(arr, 10);
	}
	return 0;
}
bool Fill_array(double ar[], int length)
{
	bool flag = 1;//输入检测标记,检测输入是否正确
	cout << "Enter number.\n";
	double num;
	int i = 0;
	while (i<length)
	{
		if (cin>>num)
		{
			ar[i] = num;
			i++;
		}
		else
		{
			cout << "Wrong enter.\n";
			flag = 0;
			break;
		}
	}
	cout << "Have entered " << i << " numbers.\n";
	return flag;
}
void Show_array(const double ar[], int length)
{
	for (int i = 0;i < length;i++)
		cout << ar[i] << "\t";
	cout << endl;
}
void Reverse_array(double ar[], int length)
{
	double temp;
	for (int i = 0;i < (length / 2);i++)
	{
		temp = ar[i];
		ar[i] = ar[length - 1 - i];
		ar[length - 1 - i] = temp;
	}
}

7.修改程序清单7.7中的3个数组处理函数,使之使用两个指针参数来表示区间。
fill_array( )函数不返回实际读取了多少个数字,而是返回一个指针,该指针指向最后被填充的位置;其他的函数可以将该指针作为第二个参数,以标识数据结尾。
程序清单7.7:

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:程序清单7.7,输入数字并显示,再输入影响因子,与原来数字相乘后再显示。
************************************************* */
#include 
const int Max = 5;

int fill_array(double ar[], int limit);
void show_array(const double ar[], int n);
void revalue(double r, double ar[], int n);

int main()
{	
	using namespace std;
	double properties[Max];

	int size = fill_array(properties, Max);//获得输入的个数size
	show_array(properties, size);
	if (size > 0)
	{
		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";
	cin.get();
	cin.get();
	return 0;
}
int fill_array(double ar[], int limit)
{
	using namespace std;
	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 i;
}
void show_array(const double ar[], int n)
{
	using namespace std;
	for (int i = 0;i < n;i++)
	{
		cout << "Property #" << (i + 1) << ": $";
		cout << ar[i] << endl;
	}
}
void revalue(double r, double ar[], int n)
{
	for (int i = 0;i < n;i++)
		ar[i] *= r;
}
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:使用两个指针处理数组。
************************************************* */
#include 
const int Max = 5;

double * fill_array(double ar[], int limit);
void show_array(const double ar[], const double * array_end);
void revalue(double r, double ar[], double * array_end);

int main()
{	
	using namespace std;
	double properties[Max];

	double *propeties_end = fill_array(properties, Max);
	show_array(properties, propeties_end);
	if ((propeties_end - properties ) > 0)
	{
		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, propeties_end);
		show_array(properties, propeties_end);
	}
	cout << "Done.\n";
	cin.get();
	cin.get();
	return 0;
}
double* fill_array(double ar[], int limit)
{
	using namespace std;
	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[], const double * array_end)
{
	using namespace std;
	const double * pt = ar;
	int i = 0;
	for (pt = ar;pt < array_end;pt++)
	{
		cout << "Property #" << (i + 1) << ": $";
		cout << ar[i] << endl;
		i++;
	}
}
void revalue(double r, double ar[], double * array_end)
{
	double * pt;
	int i = 0;
	for (pt = ar;pt < array_end;pt++)
	{
		ar[i] *= r;
		i++;
	}
}

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

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:程序清单7.15
************************************************* */
#include 
#include 
#include 

const int Seasons = 4;
const std::array<std::string, Seasons> Snames = { "Spring","Summer","Fall","Winter" };

void fill(std::array<double, Seasons>* pa);
void show(std::array<double, Seasons> da);

int main()
{	
	std::array<double, Seasons> expense;
	fill(&expense);
	show(expense);	
	return 0;
}
void fill(std::array<double, Seasons>* pa)
{
	using namespace std;
	for (int i = 0;i < Seasons;i++)
	{
		cout << "Enter " << Snames[i] << " expense: ";
		cin >> (*pa)[i];
	}
}
void show(std::array<double, Seasons> da)
{
	using namespace std;
	double total = 0.0;
	cout << "\nEXPEXSES\n";
	for (int i = 0;i < Seasons;i++)
	{
		cout << Snames[i] << ": $" << da[i] << endl;
		total += da[i];
	} 
	cout << "Total Expense: $" << total << endl;
}
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:
************************************************* */
#include 

const int Seasons = 4;
const char * Snames[Seasons] = { "Spring","Summer","Fall","Winter" };  

void fill(double * pa);
void show(double * pa);

int main()
{	
	double expense[Seasons];
	fill(expense);
	show(expense);	
	return 0;
}
void fill(double * pa)
{
	using namespace std;
	for (int i = 0;i < Seasons;i++)
	{
		cout << "Enter " << Snames[i] << " expense: ";
		cin >> pa[i];
	}
}
void show(double * pa)
{
	using namespace std;
	double total = 0.0;
	cout << "\nEXPEXSES\n";
	for (int i = 0;i < Seasons;i++)
	{
		cout << Snames[i] << ": $" << pa[i] << endl;
		total += pa[i];
	} 
	cout << "Total Expense: $" << total << endl;
}
/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:程序清单7.15(b)
************************************************* */
#include 

const int Seasons = 4;
const char * Snames[Seasons] = { "Spring","Summer","Fall","Winter" };  
struct Expense
{
	double money[Seasons];
};

void fill(Expense *pa);
void show(Expense pa);

int main()
{	
	Expense exp;
	fill(&exp);//传递结构体地址
	show(exp);	//按值传递
	return 0;
}
void fill(Expense *pa)
{
	using namespace std;
	for (int i = 0;i < Seasons;i++)
	{
		cout << "Enter " << Snames[i] << " expense: ";
		cin >> pa->money[i];
	}
}
void show(Expense pa)
{
	using namespace std;
	double total = 0.0;
	cout << "\nEXPEXSES\n";
	for (int i = 0;i < Seasons;i++)
	{
		cout << Snames[i] << ": $" << pa.money[i] << endl;
		total += pa.money[i];
	} 
	cout << "Total Expense: $" << total << endl;
}

9.这个练习让您编写处理数组和结构的函数。下面是程序的框架,请提供其中描述的
函数,以完成该程序。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/04
* 描述:程序清单7.15
************************************************* */
#include 
using namespace std;
const int SLEN = 30;
struct student {
	char fullname[SLEN];
	char hobby[SLEN];
	int ooplevel;
};
//getinfo() has two argumnets: a pointer to the first element of
//an array of student structures and an int representing the
//number of elemnets of the array. The function solicits and
//stores data about students. It terminates input upon filling
//the array or upon encountering a blank line for the student
//name. The function returns the actual number of array elemnets
//filled.
int getinfo(student pa[], int n);

//display1() takes a student structure as an argument
//and displays its contents
void display1(student st);

//display2() takes the address of student struture as an
//argument and displays the stucture's contents
void display2(const student* ps);

//display3() takes the address of the first elemnet of an array
//of student structures and the number of array elemnets as
//arguments and displays the contents of the structures
void display3(const student pa[], int n);

int main()
{
	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)
	{
		display1(ptr_stu[i]);
		display2(&ptr_stu[i]);
	}
	display3(ptr_stu, entered);
	delete[] ptr_stu;
	cout << "Done\n";
	return 0;
}
int getinfo(student pa[], int n)
{
	cout << "Enter their infomation.\n";
	int i;
	for (i = 0;i < n;i++)
	{
		cout << "Student " << i+1 << " :\n";
		cout << "Name: ";
		cin.getline(pa[i].fullname, SLEN);
		//cin >> pa[i].fullname;
		cout << "Hobby: ";
		cin >> pa[i].hobby;
		cout << "Ooplevel: ";
		cin >> pa[i].ooplevel;
	}
	return i;
}
void display1(student st)
{
	cout << "Name: " << st.fullname << endl;
	cout << "Hobby: " << st.hobby << endl;
	cout << "Ooplevel: " << st.ooplevel<< endl;
}
void display2(const student* ps)
{
	cout << "Name: " << ps->fullname << endl;
	cout << "Hobby: " << ps->hobby << endl;
	cout << "Ooplevel: " << ps->ooplevel << endl;
}
void display3(const student pa[], int n)
{
	for (int i = 0;i < n;i++)
	{
		cout << "Student " << i + 1 << " :\n";
		cout << "Name: " << pa[i].fullname << endl;
		cout << "Hobby: " << pa[i].hobby << endl;
		cout << "Ooplevel: " << pa[i].ooplevel << endl;
	}
}

10.设计一个名为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);
可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。

/* *************************************************
* 文件名:
* 创建人:px
* 创建时间:2020/3/05
* 描述:程序清单7.15
************************************************* */
#include 
using namespace std;

double add(double x, double y);
double sub(double x, double y);
double mean(double x, double y);
double calculate(double a, double b, double (*pt)(double x, double y));

int main()
{
	double num1;
	double num2;
	double (*pt[3])(double x, double y) = { add,sub,mean };//三个指针,指向三个函数
	const char* pc[3] = { "Add","Subtraction","Mean" };
	cout << "Enter 2 numbers('q' to quit): \n";
	while (cin >> num1 >> num2)
	{
		if ((num1 == 'q') && (num2 == 'q'))
		{
			cout<<"Wrong input.\n";
			break;
		}
		for (int i = 0;i < 3;i++)
		{
			cout << pc[i] << ": " << calculate(num1, num2, (*pt[i])) << endl;
		}
	}

	return 0;
}
double add(double x, double y)
{
	return x+y;
}
double sub(double x, double y)
{
	return x-y;
}
double mean(double x, double y)
{
	return ((x+y)/2.0);
}
double calculate(double a, double b, double (*pt)(double x, double y))
{
	return (*pt)(a, b);
}

你可能感兴趣的:(C++编程)