C++ primer plus第七章编程练习答案

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

#include <iostream>
using namespace std;

double harmonic_mean(double x, double y);

int main()
{
    double a, b;

    cout << "Please enter two numbers (0 to quit): ";
    while (cin >> a >> b && a && b)
    {
        cout << "The harmonic mean of " << a;
        cout << " and " << b << " is ";
        cout << harmonic_mean(a, b) << endl;
        cout << "Next two numbers (0 to quit): ";
    }
    cout << "Bye." << endl;

    return 0;
}

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

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

#include <iostream>
using namespace std;

int initialize_array(double arr[], int n);
void show_array(const double arr[], int n);
void count_average(const double arr[], int n);

const int ArSize = 10;

int main()
{
    double golf[ArSize];

    int n = initialize_array(golf, ArSize);
    show_array(golf, n);
    count_average(golf, n);
    cout << "Bye." << endl;

    return 0;
}

int initialize_array(double arr[], int n)
{
    int i = 0;

    cout << "You can enter up to " << ArSize;
    cout << " golf scores (q to terminate)." << endl;

    cout << "Golf scores #1: ";
    while (i < n && cin >> arr[i])
    {
        if (++i < ArSize)
        {
            cout << "Golf scores #" << i + 1 << ": ";
        }
    }
    return i;
}

void show_array(const double arr[], int n)
{
    cout << "All golf scores:" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << ' ';
    }
    cout.put('\n');
}

void count_average(const double arr[], int n)
{
    double aver = 0.0;

    for (int i = 0; i < n; i++)
    {
        aver += arr[i];
    }
    aver /= n;
    cout << "Average golf scores: " << aver << endl;
}

3,下面是一个结构声明:
struct box
char maker1401 :
float heighti
float width;
float length;
float volumei
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 value_show_box(box temp);
void address_show_box(box *temp);

int main()
{
    box smallbox = {"Cute box", 20, 10, 30, 50};

    value_show_box(smallbox);
    address_show_box(&smallbox);
    value_show_box(smallbox);

    return 0;
}

void value_show_box(box temp)
{
    cout << "Box informations: " << endl;
    cout << "Name: " << temp.maker << endl;
    cout << "height: " << temp.height << endl;
    cout << "width: " << temp.width << endl;
    cout << "length: " << temp.length << endl;
    cout << "volume: " << temp.volume << endl;
}

void address_show_box(box *temp)
{
    temp->volume = temp->height * temp->width * temp->length;
}

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

#include <iostream>
using namespace std;

long double probability(unsigned numbers, unsigned picks);

int main()
{
    unsigned total, choices, temp;
    cout << "Enter the total number of choices on the game card and\n";
    cout << "the number of picks allowed and the second section(<= total number):" << endl;
    while ((cin >> total >> choices >> temp) && choices <= total && temp <= total)
    {
        cout << "You have one chance in ";
        cout << probability(total, choices) * probability(temp, 1);
        cout << " of winning.\n";
        cout << "Next three numbers (q to quit): ";
    }
    cout << "bye\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 *= n / p;
    }
    return result;
}

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

#include <iostream>
using namespace std;

long double factorial(long double n);

int main()
{
    long double temp;

    cout << "Please enter a number(<0 or q to quit): ";
    while (cin >> temp && temp >= 0)
    {
        cout << temp << "! = " << factorial(temp) << endl;
        cout << "Next number(<0 or q to quit): ";
    }
    cout << "Bye." << endl;

    return 0;
}

long double factorial(long double n)
{
    return n ? n * factorial(n - 1) : 1;
}

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

#include <iostream>
using namespace std;

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

const int ArSize = 10;

int main()
{
    double arr[ArSize];

    int n = Fill_array(arr, ArSize);
    Show_array(arr, n);
    Reverse_array(arr, n);
    Show_array(arr, n);
    Reverse_array(arr, n);
    Reverse_array(arr + 1, n - 2);
    Show_array(arr, n);
    cout << "Bye." << endl;

    return 0;
}

int Fill_array(double arr[], int n)
{
    int i = 0;

    cout << "You can enter up to " << ArSize;
    cout << " numbers (q to terminate)." << endl;
    cout << "Number #1: ";
    while (i < n && cin >> arr[i])
    {
        if (++i < ArSize)
        {
            cout << "Number #" << i + 1 << ": ";
        }
    }
    return i;
}

void Show_array(const double arr[], int n)
{
    cout << "All numbers:" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << ' ';
    }
    cout.put('\n');
}

void Reverse_array(double arr[], int n)
{
    for (int i = 0; i < n / 2; i++)
    {
        double temp = arr[n - 1 - i];
        arr[n - 1 - i] = arr[i];
        arr[i] = temp;
    }
}

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

#include <iostream>
using namespace std;

const int Max = 5;

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

int main()
{
    double properties[Max];

    double *size = fill_array(properties, properties + Max);
    show_array(properties, size);
    if (size - 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, size);
        show_array(properties, size);
    }
    cout << "Done.\n";

    return 0;
}

double *fill_array(double *begin, double *end)
{
    int i;
    double temp;
    double *ptr;

    for (i = 0, ptr = begin; ptr < end; i++, ptr++)
    {
        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;
        }
        *ptr = temp;
    }
    return begin + i;
}

void show_array(const double *begin, double *end)
{
    int i;
    const double *ptr;

    for (i = 0, ptr = begin; ptr < end; i++, ptr++)
    {
        cout << "Property #" << (i + 1) << ": $";
        cout << *ptr << endl;
    }
}

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

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

#include <iostream>

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

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

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

    return 0;
}

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

void show(const double pa[], int n)
{
    double total = 0.0;

    std::cout << "EXPENSES\n";
    for (int i = 0; i < n; i++)
    {
        std::cout << Snames[i] << ": $" << pa[i] << '\n';
        total += pa[i];
    }
    std::cout << "Total: $" << total << '\n';
}

#include <iostream>

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

struct spending
{
    double expenses[Seasons];
};

void fill(spending *temp);
void show(spending *temp);

int main()
{
    spending temp;
    fill(&temp);
    show(&temp);

    return 0;
}

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

void show(spending *temp)
{
    double total = 0.0;

    std::cout << "EXPENSES\n";
    for (int i = 0; i < Seasons; i++)
    {
        std::cout << Snames[i] << ": $" << temp->expenses[i] << '\n';
        total += temp->expenses[i];
    }
    std::cout << "Total: $" << total << '\n';
}


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

include ciostream>
using namespace std;
const int SLEN = 30:
struct student
char fullnamelSLEN] 
char hobby[SLEN] ;
int ooplevel;
// getinfol) 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);
// displayi() takes a student structure as an argument// and displays its contentsvoid displayl(student st);
// display21) takes the address of student structure as an// argument and displays the structure's contentswoid 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 structuresvoid display3(const student pa[].int n];
int wain(l
cout es "Enter class size:“;
int class size?
cin >> class size;

while (cin.get() !=rn')
continuei
student * ptr_stu = new student [class size];int entered = getinfoiptr atu,class size]ifor (int i m 0;i c entered, i++]
display(ptrstu[il);display2(5ptrstu[il);
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 ooplevel;
};

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 i;
    
    cout << "You can enter up to " << n;
    cout << " students' messages (enter to terminate)." << endl;
    for (i = 0; i < n; i++)
    {
        cout << "Student #" << i + 1 << ": " << endl;
        cout << "Enter the fullname(a blank line to quit): ";
        cin.getline(pa[i].fullname, SLEN);
        if ('\0' == pa[i].fullname[0]) //题目要求空行结束输入;
        {
            break;
        }
        cout << "Enter the hobby: ";
        cin.getline(pa[i].hobby, SLEN);
        cout << "Enter the ooplevel: ";
        while (!(cin >> pa[i].ooplevel))
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
            cout << "Please enter an number: ";
        }
        cin.get(); //吸收正确输入时的换行符;
    }
    return i;
}

void display1(student st)
{
    cout << "\nName: " << st.fullname << endl;
    cout << "Hobby: " << st.hobby << endl;
    cout << "Ooplevel: " << st.ooplevel << endl;
}

void display2(const student *ps)
{
    cout << "\nName: " << ps->fullname << endl;
    cout << "Hobby: " << ps->hobby << endl;
    cout << "Ooplevel: " << ps->ooplevel << endl;
}

void display3(const student pa[], int n)
{
    if (n > 0)
    {
        cout << "\nAll students' information:" << endl;
        for (int i = 0; i < n; i++)
        {
            cout << "Name: " << pa[i].fullname << endl;
            cout << "Hobby: " << pa[i].hobby << endl;
            cout << "Ooplevel: " << pa[i].ooplevel << endl;
        }
    }
}

10.设计一个名为 calculate()的函数,它接受两个 double 值和一个指向数的指针,而被指向的函数接受两个 double 参数,并返回一个 double 值calculate()函数的类型也是 doublc,并返回被指向的函数使用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 calculate(double a, double b, double (*p)(double a, double b));
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);

int main()
{
    double a, b;
    double (*pf[3])(double a, double b) = {add, subtract, multiply};

    cout << "Enter two numbers (q to quit): ";
    while (cin >> a >> b)
    {
        for (int i = 0; i < 3; i++)
        {
            switch (i)
            {
                case 0:
                {
                    cout << "The " << a << " + " << b << " answer is: " << (*pf[i])(a, b) << endl;
                    break;
                }
                case 1:
                {
                    cout << "The " << a << " - " << b << " answer is: " << (*pf[i])(a, b) << endl;
                    break;
                }
                case 2:
                {
                    cout << "The " << a << " * " << b << " answer is: " << (*pf[i])(a, b) << endl;
                    break;
                }
            }
        }
        cout << "Next two numbers (q to quit): ";
    }
    cout << "Done!" << endl;

    return 0;
}

double calculate(double a, double b, double (*p)(double a, double b))
{
    return (*p)(a, b);
}

double add(double a, double b)
{
    return a + b;
}

double subtract(double a, double b)
{
    return a - b;
}

double multiply(double a, double b)
{
    return a * b;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值