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

1

题目

  下面是一个头文件:

#ifndef GOLF_H_
#define GOLF_H_
const int Len=40;
struct golf{
    char fullname[Len];
    int handicap;
};
//设置golf的值
void setgolf(golf &g,const char* name, int hc);
//提示用户输入并设置golf的值
int setgolf(golf &g);
//重置handicap的值
void handicap(golf &g,int hc);
void showgolf(const golf &g);
#endif

  注意到setgolf()被重载,可以这样使用其中的第一个版本:

golf ann;
setgolf(ann,"Ann Birdfree",24);

  上述函数调用提供了存储再ann结构中的信息。可以这样使用其第二个版本:

golf andy;
setgolf(andy);

  上述函数将提示用户输入姓名和等级,并将他们存储在andy结构中。这个函数可以(但是不一定必须)再内部使用第一个版本。
  根据这个头文件,创建一个多文件程序。其中的二个文件名为golf.cpp,它提供了与头文件中的原型匹配的函数定义;另一个文件应包含main(),并演示原型化函数的所有特性。例如,包含一个让用户输入的循环,并使用输入的数据来填充一个由golf结构组成的数组,数组被填满或用户将高尔夫选手的姓名设置为空字符串时,循环将结束。main()函数只使用头文件中原型化的函数来访问golf结构。

题解

  源文件golf.cpp:

#include<iostream>
#include<cstring>
#include"golf.h"
void setgolf(golf &g,const char* name, int hc){
    std::strcpy(g.fullname,name);
    g.handicap=hc;
}
//提示用户输入并设置golf的值,如果读入名字,返回1;如果读入空行,返回0;
int setgolf(golf &g){
    std::cout<<"Enter the name: ";
    std::cin.getline(g.fullname,Len);
    if(g.fullname[0]=='\0') return 0;             //如果读入空行,则返回0
    std::cout<<"Enter the handicap: ";
    std::cin>>g.handicap;
    return 1;
}
//重置handicap的值
void handicap(golf &g,int hc){
    g.handicap=hc;
}
void showgolf(const golf &g){
    using std::cout;
    using std::endl;
    cout<<"Name: "<<g.fullname<<endl;
    cout<<"Handicap: "<<g.handicap<<endl;
}

  源文件1.cpp:

//与golf.cpp一同编译
#include<iostream>
#include"golf.h"
int main(){
    using namespace std;
    golf first,second;
    setgolf(first,"First one",1);
    if(setgolf(second)){
        cout<<"Set second successfully!"<<endl;
        showgolf(second); 
    }
    else
        cout<<"Set second unsuccessfully!"<<endl;
    handicap(first,3);
    showgolf(first);   
    return 0;
}

2

题目

  修改程序清单9.9:用string对象代替字符数组。这样,该程序将不再需要检查输入的字符串是否过长,同时可以将输入字符串同字符串“进行比较,以判断是否为空行。

题解

#include<iostream>
#include<string>
void strcount(std::string str);
int main(){
    using namespace std;
    string input;
    cout<<"Enter a line:\n";
    getline(cin,input);
    while(input!=""){
        strcount(input);
        cout<<"Enter next line(empty line to quit):\n";
        getline(cin,input);
    }
    cout<<"Bye\n";
    return 0;
}
void strcount(std::string str){
    using namespace std;
    static int total=0;
    int count=0;
    cout<<"\""<<str<<"\" contains ";
    count=str.size();
    total+=count;
    cout<<count<<" characters\n";
    cout<<total<<" characters total\n";
}

3

题目

  下面是一个结构声明:

struct chaff{
    char dross[20];
    int slag;
};

  编写一个程序,使用定位new运算符将一个包含两个这种结构的数组放在一个缓冲区中。然后,给结构的成员赋值(对于char数组,使用函数strcpy()),并使用一个循环来显示内容。一种方法是像程序清单9.10那样将一个静态数组用作缓冲区;另一种方法是使用常规new运算符来分配缓冲区。

题解

#include<iostream>
#include<cstring>
#include<new>
using namespace std;
const int BUF=200;
char buffer[BUF];
struct chaff{
    char dross[20];
    int slag;
};
int main(){
    const char* drosses[2]={"chaff one","chaff two"};
    chaff* pheap=new chaff[2];
    chaff* pbuff=new (buffer) chaff[2];
    cout<<"The address of pheap: "<<pheap<<endl;
    cout<<"The address of pbuff: "<<(void*)pbuff<<endl;
    cout<<endl;
    for(int i=0;i<2;i++){
        strcpy(pheap[i].dross,drosses[i]);
        pheap[i].slag=i;

        strcpy(pbuff[i].dross,drosses[i]);
        pbuff[i].slag=i;
    }
    for(int i=0;i<2;i++){
        cout<<"The address of pheap["<<i<<"] : "<<&pheap[i]<<endl;
        cout<<"The contains:"<<endl;
        cout<<"Dross: "<<pheap[i].dross<<endl;
        cout<<"Slag: "<<pheap[i].slag<<endl; 

        cout<<"The address of pbuff["<<i<<"] : "<<&pbuff[i]<<endl;
        cout<<"The contains:"<<endl;
        cout<<"Dross: "<<pbuff[i].dross<<endl;
        cout<<"Slag: "<<pbuff[i].slag<<endl;
    }
    delete [] pheap;
    return 0;
}

4

题目

  请基于下面这个名称空间编写一个由3个文件组成的程序:

#ifndef SALES_H_
#define SALES_H_
namespace SALES{
    const int QUARTERS=4;
    struct Sales{
        double sales[QUARTERS];
        double average;
        double max;
        double min;
    };
    //从ar中复制最多4个或者n个到s的sales成员中,计算平均值和最大最小值并存到对应的成员变量中
    void setSales(Sales& s,const double ar[],int n);
    //提示并读入四个数字,计算并存入对应的成员变量中
    void setSales(Sales& s);
    //显示结构体
    void showSales(const Sales &s);
}
#endif  

  第一个文件是一个头文件,其中包含名称空间;第二个文件是一个源代码文件,它对这个名称空间进行扩展,以提供这三个函数的定义:第三个文件声明两个Sales对象,并使用setSales()的交互式版本为一个结构提供值,然后使用setSales()的非交互式版本为另一个结构提供值。另外它还使用showSales()来显示这两个结构的内容。

题解

  源代码文件sales.cpp:

//sales.cpp
#include<iostream>
#include"sales.h"
namespace SALES{
    //从ar中复制最多4个或者n个到s的sales成员中,计算平均值和最大最小值并存到对应的成员变量中
    void setSales(Sales& s,const double ar[],int n){
        if(n<=0) return;
        n=n<QUARTERS?n:QUARTERS;
        double sum=0.0;
        s.max=s.min=ar[0];
        int i;
        for(i=0;i<n;i++){
            sum+=ar[i];
            s.sales[i]=ar[i];
            if(ar[i]>s.max) s.max=ar[i];
            if(ar[i]<s.min) s.min=ar[i];
        }
        //如果小于4个则,将其他置零
        if(i<QUARTERS) for(;i<QUARTERS;i++) s.sales[i]=0.0;
        s.average=sum/QUARTERS;
    }
    //提示并读入四个数字,计算并存入对应的成员变量中
    void setSales(Sales& s){
        using std::cout;
        using std::cin;
        cout<<"Enter 4 numbers as the seales:"<<std::endl;
        double sum=0.0;
        for(int i=0;i<QUARTERS;i++){
            cin>>s.sales[i];
            sum+=s.sales[i];
            if(i==0) s.max=s.min=s.sales[i];
            else{
                if(s.sales[i]>s.max) s.max=s.sales[i];
                if(s.sales[i]<s.min) s.min=s.sales[i];
            }
        }
        s.average=sum/QUARTERS;
    }
    //显示结构体
    void showSales(const Sales &s){
        using std::cout;
        using std::endl;
        cout<<"Sales for 4 quarters as following:\n";
        for(int i=0;i<QUARTERS;i++){
            if(i) putchar(' ');
            cout<<s.sales[i];
        }
        cout<<endl;
        cout<<"The average of all sales: "<<s.average<<endl;
        cout<<"The max sale: "<<s.max<<endl;
        cout<<"The min sale: "<<s.min<<endl;
    }
}

  源代码文件4.cpp:

//与sales.cpp一起编译
#include<iostream>
#include"sales.h"
int main(){
    SALES::Sales one,two;
    double mysales[]={100.2, 200.3, 300.4, 400.5};
    SALES::setSales(one,mysales,3);
    SALES::setSales(two);
    SALES::showSales(one);
    SALES::showSales(two);
    return 0;
}

当珍惜每一片时光~