《C++ Primer Plus》第八章课后题

复习题

1.哪种函数适合定义为内联函数?

只有一行代码的小型、非递归函数适合作为内联函数。

2.假设song()函数的原型如下:
void song(const char * name, int times);

a. 如何修改原型,使times的默认值为1?
b. 函数定义需要做哪些修改?
c. 能否为name提供默认值“O,My Papa”?

a. void song(const char * name, int times = 1);
b. 没有。只有原型包含默认值的信息。
c. 可以,如果保留times的默认值:
void song(const char * name = "O,My Papa", int times = 1);

3.编写 iquote()的重载版本——显示其用双引号括起的参数。编写3个版本:一个用于int参数,一个用于double参数,另一个用于 string参数。

void iquote(int n)

{

        cout<<"\""<<n<<"\"";

}

void iquote(double x)

{

        cout<<"\""<<x<<"\"";

}

void iquote(const char* str)

{

        cout<<"\""<<str<<"\"";

}

4.下面是一个结构模板:

struct box

{

        char maker [40];
        float height;
        float width;
        float length;
        float volume;

};

a.请编写一个函数,它将box结构的引用作为形参,并显示每个成员的值。
b.请编写一个函数,它将box结构的引用作为形参,并将volume成员设置为其他3边的乘积

a.void show box(const box & container)

{

        cout << "Made by " << container. maker << endl;
        cout << "Height = " << container.height << endl;
        cout << "Width = " << container.width << endI;
        cout << "Length = " << container.Iength << endl;
        cout <<"Volume = " << container.volume << endl;

}

b.void set_volume (box & crate)

{

        crate.volume = crate.height * crate.width * crate. length;

}

5. 为让函数fill()和show()使用引用参数;需要对程序清单7.15做哪些修改 ?

首先,修改原型:
void fill(std :: array<double, Seasons> & pa;
void show(const std :: array<double; Seasonss & da) ;
接下来,在main()中,将fill()调用修改
fill(expenses);
函数show()的调用不需要修改。
接下来,新的fill()进行重写
void fill (std: array<double, Seasons> & pa)
{
        using namespace std;
        for (int i = 0; i < Seasons; i++)
        {
                cout << "Enter " << Snames [i] << " expenses: ";
                cin >> pa[i];
        }
}
最后,修改show()的函数头:
void show(std :: array<double, Seasons> & da)

6.指出下面每个目标是否可以使用默认参数或函数重载完成,或者这两种方法都无法完成,并提供合适的原型。

a.mass(density, volume)返回密度为density、体积为volume的物体的质量,而mass(denstity)返回密度,为density、体积为1.0立方米的物体的质量。这些值的类型都为double。
b. repeat(10,"I'm OK”)将指定的字符串显示10次,而 repeat("But you're kind.of stupid”)将指定的字符串显示5次。
c. average(3,6)返回两个int参数的平均值(int类型),而average(3.0,6.0)返回两个double值的平均值(double类型)。
d.mangle("I'm glad to. meet you”)根据是将值赋给char变量还是char*变量,分别返回字符1和指向字符串“I'm mad to gleet you”的指针。

a.默认值double mass (double d, double v = 1:0);
        函数重载double mass (double d, double v);
        double mass (double d) ;
b.不能使用默认值,因为必须从右到左提供默认值。
        函数重载void repeat (int times, const char * str);
        void repeat (const char * str) ;
c.函数重载int average(int a, int b);
        double average (double x, double y);
d.不能这样做,因为两个版本的特征标将相同。

7. 编写返回两个参数中较大值的函数模板。

template<class T>
T max(T t1, T t2)

{

        return t1 >t2? t1 : t2;

}

8.给定复习题6的模板和复习题4的box结构,提供一个模板具体化,它接受两个box参数,并返回体积较大的一个。

template<> box max (box b1, box b2)

{

        return b1.volume > b2.volume? b1 : b2;

}

9.在下述代码(假定这些代码是一个完整程序的一部分)中v1、v2、v3、v4和v5分别是哪种类型?

int g(int x);

......

float m=5.5f ;
float & rm = m; 
decltype (m) v1 = m;
decltype(rm) v2 = m;
decltype ((m)) v3 = m;
decltype (g(100)) v4;
decltype (2.0* m) v5;

v1的类型为float,v2的类型为float&,v3的类型为float&,v4的类型为int,v5的类型为double。字面值2.0的类型为double,因此表达式2.0*m的类型为double。

编程练习

1.编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而。如果提供了第二个参数(int类型),且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第三个参数的值,而等于函数被调用的次数)。

#include <iostream>
using namespace std;
int num=0;
void printstr(const char * str,int time=0)
{
    num++;
    if(time!=0)
    {
        for(int i=0;i<num;i++)
        {
            cout<<str<<endl;
        }
    }
    else
    {
        cout<<str<<endl;
    }
}
int main()
{
    printstr("Hello");
    printstr("World",1);
    printstr("Hi");
    printstr("Bye",2);
    return 0;
}

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

#include <iostream>
#include <cstring>
using namespace std;
struct candybar
{
    char name[20];
    double weight;
    int col;
};
void set(candybar &can,const char* name="Millennium Munch",const double weight=2.85,const int col=350)
{
    strcpy(can.name,name);
    can.weight=weight;
    can.col=col;
}
void show(const candybar &can)
{
    cout<<"名称:"<<can.name<<endl;
    cout<<"重量:"<<can.weight<<endl;
    cout<<"热量:"<<can.col<<endl;
}

int main()
{
    candybar can;
    set(can);
    show(can);
    cout<<endl;
    set(can,"HL",1.1,12);
    show(can);
    return 0;
}

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>
using namespace std;

void upper(string& str)
{
    for (int i = 0; i < str.length(); i++)
        str[i] = toupper(str[i]);
}
int main()
{
    string str;
    cout<<"Enter a string (q to quit):";
    getline(cin,str);
    while(str!="q")
    {
        upper(str);
        cout<<str<<endl;
        cout<<"Next string (q to quit):";
        getline(cin,str);
    }
    cout<<"Bye"<<endl;
    return 0;
}

4.下面是一个程序框架:

#include <iostream>

using namespace std;

#include <cstring> // for strlen(), strcpy ()

struct stringy

{

    char *str; // points to a string

    int ct;    // length of string (not counting '\0')

};

// prototypes for set(), show(), and show() go here

int main()

{

    stringy beany;

    char testing[] = "Reality isn't what it used to be.";

    set(beany, testing); // first argument is a reference,

    // allocates space to hold copy of testing,

    // sets str member of beany to point to the

    // new block, copies testing to new block,

    // and sets ct member of beany

    show(beany);    // prints member string once

    show(beany, 2); // prints member string twice

    testing[0] = 'D';

    testing[1] = 'u';

    show(testing);    // prints testing string once

    show(testing, 3); // prints testing string thrice

    show("Done!");

    return 0;

}

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

#include <iostream>
using namespace std;
#include <cstring> // for strlen(), strcpy ()
struct stringy
{
    char *str; // points to a string
    int ct;    // length of string (not counting '\0')
};
// prototypes for set(), show(), and show() go here

void set(stringy &s, const char *str);
void show(const stringy &s,int ct=1);
void show(const string &str,int ct=1);

int main()
{
    stringy beany;
    char testing[] = "Reality isn't what it used to be.";
    set(beany, testing); // first argument is a reference,
    // allocates space to hold copy of testing,
    // sets str member of beany to point to the
    // new block, copies testing to new block,
    // and sets ct member of beany
    show(beany);    // prints member string once
    show(beany, 2); // prints member string twice
    testing[0] = 'D';
    testing[1] = 'u';
    show(testing);    // prints testing string once
    show(testing, 3); // prints testing string thrice
    show("Done!");
    return 0;
}
void set(stringy &s, const char *str)
{
    s.str = new char[strlen(str)+1];
    strcpy(s.str, str);
    s.ct = strlen(str);
}
void show(const stringy &s,int ct)
{
    for(int i=0;i<ct;i++)
    cout << s.str << endl;
}
void show(const string &str,int ct)
{
    for(int i=0;i<ct;i++)
    cout << str << endl;
}

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

#include <iostream>
using namespace std;
template<class T>
T max5(const T (&s)[5] )
{
    T m=s[0];
    for(int i=1;i<5;i++)
        if(s[i]>m)
            m=s[i];
    return m;
}
int main()
{
    int intArray[] = {3, 1, 4, 1, 5};
    cout<<"intArray max="<<max5(intArray)<<endl;
    double doubleArray[] = {2.5, 3.14, 1.41, 0.99, 5.67};
    cout<<"doubleArray max="<<max5(doubleArray)<<endl;
    return 0;
}

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

#include <iostream>
#include <string.h>
using namespace std;
template<class T>
T maxn( T x[],const int n) 
{
    T m=x[0];
    for(int i=1;i<n;i++)
        if(x[i]>m)
            m=x[i];
    return m;
}
template<>
const char* maxn(const char* x[],const int n)
{
    const char* longest=x[0];
    for(int i=1;i<n;i++)
        if(strlen(x[i])>strlen(longest))
            longest=x[i];
    return longest;
}
int main()
{
    int intArr[] = {1, 2, 3, 4, 5, 6};
    double doubleArr[] = {1.1, 2.2, 3.3, 4.4};
    const char* strArr[] = {"apple", "banana", "orange", "grape", "watermelon"};
    cout << "Max integer: " << maxn(intArr, 6) << endl;
    cout << "Max double: " << maxn(doubleArr, 4) << endl;
    cout << "Longest string: " << maxn(strArr, 5) << endl;
    return 0;
}

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

#include <iostream>
template <typename T>
T sumarray(T arr[], int n);
template <typename T>
T sumarray(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 << "Mr. E's Sum of things: \n";
    cout << sumarray(things, 6)<<endl; // uses template A
    cout << "Mr. E's Sum debts:\n";
    cout << sumarray(pd, 3);
    return 0;
}
template <typename T>
T sumarray(T arr[], int n)
{
    using namespace std;
    cout << "template A\n";
    T sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
    return sum;
}
template <typename T>
T sumarray(T *arr[], int n)
{
    using namespace std;
    cout << "template B\n";
    T sum = 0;
    for (int i = 0; i < n; i++)
        sum += *arr[i];
    return sum;
}
  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值