第七章 编程练习 (C++ Primer Plus)

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

#include <iostream>

double CalTiaoHe(double,double);

int main()
{
	using std::cout;
	using std::cin;
	using std::endl;
	cout << "请输入两个数(终止程序请输入0)"<< endl;
	double x, y;
	cout << "x: _\b";
	cin >> x;
	cout << "y: _\b";
	cin >> y;
	while(x != 0 && y != 0)
	{
		cout << "调和平均数为:" << CalTiaoHe(x,y) << endl;	
		cout << "x: _\b";
		cin >> x;
		cout << "y: _\b";
		cin >> y;
	}	
	cout << "程序终止" << endl;
	return 0;
}
double CalTiaoHe(double x, double y)
{
	return (2.0 * x * y / (x + y));
}

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

#include<iostream>

const int ArraySize =  10;
void FillArray(double arr[], const int arrSize);
void ShowArray(double arr[], const int arrSize);
double CalAverage(double arr[], const int arrSize);

int main()
{
	using std::cout;
	using std::endl;
	
	double array[ArraySize] = {0};
	FillArray(array,ArraySize);
	ShowArray(array,ArraySize);
	cout << "平均值:"<<CalAverage(array,ArraySize) << endl;
	return 0;	
 } 
 
void FillArray(double arr[], const int arrSize)
{
	using std::endl;
	using std::cout;
	using std::cin;
	
	double temp;
	
	for (int i = 0; i < arrSize; i++)
	{
		cout << "#" << 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;
		arr[i] = temp;
	 } 
}

void ShowArray(double arr[], const int arrSize)
{
	using std::endl;
	using std::cout;
	
	for(int i = 0; i < arrSize; i++)
	{
		if(arr[i] == 0)
			continue;
		cout << arr[i] << " ";	
	}
}

double CalAverage(double arr[], const int arrSize)
{
	using std::endl;
	using std::cout;
	
	int num = 0 ,sum = 0;
	for (int i = 0; i < arrSize; i++)
	{
		if(arr[i] > 0)
		{
			num++;
			sum += arr[i];	
		}
	}
	return (sum/num);	
}

3.下面是一个结构声明:

struct box
{
	char maker[40]
	float height
	float width
	float length;
	float volume
}

a.编写一个函数,按值传递box结构,并显示每个成员的值
b.编写一个函数,传递box结构的地址,并将 volume成员设置为其他三维长度的乘积
c.编写一个使用这两个函数的简单程序。

#include <iostream>

struct box
{
	char maker[40];
	float height;
	float width;
	float length;
	float volume;
};

void ShowBox(box );
void SetBox(box *);

int main()
{
	box bx {"jlm",25.0,34.2,11.2};
	SetBox(&bx);
	ShowBox(bx);
	return 0;
}

void ShowBox(box BB)
{
	using std::endl;
	using std::cout;
	
	cout << BB.maker << endl;
	cout << BB.height << endl;
	cout << BB.width << endl;
	cout << BB.length << endl;
	cout << BB.volume << endl;
}

void SetBox(box *pb)
{
	using std::endl;
	pb -> volume = pb -> height * pb -> width * pb -> length;
}

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

#include <iostream>

long double probability(unsigned numbers , unsigned picks , unsigned texuan);

int main()
{
	using namespace std;
	unsigned total,choices, texuan;
	cout << "Enter the total number of chices on the game card and\n "
		<< "the number of picks allowed:\n";
		while((cin >>total >>choices>> texuan) && choices <= total)
		{
			cout << "You have one chance in ";
			cout.setf(ios_base::dec,ios_base::basefield);
			cout << probability(total, choices ,texuan);
			cout << " of winning.\n";
			cout << "Next two numbers(q to quit):";
		}
		cout << "bye\n";
		return 0;
}

long double probability(unsigned numbers, unsigned picks, unsigned texuan)
{
	long double result = 1.0;
	long double n;
	unsigned p;
	
	for (n = numbers,p = picks; p > 0; n--, p--)
		result = result * n / p;
	return result*texuan;
}

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

#include<iostream>

long DiGui(int n)
{
	long temp;
	if (n == 0)
		return 1L;
	temp = n * DiGui(n - 1);
	return temp;
}

int main()
{
	using namespace std;
	int num;
	cout << "请输入数据"<< endl; 
	while(cin >> num && num >= 0)
	{
		cout << num << "!= " << DiGui(num) << endl;
		cout << "next number" << endl;	
	}
	if(!cin)
	{
		cin.clear();
		while(cin.get() != '\n')
			continue;
		cout << "输入数据错误,导致进程错误" << endl;
	}
	return 0;
}

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

#include <iostream>

const int ArrSize = 10;

int Fill_array(double arr[], const int arrSize);
void Show_array(const double arr[], const int arrSize);
void Reverse_array(double arr[], const int arrSize);

int main()
{
	double arr[ArrSize];
	int num;
	num = Fill_array(arr, ArrSize);
	Show_array(arr, num);
	Reverse_array(arr, num);
	Show_array(arr, num);
	int temp = arr[0];
	arr[0] = arr[num-1];
	arr[num - 1] = temp;
	Show_array(arr, num);
	return 0;
}

int Fill_array(double arr[], const int arrSize)
{
	using std::cout;
	using std::cin;
	using std::endl;
	
	cout <<"请输入数据"<<endl;
	
	int i ;
	for (i = 0; i < arrSize; i++)
	{
		cout << "#" << i + 1 << ":_\b";
		cin >> arr[i];
		if(!cin)
		{
			cout << "输入提前终止"<<endl;
			cin.clear();
			while(cin.get() != '\n')
				continue;
			break;
		}
	}	
	return i;
}

void Show_array(const double arr[], const int arrSize)
{
	using std::cout;
	using std::endl;
	
	for (int i = 0; i < arrSize; i++)
	{
		cout << arr[i] << ' ';
	}
	cout << endl;
}
void Reverse_array(double arr[], const int arrSize)
{
	double temp;
	
	for(int i = 0; i < arrSize/2; i++)
	{
		temp = arr[arrSize - i - 1];
		arr[arrSize - i - 1] = arr[i];
		arr[i] = temp;
	}
}

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

#include <iostream>

const int Max = 5;

double * fill_array(double * begin, double * end);
void show_array(const double * begin, const double * end);
void revalue(double r, double * begin, double * end);

int main()
{
	using namespace std;
	double properties[Max];
	
	double * end = fill_array(properties,properties + Max);
	show_array(properties,end);
	if(end != 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,end);
		show_array(properties,end);
	}
	cout << "Done.\n";
	cin.get();
	cin.get();
	return 0;
}

double * fill_array(double * begin, double * end)
{
	using namespace std;
	double temp;
	double * pt;
	int i = 0;
	for(pt = begin; pt != end; pt++)
	{
		cout << "Enter value #" << i++ <<": ";
		cin >> temp;
		if(!cin)
		{
			cin.clear();
			while(cin.get() != '\n')
				continue;
			cout << "Bad input; input process terminated.\n";
			break;
		}
		else if(temp < 0)
			break;
		*pt = temp;
	}
	return pt;
}

void show_array(const double * begin, const double * end)
{
	using namespace std;
	int i = 0;
	for (const double * pt = begin; pt != end; pt++)
	{
		cout << "Property #" <<i++ << ": $";
		cout << *pt << endl;
	}
}

void revalue(double r, double * begin, double * end)
{
	for (double * pt = begin; pt != end; pt++)
	{
		*pt *= r;
	}
}

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

#include <iostream>
#include <string>

const int Seasons = 4;

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

void fill(double pa[], const int size);
void show(const double da[], const int size);

int main()
{
	double expenses[Seasons];
	fill(expenses,Seasons);
	show(expenses,Seasons);
	return 0;
}

void fill(double pa[], const int size)
{
	using namespace std;
	for (int i = 0; i < size; i++)
	{
		cout <<"Enter " << str[i] <<" expenses: ";
		cin >> pa[i];
	}
}

void show(const double da[], const int size)
{
	using namespace std;
	double total = 0.0;
	cout << "\nEXPENSES\n";
	for (int i = 0; i < size; i++)
	{
		cout << str[i] << ": $" << da[i] << endl;
		total += da[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

b、

#include <iostream>
#include <string>

const int Seasons = 4;

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

struct KaiZhi{
	double expenses[Seasons];
}; 

void fill(KaiZhi * Pa);
void show(const KaiZhi da);

int main()
{
	KaiZhi expenses;
	fill(&expenses);
	show(expenses);
	return 0;
}

void fill(KaiZhi * Pa)
{
	using namespace std;
	for (int i = 0; i < Seasons; i++)
	{
		cout <<"Enter " << str[i] <<" expenses: ";
		cin >> Pa -> expenses[i];
	}
}

void show(const KaiZhi da)
{
	using namespace std;
	double total = 0.0;
	cout << "\nEXPENSES\n";
	for (int i = 0; i < Seasons; i++)
	{
		cout << str[i] << ": $" << da.expenses[i] << endl;
		total += da.expenses[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

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

#include <iostream>
using namespace std;
const int SLEN = 30;
struct student {
	char fullname[SLEN];
	char hobby[SLEN];
	int ooplevel;
};
// getinfo() has two arguments: a pointer to the first element of
// an array of student structures and an int representing the 
// number of elemments of the array. The functionn solicits and
// stores data about students. It terminates input upon filling
// the array of upon encountering a blank line for the student
// name. The function returns the actual number of array elements
// 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 os student structure as an
// argument and displays the structure's contents
void display2(const student * ps);

//display3() takes the address of the first element of an array
// of student structures and the number of array elements as
// arguments and sisplays 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)
{
   int enter = 0;
    for (int i = 0; i < n; i++)
    {
        cout << "Enter the infomation of student #" << i+1 << endl;
        cout << "Enter full name (blank line to quit): ";
        cin.getline(pa[i].fullname, SLEN);
        cout << "Enter hobby: ";
        cin.getline(pa[i].hobby, SLEN);
        cout << "Enter ooplevel: ";
        cin >> pa[i].ooplevel;
        while (cin.get() != '\n')
            continue;
        enter++;
    }
    return enter;
}
void display1(student st)
{
    cout << "Using display1(student st): " << endl;
    cout << "Full name: " << st.fullname << endl;
    cout << "Hobby: " << st.hobby << endl;
    cout << "Ooplevel: " << st.ooplevel << endl;	
}

void display2(const student * ps)
{
    cout << "Using display2(const student *st)" << endl;
    cout << "Full name: " << ps->fullname << endl;
    cout << "Hobby: " << ps->hobby << endl;
    cout << "Ooplevel: " << ps->ooplevel << endl;	
}

void display3(const student pa[], int n)
{
    cout << "Using display3(const student pa[], int n)" << endl;;
    for (int i = 0; i < n; i++)
    {
        cout << "Infomation of student #" << i + 1 << ": " << endl;
        cout << "Full 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()和至少一个其他的函数。如果读者爱冒险,可以尝试创建一个指针数组,其中的指针指向ad)样式的函数,并编写一个循环,使用这些指针连续让 calculate()调用这些函数。提示:下面是声明这种指针数组的方式,其中包含三个指针:

double (*pf[3])(double, double);

可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。

#include <iostream>
using namespace std;

double add(double x, double y)
{
    return x + y;
}
double mul(double x, double y)
{
    return x * y;
}
double calculate(double x, double y, double(*fun)(double, double))
{
    return fun(x, y);
}
int main()
{
    double x = 0.0;
    double y = 0.0;

    cout << "Enter two double number: ";
    while (cin >> x >> y)
    {
        cout << "Call add, the result of " << x << " and " << y << " is " << calculate(x, y, add) << endl;
        cout << "Call mul, the result of " << x << " abd " << y << " is " << calculate(x, y, mul) << endl;

        cout << "Enter next two double number: ";
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值