C++ Primer Plus章节编程练习第七章

1

题目

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

题解

#include<iostream>
using namespace std;
double HarmonicAverage(double x,double y);
int main(){
    double a,b;
    cout<<"Enter two numbers: "<<endl;
    while(cin>>a>>b&&(a&&b)){
        if(a+b==0) cout<<"Error!"<<endl;
        else    cout<<"The harmonicAverage of your two numbers is "<<HarmonicAverage(a,b)<<endl;
        cout<<"Enter next two numbers: "<<endl;
    }
    cout<<"End"<<endl;
    return 0;
}
double HarmonicAverage(double x,double y){
    return 2.0*x*y/(x+y);
}

2

题目

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

题解

#include<iostream>
using namespace std;
int GetScore(double a[],int n);
void ShowScore(double a[],int n);
double Average(double a[],int n);
int main(){
    double *scores=new double[10];
    int cnt=GetScore(scores,10);
    ShowScore(scores,cnt);
    cout<<"The average of your scores is: "<<Average(scores,cnt)<<".\n";
    return 0;
}
int GetScore(double a[],int n){
    cout<<"Please enter your scores no more than 10 times (end with q): "<<endl;
    int cnt=0;
    while(cnt<n&&cin>>a[cnt]){
        cnt++;
    }
    return cnt;
}
void ShowScore(double a[],int n){
    cout<<"Your scores list following: "<<endl;
    if(n==0) cout<<"NULL";
    for(int i=0;i<n;i++){
        if(i) putchar(' ');
        cout<<a[i];
    }
    cout<<endl;
}
double Average(double a[],int n){
    double sum=0.0;
    for(int i=0;i<n;i++)
        sum+=a[i];
    return n==0?0:sum/n;
}

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 ShowBox(box onebox);
void CaculatorVolume(box * boxp);
int main(){
    box mybox={
        "China",
        10.0,
        10.0,
        10.0,
    };
    CaculatorVolume(&mybox);
    ShowBox(mybox);
    return 0;
}
void ShowBox(box onebox){
    cout<<"This is the information of your box:"<<endl;
    cout<<"Maker: "<<onebox.maker<<endl
        <<"Height: "<<onebox.height<<endl
        <<"Width: "<<onebox.width<<endl
        <<"Length: "<<onebox.length<<endl
        <<"Volume: "<<onebox.volume<<endl;
}
void CaculatorVolume(box * boxp){
    boxp->volume=boxp->height*boxp->width*boxp->length;
}

4

题目

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

题解

#include<iostream>
long double probability(unsigned numbers, unsigned picks);
int main(){
    using namespace std;
    double total,choices;
    cout<<"Enter the total number of field number and\n"
          "the number of pickes allowed:\n";
    cin>>total>>choices;
    long double pro=probability(total,choices);
    cout<<"Enter the total number of special number and\n"
          "the number of pickes allowed:\n";
    cin>>total>>choices;
    pro*=probability(total,choices);
    cout<<"You have one chance in "<<pro<<" of winning.\n";
    return 0;
}
//用于计算可能性
long double probability(unsigned numbers, unsigned picks){
    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;
}

5

题目

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

题解

#include<iostream>
using namespace std;
long long Factorial(long long n);
int main(){
    cout<<"Enter a non-negative integer no more than 20 (quit with q): ";
    int n;
    while(cin>>n){
        cout<<n<<"! = "<<Factorial(n)<<endl;
        cout<<"Enter next non-negative integer no more than 20 (quit with q): ";
    }
    cout<<"Bye!\n";
    return 0;
}
long long Factorial(long long n){
    if(n<2) return 1;
    else return n*Factorial(n-1);
}

6

题目

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

题解

#include<iostream>
using namespace std;
int Fill_array(double a[],int n);
void Show_array(double a[],int n);
void Reverse_array(double a[],int n);
int main(){
    double *darray=new double[10];
    int cnt=Fill_array(darray,10);
    Show_array(darray,cnt);
    Reverse_array(darray,cnt);
    Show_array(darray,cnt);
    return 0;
}
int Fill_array(double a[],int n){
    cout<<"Please enter no more than "<<n<<"numbers (end with q): "<<endl;
    int cnt=0;
    while(cnt<n&&cin>>a[cnt]){
        cnt++;
    }
    return cnt;
}
void Show_array(double a[],int n){
    cout<<"Your array following: "<<endl;
    if(n==0) cout<<"NULL";
    for(int i=0;i<n;i++){
        if(i) putchar(' ');
        cout<<a[i];
    }
    cout<<endl;
}
void Reverse_array(double a[],int n){
    int low=1,high=n-2;
    while(low<high){
        double temp=a[low];
        a[low]=a[high];
        a[high]=temp;
        low++,high--;
    }
}

7

题目

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

题解

#include<iostream>
const int Max=5;
double* fill_array(double *begin, double *end);
void show_array(double *begin, 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);        //将所有的数字扩大factor倍
        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* p;
    int i;
    for(i=0,p=begin;p<end;p++,i++){                       //最多输入到end前的位置
        cout<<"Enter value #"<<i+1<<": ";
        cin>>temp;
        if(!cin){                               //如果输入一个非数字
            cin.clear();                        //清空cin的标记位
            while(cin.get()!='\n')              //清空后续的所有字符
                continue;
            cout<<"Bad input; Please enter a number: ";
            break;                              //跳出循环
        }
        else if(temp<0)                         //如果遇到负数也跳出循环
            break;
        *p=temp;                                //填充输入的数字
    }
    return p;
}
void show_array(double *begin, double *end){       //输出数组内容
    using namespace std;
    for(int i=0;i<end-begin;i++){
        cout<<"Property #"<<i+1<<": $";
        cout<<*(begin+i)<<endl;
    }
}
void revalue(double r,double *begin, double *end){     //将数组中所有的数字都乘以r
    for(int i=0;i<end-begin;i++)
        begin[i]*=r;
}

8

题目

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

题解

a组

#include<iostream>
const int Seasons=4;
const char*Snames[Seasons]=
    {"Spring","Summer","Fall","Winter"};
void fill(double a[]);
void show(double a[]);
int main(){
    double expenses[Seasons];
    fill(expenses);
    show(expenses);
    return 0;
}
void fill(double a[]){
    using namespace std;
    for(int i=0;i<Seasons;i++){
        cout<<"Enter "<<Snames[i]<<" expenses: ";
        cin>>a[i];
    }
}
void show(double a[]){
    using namespace std;
    double total=0.0;
    cout<<"\nEXPENSES\n";
    for(int i=0;i<Seasons;i++){
        cout<<Snames[i]<<": $"<<a[i]<<endl;
        total+=a[i];
    }
    cout<<"Total Expenses: $"<<total<<endl;
}

b组

#include<iostream>
const int Seasons=4;
const char*Snames[Seasons]=
    {"Spring","Summer","Fall","Winter"};
struct expenses{
    double da[Seasons];
};
void fill(expenses &exp);       //传引用才能对main的数组进行填充
void show(expenses &exp);
int main(){
    expenses allexpenses;
    fill(allexpenses);
    show(allexpenses);
    return 0;
}
void fill(expenses &exp){
    using namespace std;
    for(int i=0;i<Seasons;i++){
        cout<<"Enter "<<Snames[i]<<" expenses: ";
        cin>>exp.da[i];
    }
}
void show(expenses &exp){
    using namespace std;
    double total=0.0;
    cout<<"\nEXPENSES\n";
    for(int i=0;i<Seasons;i++){
        cout<<Snames[i]<<": $"<<exp.da[i]<<endl;
        total+=exp.da[i];
    }
    cout<<"Total Expenses: $"<<total<<endl;
}

9

题目

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

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

题解

#include<iostream>
using namespace std;
const int SLEN=30;
struct student{
    char fullname[SLEN];
    char hobby[SLEN];
    int opplevel;
};
int getinfo(student pa[], int n);
void display1(student st);
void display2(const student* ps);
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 cnt=0;
    for(cnt=0;cnt<n;cnt++){
        cout<<"Enter the name of the student #"<<cnt+1<<": ";
        cin.getline(pa[cnt].fullname,SLEN);
        if(pa[cnt].fullname[0]=='\0') break;
        cout<<"Enter the hobby of the student #"<<cnt+1<<": ";
        cin.getline(pa[cnt].hobby,SLEN);
        cout<<"Enter the opplevel of the student #"<<cnt+1<<": ";
        cin>>pa[cnt].opplevel;
        while(cin.get()!='\n') continue;    //吸收多余字符,为下一次输入做准备              
    }
    return cnt;
}
void display1(student st){
    cout<<"Name: "<<st.fullname<<endl
        <<"hobby: "<<st.hobby<<endl
        <<"opplevel: "<<st.opplevel<<endl;
}
void display2(const student* ps){
    cout<<"Name: "<<ps->fullname<<endl
        <<"hobby: "<<ps->hobby<<endl
        <<"opplevel: "<<ps->opplevel<<endl;
}
void display3(const student pa[],int n){
    for(int i=0;i<n;i++){
        cout<<"Student #"<<i+1<<":\n";
        display1(pa[i]);
    }
}

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;
double add(double x,double y);
double sub(double x,double y);
double calculate(double x,double y,double (*pf)(double,double));
int main(){
    double a,b;
    cout<<"Enter two numbers for calculate: ";
    while(cin>>a>>b){
        cout<<a<<" + "<<b<<" = "<<calculate(a,b,add)<<endl;
        cout<<a<<" - "<<b<<" = "<<calculate(a,b,sub)<<endl;
        cout<<"Enter next two numbers for calculate: ";
    }
    cout<<"Bye!\n";
    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 (*pf)(double,double)){
    return (*pf)(x,y);
}

当珍惜每一片时光~