第7章 函数——C++的编程模块
1.编写一个程序,不断要求用户输入两个数,直到其中的一个为0。对于每两个数,程序将使用一个函数来计算它们的调和平均数,并将结果返回给main(),而后者将报告结果。调和平均数指的是倒数平均值的倒数,计算公式如下:调和平均数 = 2.0 * x * y / (x + y)
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
const int MAX = 50;
double average(double x, double y);
int main()
{
int i = 0;
double (*p)[2] = new double[MAX][2];
cout << "1#:请输入第1个数:" << endl;
cin >> p[i][0];
cout << "1#: 请输入第2个数:" << endl;
cin >> p[i][1];
while ((p[i][0] != 0) && (p[i][1] != 0)) {
i++;
for (int j = 0; j <= 1; j++) {
cout << i + 1 << "#: 请输入第" << j + 1 << "个数:" << endl;
cin >> p[i][j];
}
}
i = 0;
double tmp = 0.0;//O.o?
while ((p[i][0] != 0) && (p[i][1] != 0)) {
tmp = average(p[i][0], p[i][1]);
cout << i + 1 << "#:" << tmp << endl;
i++;
}
delete[] p;
}
double average(double x, double y)
{
return 2.0 * x * y / (x + y);
}
2.编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存储在一个数组中。程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。请使用3个数组处理函数来分别进行输入、显示和计算平均成绩。
#include <iostream>
using namespace std;
const int MAX = 10;
int inputScore(double*);
void showScore(double*, int);
void average(double*, int);
int main()
{
double* p = new double[MAX];
int count = inputScore(p);
showScore(p, count);
average(p, count);
delete[] p;
}
int inputScore(double* arr) {
cout << "请输入最多" << MAX << "个高尔夫成绩" << endl;
int count = 0;
for (int i = 0; i < MAX; i++) {
cout << "请输入第" << i + 1 << "个高尔夫成绩:";
if (!(cin >> arr[i])) {
break;
}
count++;
}
return count;
}
void showScore(double* arr, int count) {
for (int i = 0; i < count; i++) {
cout << i + 1 << "#:" << arr[i] << endl;
}
}
void average(double* arr, int count) {
double sum = 0;
for (int i = 0; i < count; i++) {
sum += arr[i];
}
cout << "平均成绩为:" << (sum / count);
}
3.下面是一个结构声明:struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
};
a)编写一个函数,按值传递box结构,并显示每个成员的值。
b)编写一个函数,传递box结构的地址,并将volume成员设置为其他三维长度的乘积。
c)编写一个使用这两个函数的简单程序
#include <iostream>
using namespace std;
struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
};
void show(box);
void set_volume(box*);
int main()
{
box Box{};
cout << "请输入容器:";
cin.getline(Box.maker, 39);
cout << "长:";
cin >> Box.length;
cout << "宽:";
cin >> Box.width;
cout << "高:";
cin >> Box.height;
show(Box);
cout << endl;
box* pBox = &Box;
set_volume(pBox);
show(Box);
}
void show(box b) {
cout << "maker = " << b.maker << endl;
cout << "height = " << b.height << endl;
cout << "length = " << b.length << endl;
cout << "width = " << b.width << endl;
cout << "volume = " << b.volume << endl;
}
void set_volume(box* b) {
(*b).volume = b->height * b->length * b->width;
}
4.许多州的彩票发行机构都使用如程序清单7.4所示的简单彩票玩法的变体。在这些玩法中,玩家从一组被称为域号码(field number)的号码中选择几个。例如,可以从域号码1-47中选择5个号码:还可以从第二个区间(如1-27)选择一个号码(称为特选号码)。要赢头奖,必须正确猜中所有号码。中头奖的几率是选中所有域号码的几率与选中特选号码几率的乘积。例如,在这个例子中,中头奖的几率是从47个号码中正确的选取5个号码的几率与从27个号码中正确选择1个号码的几率的乘积。请修改程序清单7.4,以计算中得这种彩票头奖的几率
#include<iostream>
using namespace std;
long double probability(int individual, int population);
int main()
{
long double result1 = probability(5, 47);
long double result2 = probability(1, 27);
long double result = result1 * result2;
cout << "彩票头奖的几率为:" << result;
}
long double probability(int individual, int population)
{
long double result = 1;
long double n, p;
for (n = individual, p = population; 0 < n; n--, p--)
{
result = result * n / p;
}
return result;
}
5.定义一个递归函数,接受一个整型参数,并返回该参数的阶乘。前面讲过,3的阶乘写作3!,等于3 * 2!,以此类推: 而0!被定义为1.通用的计算公式是,如果n大于零 , 则n! = n * (n - 1)!。在程序中对该函数进行测试,程序使用循环让用户输入不同的值,程序将报告这些值的阶乘。
#include <iostream>
using namespace std;
int factorial(int);
int main()
{
int n;
cout << "计算参数的阶乘,请输入参数:";
cin >> n;
cout << n << "的阶乘为:" << factorial(n);
}
int factorial(int n) {
if (n != 1) {
return n * factorial(n - 1);
}
else if (n == 1) {
return 1;
}
}
6.编写一个程序,它使用下列函数:
Fill_array()将一个double数组的名称和长度作为参数。它提示用户输入double值,并将这些值存储到数组中。当数组被填满或用户输入了非数字时,输入将停止,并返回实际输入了多少个数字。
Show_array()将一个double数组的名称和长度作为参数,并显示该数组的内容。
Reverse_array()将一个double数组的名称和长度作为参数,并将存储在数组中的值的顺序反转。
程序将使用这些函数来填充数组,然后显示数组;反转数组,然后显示数组;反转数组中除第一个和最后一个元素之外的所有元素, 然后显示数组。
#include <iostream>
using namespace std;
const int MAX = 10;
int Fill_array(double*, int);
void Show_array(double*, int);
void Reverse_array(double*, int);
int main()
{
double* parr = new double[MAX];
int count = Fill_array(parr, MAX);
Show_array(parr, count);
Reverse_array(parr, count);
Show_array(parr, count);
}
int Fill_array(double* arr, int n) {
cout << "请输入填入数组的double值:" << endl;
int count = 0;//用于记录用户输入了多少个数
for (int i = 0; i < n; i++) {
cout << i + 1 << "#:";
if (!(cin >> arr[i])) {
break;
}
else {
count++;
}
}
return count;
}
void Show_array(double* arr, int n) {
cout << "数组内容:" << endl;
for (int i = 0; i < n; i++) {
cout << i + 1 << "#:" << arr[i];
cout << endl;
}
}
void Reverse_array(double* arr, int n) {
double tmp = 0.0;//用于储存中间值
for (int i = 0; i < (n / 2); i++) {
tmp = arr[i];
arr[i] = arr[n - 1 - i];
arr[n - 1 - i] = tmp;
}
}
7.修改程序清单7.7中的3个数组处理函数,使之使用两个指针参数来表示区间。file_array()函数不返回实际读取了多少个数字,而是返回一个指针,该指针指向最后被填充的位置。其他的函数可以将该指针作为第二个参数,以标识数据结尾。
#include <iostream>
const int MAX = 10;
using namespace std;
double* Fill_array(double* arr, int max);
void Show_array(double* arrb, double* arre);
void Reverse_array(double* arrb, double* arre);
int main()
{
double* parr = new double[MAX];
double* parre = Fill_array(parr, MAX);
Show_array(parr, parre);
Reverse_array(parr, parre);
Show_array(parr, parre);
}
double* Fill_array(double* arr, int max) {
cout << "请输入填入数组的double值:" << endl;
int count = 0;//用于记录用户输入了多少个数
for (int i = 0; i < max; i++) {
cout << i + 1 << "#:";
if (!(cin >> arr[i])) {
break;
}
else {
count++;
}
}
return (arr + count);
}
void Show_array(double* arrb, double* arre) {
cout << "数组内容:" << endl;
for (int i = 0; (arrb + i) != arre; i++) {
cout << i + 1 << "#:" << arrb[i];
cout << endl;
}
}
void Reverse_array(double* arrb, double* arre) {
double tmp = 0.0;//用于储存中间值
for (int i = 0; arrb + i != arre - 1 - i; i++) {
tmp = arrb[i];
arrb[i] = arre[- 1 - i];
arre[- 1 - i] = tmp;
}
}
8.在不使用array类的情况下完成程序清单7.15所做的工作。编写两个这样的版本:
//程序清单7.15
#include <iostream>
#include <array>
#include <string>
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> expenses;
fill(&expenses);
show(expenses);
return 0;
}
void fill(std::array <double, Seasons>* pa) {
using namespace std;
for (int i = 0; i < Seasons; i++) {
cout << "Enter" << Snames[i] << "expenses:";
cin >> (*pa)[i];
}
}
void show(std::array<double, Seasons>da) {
using namespace std;
double total = 0.0;
cout << "\nEXPENSES\n";
for (int i = 0; i < Seasons; i++) {
cout << Snames[i] << ":$" << da[i] << endl;
total += da[i];
}
cout << "Total Expenses : $" << total << endl;
}
a.使用const char *数组存储表示季度名称的字符串,并使用double数组存储开支。
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;;
const char* Snames[Seasons] = {"Spring","Summer", "Fall", "Winter"};
void fill(double * pa);
void show(double * da);
int main()
{
double expenses[Seasons];
fill(expenses);
show(expenses);
return 0;
}
void fill(double* pa) {
using namespace std;
for (int i = 0; i < Seasons; i++) {
cout << "Enter" << Snames[i] << "expenses:";
cin >> pa[i];
}
}
void show(double* da) {
using namespace std;
double total = 0.0;
cout << "\nEXPENSES\n";
for (int i = 0; i < Seasons; i++) {
cout << Snames[i] << ":$" << da[i] << endl;
total += da[i];
}
cout << "Total Expenses : $" << total << endl;
}
b.使用const char *数组存储表示季度名称的字符串,并使用一个结构,该结构只有一个成员——一个用于存储开支的double数组。
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;;
const char* Snames[Seasons] = {"Spring","Summer", "Fall", "Winter"};
void fill(expense& se);
void show(expense& sa);
struct expense
{
double expense[Seasons];
};
int main()
{
expense e;
fill(e);
show(e);
return 0;
}
void fill(expense& se) {
using namespace std;
for (int i = 0; i < Seasons; i++) {
cout << "Enter" << Snames[i] << "expenses:";
cin >> se.expense[i];
}
}
void show(expense& sa) {
using namespace std;
double total = 0.0;
cout << "\nEXPENSES\n";
for (int i = 0; i < Seasons; i++) {
cout << Snames[i] << ":$" << sa.expense[i] << endl;
total += sa.expense[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()有两个参数:一个指向学生结构数组的第一个元素的指针和一个表示数组元素数的int。
// 该函数收集并存储有关学生的数据。
// 它在填充数组或遇到学生姓名的空行时终止输入。
// 函数返回实际填充的数组元素数。
int getinfo(student pa[], int n);
//display1()将学生结构作为参数
void display1(student st);
//display2()将学生结构的地址作为参数,并显示结构的内容
void display2(const student* ps);
//display3()将学生结构数组的第一个元素的地址和数组元素的数量作为参数,并显示结构的内容
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;
}
void display3(const student pa[], int n) {
for (int i = 0; i < n; i++) {
cout << i + 1 << "#:" << endl;
cout << "姓名:" << pa[i].fullname << endl;
cout << "爱好:" << pa[i].hobby << endl;
cout << "OOP等级" << pa[i].ooplevel << endl;
}
}
void display2(const student* ps) {
cout << "姓名:" << ps->fullname << endl;
cout << "爱好:" << ps->hobby << endl;
cout << "OOP等级:" << ps->ooplevel << endl;
}
void display1(student st) {
cout << "姓名:" << st.fullname << endl;
cout << "爱好:" << st.hobby << endl;
cout << "OOP等级:" << st.ooplevel << endl;
}
int getinfo(student pa[], int n) {
for (int i = 0; i < n; i++) {
cout << i + 1 << "#:" << endl;
cout << "请输入学生全名:";
cin.getline(pa[i].fullname, SLEN);
cout << "请输入学生爱好:";
cin.getline(pa[i].hobby, SLEN);
cout << "请输入学生OOP等级:";
cin >> pa[i].ooplevel;
}
}
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);
可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。
#include<iostream>
using namespace std;
const int pairNumber = 3;
double add(double x, double y);
double subtract(double x, double y);
double calculate(double a, double b, double(*p)(double c, double d));
int main()
{
double(*p)[2] = new double[pairNumber][2];
for (int i = 0; i < pairNumber; i++)
{
cout << "请输入两个数字:";
cin >> p[i][0] >> p[i][1];
}
double (*p_add)(double x, double y) = add;
double (*p_subtract)(double x, double y) = subtract;
double (*p_sum[2]) (double, double) = { p_add ,p_subtract };
for (int i = 0; i < pairNumber; i++)
{
cout << "add:" << endl;
cout << add(p[i][0], p[i][1]) << endl;
cout << calculate(p[i][0], p[i][1], add) << endl;
cout << p_sum[0](p[i][0], p[i][1]) << endl;
cout << "subtract:" << endl;
cout << subtract(p[i][0], p[i][1]) << endl;
cout << calculate(p[i][0], p[i][1], subtract) << endl;
cout << p_sum[1](p[i][0], p[i][1]) << endl;
}
}
double add(double x, double y)
{
return x + y;
}
double subtract(double x, double y)
{
return x - y;
}
double calculate(double a, double b, double(*p)(double c, double d))
{
return p(a, b);
}