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

1

题目

  编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数(int类型),且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的-些技术。在一个简单的程序中使用该函数,以演示该函数是如何工作的。

题解

#include<iostream>
using namespace std;
int cnt=0;
void PrintStr(const char a[],int n=0);
int main(){
    const char *p="Hello C++!";
    PrintStr(p);                //调用一次,输出一次字符串
    PrintStr(p);                //调用一次,参数为0,输出一次字符串
    PrintStr(p,1);              //因为带上自身总共调用了三次,所以会输出三次字符串
    return 0;
}
void PrintStr(const char a[],int n){
    cnt++;
    n=n==0?1:cnt;
    for(int i=0;i<n;i++)
        cout<<a<<endl;
}

2

题目

  CandyBar结构包含3个成员。第一个成员存储candybar的品牌名称;第二个成员存储candybar的重量(可能有小数);第三个成员存储candy bar的热量(整数)。请编写一个程序,它使用一个这样的函数,即将CandyBar的引用、char指针、double和int作为参数,并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为“Millennium Munch"、2.85和350。另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。

题解

#include<iostream>
#include<string>
using namespace std;
struct CandyBar{
    string brand;
    double weight;
    int calorie;
};
void SetCandyBar(CandyBar &cb,const char *brand="Millennimu Munch",double weight=2.85,int calorie=350);
void ShowCandyBar(const CandyBar &cb);
int main(){
    CandyBar cb;
    SetCandyBar(cb);
    ShowCandyBar(cb);
    return 0;
}
void SetCandyBar(CandyBar &cb,const char *brand,double weight,int calorie){
    cb.brand=brand;
    cb.weight=weight;
    cb.calorie=calorie;
}
void ShowCandyBar(const CandyBar &cb){
    cout<<"Band: "<<cb.brand<<endl
        <<"Weight: "<<cb.weight<<endl
        <<"Calorie: "<<cb.calorie<<endl;
}

3

题目

  编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,为此可使用表6.4描述的函数toupper()。然后编写一个程序,它通过使用一个循环让您能够用不同的输入来测试这个函数,该程序的运行情况如下:

Enter a string (q to quit): go away
GO AWAY
Next string (q to quit): good grief!
GOOD GRIEF!
Next string (q to quit): q
Bye.

题解

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
void AllToUpper(string &str);
int main(){
    string str;
    cout<<"Enter a string (q to quit): ";
    while(getline(cin,str)&&str!="q"){
        AllToUpper(str);
        cout<<str<<endl;
        cout<<"Next string (q to quit): ";
    }
    cout<<"Bye."<<endl;
    return 0;
}
void AllToUpper(string &str){
    int size=str.size();
    for(int i=0;i<size;i++)
        str[i]=toupper(str[i]);
}

4

题目

  下面是一个程序框架:

#include<iostream>
#include<cstring>
using namespace std;
struct stringy{
    char *str=nullptr;
    int ct=0;
};
int main(){
    stringy beany;
    char testing[]="Reality isn't what it used to be.";
    set(beany,testing);
    show(beany);
    show(beany,2);
    testing[0]='D';
    testing[1]='u';
    show(testing);
    show(testing,3);
    show("Done!");
    return 0;
}

  请提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每个都使用默认参数。请尽可能使用cosnt参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器。)

题解

#include<iostream>
#include<cstring>
using namespace std;
struct stringy{
    char *str=nullptr;
    int ct=0;
};
void set(stringy &stry,const char * cstr);
void show(const stringy &stry,int n=1);         //打印stringy字符串n次
void show(const char* cstr,int n=1);            //打印字符串n次
int main(){
    stringy beany;
    char testing[]="Reality isn't what it used to be.";
    set(beany,testing);
    show(beany);
    show(beany,2);
    testing[0]='D';
    testing[1]='u';
    show(testing);
    show(testing,3);
    show("Done!");
    return 0;
}
void set(stringy &stry,const char * cstr){
    delete [] stry.str;                         //先释放原来的空间,初始化是空,所以delete不会有问题
    int size=strlen(cstr);
    stry.ct=size;
    stry.str=new char[size];
    memcpy(stry.str,cstr,size);
}
void show(const stringy &stry,int n){
    for(int i=0;i<n;i++)
        cout<<stry.str<<endl;
}
void show(const char* cstr,int n){
    for(int i=0;i<n;i++)
        cout<<cstr<<endl;
}

5

题目

  编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序中使用该函数,将T替换为一个包含5个int值的数组和一个包含5个dowble值的数组,以测试该函数。

题解

#include<iostream>
using namespace std;
const int SIZE=5;
template<typename T>
T max5(T at[]);
int main(){
    int ai[SIZE]={1,2,7,4,3};
    double ad[SIZE]={1.0,3.0,4.0,5.0,2.0};
    cout<<"The max number of "<<SIZE<<" int numbers is: "<<max5(ai)<<endl;
    cout<<"The max number of "<<SIZE<<" double numbers is: "<<max5(ad)<<endl;
    return 0;
}
template<typename T>
T max5(T at[]){
    int maxpos=0;
    for(int i=1;i<SIZE;i++){
        if(at[i]>at[maxpos])
            maxpos=i;
    }
    return at[maxpos];
}

6

题目

  编写模板函数maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个double元素的数组来调用该函数。程序还包含一个具体化,它将char指针数组和数组中的指针数量作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使用由5个字符串指针组成的数组来测试该具体化。

题解

#include<iostream>
#include<cstring>
using namespace std;
//模板
template<typename T>
T maxn(T at[],int n);
//针对字符串数组的实例化
template<>
const char* maxn(const char *ap[],int n);
int main(){
    int ai[6]={1,2,7,4,3,3};
    double ad[4]={1.0,4.3,5.1,2.2};
    const char* ac[5]={"Hello world!","Hello C++!","Hello PHP!","Hello Java!","Hello Python!"};
    cout<<"The max number of "<<6<<" int numbers is: "<<maxn(ai,6)<<endl;
    cout<<"The max number of "<<4<<" double numbers is: "<<maxn(ad,4)<<endl;
    cout<<"The max length string of "<<5<<" strings is: "<<maxn(ac,5)<<endl;
    return 0;
}
template<typename T>
T maxn(T at[],int n){
    int maxpos=0;
    for(int i=1;i<n;i++){
        if(at[i]>at[maxpos])
            maxpos=i;
    }
    return at[maxpos];
}
template<>
const char* maxn(const char *ap[],int n){
    int maxpos=0;
    for(int i=1;i<n;i++){
        if(strlen(ap[i])>strlen(ap[maxpos]))
            maxpos=i;
    }
    return ap[maxpos];
}

7

题目

  修改程序清单8.14, 使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显示数组的内容。程序应显示thing的总和以及所有debt的总和。

题解

#include<iostream>
template<typename T>
T ShowArray(T arr[],int n);
template<typename T>
T ShowArray(T* arr[],int n);
struct debts{
    char name[50];
    double amount;
};
int main(){
    using namespace std;
    int things[6]={13,31,103,301,310,130};
    struct debts mr_E[3]={
        {"Ima Wolfe",2400.0},
        {"Ura Foxe",1300.0},
        {"Iby Stout",1800.0},
    };
    double *pd[3];
    for(int i=0;i<3;i++)
        pd[i]=&mr_E[i].amount;
    cout<<"Sum of Mr. E's counts of things:\n";
    cout<<ShowArray(things,6)<<endl;
    cout<<"Sum of Mr. E's debets:\n";
    cout<<ShowArray(pd,3)<<endl;
    return 0;
}
template<typename T>
T ShowArray(T arr[],int n){             //将所有的数字都加载第一个数字上
    using namespace std;
    cout<<"template A\n";
    for(int i=1;i<n;i++)
        arr[0]+=arr[i];
    return arr[0];
}
template<typename T>
T ShowArray(T* arr[],int n){            //将所有的数字都加载第一个数字上
    using namespace std;
    cout<<"template B\n";
    for(int i=1;i<n;i++)
        *arr[0]+=*arr[i];
    return *arr[0];
}

当珍惜每一片时光~