C++ Primer Plus (第6版) 中文版 第七章 函数---C++的编程模块 编程练习答案

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

//编写一个程序,输入两个数,并求出这两个数的调和平均数,直到有一个数是0则退出。

#include<iostream>

double get_harmonic_mean(double,double);
using namespace std;

int main()
{
 double x;
 double y;
 
 cout<<"请输入两个由空格隔开的数字:\n";
 while(cin>>x>>y)
 {
  if (x==0 || y==0)
   break;
  else
  cout<<"这两个数的调和平均数是:"<<get_harmonic_mean(x,y)<<endl;
 }
 
 cin.get();
 cin.get();
 return 0;
}

double get_harmonic_mean(double x,double y)
{
 return 2.0*x*y/(x+y);
}

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

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

#include<iostream>

int input(double grades[],int times);
double calculate_average(const double grades[],int times);
void show(const double grades[],int times,double average);
using namespace std;
const int maxsize=10;

int main()
{
 double *grades = new double[maxsize];
 double average;
 int real_times;
 real_times = input(grades,maxsize);
 average = calculate_average(grades,real_times);
 show(grades,real_times,average);
 cin.get();
 return 0;
}

int input(double grades[],int times)
{
 int i;
 double grade;
 cout<<"请输入最多十个高尔夫成绩:\n";
 for (i=0;i<times;i++)
 {
  cout<<"第"<<i+1<<"次成绩:";
  cin>>grade;
  if (!cin)
  {
   cin.clear();
   while (cin.get()  !=  '\n')
    continue;
   cout<<"退出(Q)\n";
   break;
  }
  grades[i]=grade;  
 }
 return i;
}

double calculate_average(const double grades[],int times)
{
 double average;
 double sum=0;
 for (int i=0;i<times;i++)
  sum = sum + grades[i];
 average = sum/times;
 return average;
}

void show(const double grades[],int times,double average)
{
 cout<<"显示高尔夫成绩:\n";
 for (int i=0;i<times;i++)
  cout<<grades[i]<<"\t";
 cout<<endl<<times<<"次的平均成绩是:"<<average<<endl;
}

3.下面是一个结构声明
struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
};
a. 编写一个函数,按值传递box结构,并显示每一个成员的值。
b. 编写一个函数,传递box结构的地址,并将volume成员设置为其他三维长度的乘积。
c. 编写一个使用这两个函数的简单程序。

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

#include<iostream>

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

void show(box);
void cal(box *);
using namespace std;

int main()
{
 box temp;
 cal(&temp);
 show(temp);
 cin.get();
 cin.get();
 return 0;
}

void show(box value)
{
 cout<<"高度:"<<value.height<<endl;
 cout<<"长度:"<<value.length<<endl;
 cout<<"宽度:"<<value.width<<endl;
 cout<<"体积:"<<value.volume<<endl;
}

void cal(box *value)
{
 cout<<"请输入高度:";
 cin>>value->height;
 cout<<"请输入宽度:";
 cin>>value->width;
 cout<<"请输入长度:";
 cin>>value->length;
 value->volume = value->height*value->width*value->length;
}

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

//修改程序清单7.4,计算中得头奖的几率。
#include <iostream>
long double probability(unsigned numbers, unsigned picks,unsigned extra);

int main()
{
    using namespace std;
    double total, choices,extra;
    cout << "Enter the total number of choices on the game card and\n"
            "the number of picks allowed and the extra number:\n";
    while ((cin >> total >> choices>>extra) && choices <= total && 1<=extra<=27)
    {
        cout << "You have one chance in ";
        cout << probability(total, choices,extra);      // compute the odds
        cout << " of winning.\n";
        cout << "Next two numbers (q to quit): ";
    }
    cout << "bye\n";    
    return 0;
}

long double probability(unsigned numbers, unsigned picks,unsigned extra)
{
    long double result = 1.0;  // here come some local variables
    long double n;
    unsigned p;
    for (n = numbers, p = picks; p > 0; n--, p--)
        result = result * n / p ; 
    result = result*extra;
    return 1/result;
}

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

//定义一个递归函数,接受一个整数参数,并返回该参数的阶乘。
//阶乘:如果n>0,则n!=n*(n-1)!。
//程序使用循环让用户输入不同的值,程序则报告这些值的阶乘。
#include<iostream>
int cal(int);
using namespace std;
int main()
{
 int a;
 cout<<"请输入数字:";
 while (cin>>a)
  cout<<a<<"的阶乘是:"<<cal(a)<<endl;
 return 0;
}
int cal(int x)
{
 if (x==0)
  return 1;
 else
  return x*cal(x-1);
}

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

//使用Fill_array()将一个double数组的名称和长度作为参数。它显示用户输入double值,并将这些值存储到数组中。当数组被填满或用户输入了非数字时,输入将停止,并返回实际输入了多少个数字。
//使用Show_array()将一个double数组的名称和长度作为参数,并显示该数组的内容。
//使用Reverse_array()将一个double数组的名称和长度作为参数,并将存储在数组中的值的顺序反转。

#include<iostream>

int Fill_array(double ar[],int size);
void Show_array(const double ar[],int size);
void Reverse_array(double ar[],int size);
using namespace std;

int main()
{
 const int maxsize = 20;
 double ar[maxsize]; 
 int size = Fill_array(ar,maxsize);
 Show_array(ar,size);
 Reverse_array(ar,size);
 cout<<"\n顺序反转后,ar如下:\n";
 Show_array(ar,size);
 Reverse_array(ar+1,size-2);
 cout<<"\n再次反转除第一个和最后一个元素之外的所有元素后,ar如下:\n";
 Show_array(ar,size);
 cin.get();
 return 0;
}

int Fill_array(double ar[],int size)
{
 double temp;
 int i;
 for (i=0;i<size;i++)
 {
  cout<<"用户输入double(这个值要存储在一个double数组中的):";
  cin>>temp;
  if (!cin)
  {
   cin.clear();
   while (cin.get() !='\n')
    continue;
   cout<<"Bad input;input process terminated.\n";
   break;
  }
  else if (i == size)
   break;
  ar[i]=temp;
 }
 return i;
}

void Show_array(const double ar[],int size)
{
 for (int i=0;i<size;i++)
  cout<<"在数组中,第"<<i+1<<"个数字为:\t"<<ar[i]<<endl;
}

void Reverse_array(double ar[],int size)
{
 double reverse;
 int i ,j;
 for(i=0,j=size-1;i<j;i++,j--)
 {
  reverse=ar[i];
  ar[i]=ar[j];
  ar[j]=reverse;
 }
}

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

//修改程序清7.7中的三个数组处理函数,使之使用两个指针参数来表示区间。
//fill_array()函数不返回实际读取了多少个数字,而是返回一个指针,该指针指向最后被填充的位置。
//其它函数可以将该指针作为第二个参数,以标识数据结尾。
#include <iostream>
const int Max = 5;
double *fill_array(double ar[], int limit);
void show_array(const double ar[], double* n); 
void revalue(double r, double ar[], double* n);

int main()
{
    using namespace std;
    double properties[Max];
    double *size = fill_array(properties, Max);
    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;
}

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[], double* n)
{
    using namespace std;
    for (int i = 0; i < n-ar; i++)
    {
        cout << "Property #" << (i + 1) << ": $";
        cout << ar[i] << endl;
    }
}

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

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

//在不使用array类的情况下完成程序清单7.15所做的工作。编写两个这样的版本:
//a.使用const char*数组存储表示季度名称的字符串,并使用double数组存储开支。

#include <iostream>
using namespace std;
const int Seasons = 4;
const char *Snames[Seasons] ={"Spring", "Summer", "Fall", "Winter"};
void fill(double pa[]);
void show(double da[]);

int main()
{
   double expenses[4];
    fill(expenses);
    show(expenses);
    cin.get();
    cin.get();
    return 0;
}

void fill(double pa[])
{
    for (int i = 0; i < Seasons; i++)
    {
        cout << "Enter " << Snames[i] << " expenses: ";
        cin >> pa[i];
    }
}

void show(double da[])
{
    double total = 0.0;
    cout << "\nEXPENSES\n";
    for (int i = 0; i < Seasons; i++)
    {
        cout << Snames[i] << ": $" << da[i] << '\n';
        total += da[i];
    }
    cout << "Total: $" << total << '\n';
}
//b.使用const char*数组存储表示季度名称的字符串,并使用一个结构,该结构只有一个成员---一个用于存储开支的double数组。这种设计与使用array类的基本设计类似。

#include <iostream>
using namespace std;
const int Seasons = 4;
const char* Snames[Seasons] ={"Spring", "Summer", "Fall", "Winter"};

struct output_expenses
{
 double expenses[Seasons];
};

void fill(output_expenses*);
void show(output_expenses*);

int main()
{
 output_expenses object_expenses;
    fill(&object_expenses);
    show(&object_expenses);
    cin.get();
    cin.get();
    return 0;
}

void fill(output_expenses* object_expenses_point)
{
    for (int i = 0; i < Seasons; i++)
    {
        cout << "Enter " << Snames[i] << " expenses: ";
  cin >> object_expenses_point->expenses[i];
    }
}

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

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 elements 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 elements
//filled.
int getinfo(student pa[],int n);
//display1() takes a student structures as an argument
//and displays its contents
void display1(student st);
//display2() takes the address of 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 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";
 cin.get();
 return 0;
}
int getinfo(student pa[],int n)
{
 int i;
 for (i=0;i<n;i++)
 {
  cout<<"Please enter the fullname:";
  cin.getline(pa[i].fullname,SLEN);
  cout<<"Please enter the hobby:";
  cin>>pa[i].hobby;
  cout<<"Please enter the ooplevel:";
  cin>>pa[i].ooplevel;
  cin.get();
 }
 cout<<"Enter end!"<<endl;
 return i;
}
void display1(student st)
{
 cout<<"\ndisplay1:\nFullname:"<<st.fullname<<endl;
 cout<<"hobby:"<<st.hobby<<endl;
 cout<<"ooplevel:"<<st.ooplevel<<endl;
}
void display2(const student *ps)
{
 cout<<"\ndisplay2:\nFullname:"<<ps->fullname<<endl;
 cout<<"hobby:"<<ps->hobby<<endl;
 cout<<"ooplevel:"<<ps->ooplevel<<endl;
}
void display3(const student pa[],int n)
{
 cout<<"\ndisplay3:"<<endl;
 for(int i=0;i<n;i++)
 {
  cout<<i<<"::\nFullname:"<<pa[i].fullname<<endl;
  cout<<"hobby:"<<pa[i].hobby<<endl;
  cout<<"ooplevel:"<<pa[i].ooplevel<<endl<<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); 其中包含三个指针可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。

//设计一个名为calculate()的函数,它接受两个double值和一个指向函数的指针,而被指向的函数接受两个double参数,并返回一个double值。
//calculate()函数的类型也是double,并返回被指向的函数使用calculate()的两个double参数计算得到的值。

#include<iostream>
double add(double x,double y);
double sub(double x,double y);
double calculate(double x,double y,double (*func)(double x,double y));
using namespace std;

int main()
{
 while(1)
 {
  cout<<"Please enter two number,'q' to quit:";
  double x,y;
  double result;
  cin>>x>>y;
  if(!cin)
  {
   cout<<"Input terminated.\nQuit.\n";
   break;
  }
  double q=calculate(x,y,add);
  double w=calculate(x,y,sub);
  cout<<x<<"and"<<y<<"equals to "<<q<<endl;
  cout<<x<<"minus"<<y<<"equals to "<<w<<endl;
 }
 system("pause");
 return 0;
}

double add(double x,double y)
{
 return x+y;
}

double sub(double x,double y)
{
 return x-y;
}

double calculate(double x,double y,double (*func)(double x,double y))
{
 double result;
 result =(*func)(x,y);
 return result;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值