《C++ Primer Plus》第六章习题与参考答案

1,内容选自《C++ Primer Plus》(第6版)中文版,2017年1月河北第21次印刷版本
2,文章系笔者学习笔记,若有错误,欢迎指正
3,如有雷同,纯属巧合

6.10 复习题

1.请看下面两个计算空格和换行符数目的代码片段:

//version 1
while (cin.get(ch)) //quit on eof
{
     if (ch == ' ')
         spaces++;
     if (ch == '\n')
         newlines++;
}

//version 2
while (cin.get(ch)) //quit eof
{
     if (ch == ' ')
         spacees++;
     else if (ch == '\n')
         newlines++;
}

第二个格式比第一个格式好在哪里?

这两个版本将给出相同的答案,但if else版本的效率更高。例如,考虑当ch为空格时的情况。版本1对空格加1,然后看它是否为换行符。这将浪费时间,因为程序已经知道ch为空格,因此它不是换行符。在这种情况下,版本2将不会查看字符是否为换行符。

2.在程序清单6.2中,用ch+1替换++ch将发生什么情况?

++ch和ch+1得到的数值相同。但++ch的类型为char,将作为字符打印,而ch+1是int类型(因为将char和int相加),将作为数字打印。

3.请认真考虑下面的程序:

#include <iostream>
using namespace std;

int main()
{
    char ch;
    int ct1, ct2;
    ct1 = ct2 = 0;
    while ((ch = cin.get()) != '$')
    {
        cout << ch;
        ct1++;
        if (ch = '$')
            ct2++;
        cout << ch;
    }
    cout << "ct1=" << ct1 << ",ct2=" << ct2 << "\n";
    return 0;
}

假设输入如下(请在每行末尾按回车键):
Hi!
Send $10 or $20 now!
则输出将是什么(还记得吗,输入被缓冲)?

由于程序使用ch=$,而不是ch==$,因此输入和输出将如下:
Hi!
H$i$!$
$Send $10 or $20 now!
S$e$n$d$ $ct1 = 9, ct2 = 9

在第二次打印前,每个字符都被转换为 c h = 字符。另外,表达式ch= 的值为$字符的编码,因此它是非0值,因而为true;所以每次ct将被加1.

4.创建表示下述条件的逻辑表达式:
a.weight大于或等于115,但小于125。
b.ch为q或Q。
c.x为偶数,但不是26。
d.x为偶数,但不是26的倍数。
e.donation为1000-2000或guest为1。
f.ch是小写字母或大写字母(假设小写字母是依次编码的,大写字母也是依次编码的,但在大小写字母间编码是不连续的)。

a.weight >=115 && weight < 125
b.ch == 'q' || ch == 'Q' 
c.(x % 2 == 0) && (x != 26)
d.(x % 2 == 0) && !(x % 26 = 0) 
e.(1000 <= donation >= 2000) || (guest == 1)
f.(ch >= 'a' && ch <= 'z') || (ch <= 'A' && ch <= 'Z')

5.在英语中,"I will not not speak(我不会不说) "的意思与"I will speak(我要说)"相同。在c++中,!!x是否与x相同呢?

不一定。例如,如果x为10,则!x为0,!!x为1。然而,如果x为bool变量,则!!x为x。

6.创建一个条件表达式,其值为变量的绝对值。也就是说,如果变量x为正,则表达式的值为x;但如果x为负,则表达式的值为-x–这是一个正值。

(x < 0) ? -x : x;(x >= 0) ? x : -x;

7.用switch改写下面的代码片段:

if (ch == 'A')
        a_grade++;
else if (ch == 'B')
        b_grade++;
else if (ch == 'C')
        c_grade++;
else if (ch == 'D')
        d_grade++;
else
        f_grade++;
switch (ch)
    {
    case 'A':
        a_grade++;
        break;
    case 'B':
        a_grade++;
        break;
    case 'C':
        a_grade++;
        break;
    case 'D':
        a_grade++;
        break;
    case 'F':
        f_grade++;
        break;
    }

8.对于程序清单6.10,与使用字符(如a和c)表示菜单选项和case标签有何优点呢?(提示:想一想用户输入q和输入5的情况。)

如果使用整数标签,且用户输入了非整数(如q),则程序将因为整数输入不能处理字符而挂起。但是,如果使用字符标签,而用户输入了整数(如5),则字符输入将5作为字符处理。然后,switch语句的default部分将提示输入另一个字符。

9.请看下面的代码片段

int line = 0;
char ch;
while (cin.get(ch))
{
    if (ch == 'Q')
           break;
    if (ch != '\n')
           continue;
    line++;
}

请重写该代码片段,不要使用break语句continue语句。

int line = 0;
    char ch;
    while (cin.get(ch) && ch != 'Q')
    {
        if (ch == '\n')
            line++;
    }

6.11 编程练习

1.编写一个程序,读取键盘输入,直到遇到@符号为止,并回显输入(数字除外),同时将大写字符转换为小写字符,将小写字符转换为大写(别忘了cctype函数系列)。

#include <iostream>
#include <cctype>
using namespace std;

int main()
{
    cout << "Enter text for analysis, and type @ to terminate input: \n";
    char ch;
    cin.get(ch);
    while (ch != '@')
    {
        if (islower(ch))
            ch = toupper(ch);
        else if (isupper(ch))
            ch = tolower(ch);
        if (!isdigit(ch))
            cout << ch;
        cin.get(ch);
    }
    return 0;
}

2.编写一个程序,最多将10个donation值读入一个double数组中(如果你愿意,也可以使用模板类array)。程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。

#include <iostream>
using namespace std;
const int MAX = 10;
int main()
{
    double donations[MAX];
    cout << "Please enter the donations. \n";
    cout << "You may enter up to " << MAX << " donation <not-a-number to terminate>. \n";
    cout << "donation #1: ";
    int i = 0;
    while (i < MAX && cin >> donations[i])
    {
        if (++i < MAX)
        {
            cout << "donation #" << i + 1 << ": ";
        }
    }
    double total = 0;
    for (int j = 0; j < i; j++)
    {
        total += donations[j];
    }

    int average = total / i;
    int count = 0;
    if (i == 0)
    {
        cout << "No donation. \n";
    }
    else
    {
        for (int j = 0; j < i; j++)
        {
            if (donations[j] > average)
            {
                ++count;
            }
        }
        cout << "average: " << average << endl;
        cout << count << " donations bigger than average. \n"
             << endl;
    }
    cout << "Done. \n";
    return 0;
}

3.编写一个菜单驱动程序的雏形。该程序显示一个提供四个选项的菜单–每个选项用一个字母表标记。如果用户使用有效选项之外的字母进行响应,程序将提示用户输入有效的字母,直到用户这样选择为止。然后,该程序使用一条switch语句,根据用户的选择执行一个简单操作。该程序的运行情况如下:

Please enter one of the following choices:
c) carnivore         p) pianist
t) tree              g)game
f
Please enter a c,p,t or g:q
Please enter a c,p,t or g:t
A maple is a tree.
#include <iostream>
using namespace std;

int main()
{
    cout << "Please enter one of the following choices:" << endl;
    cout << "c) carnivore         p) pianist" << endl;
    cout << "t) tree              g) game" << endl;
    char ch;
    cin >> ch;
    while (ch != 'c' && ch != 'p' && ch != 't' && ch != 'g')
    {
        cout << "Please enter a c,p,t or g:";
        cin >> ch;
    }
    switch (ch)
    {
    case 'c':
        cout << "A maple is a carnivore." << endl;
        break;
    case 'p':
        cout << "A maple is a pianist." << endl;
        break;
    case 't':
        cout << "A maple is a tree." << endl;
        break;
    case 'g':
        cout << "A maple is a game." << endl;
        break;
    default:
        break;
    }
    return 0;
}

4.加入Benevolent Order of Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名来了解他(她)。请编写一个程序,可以使用真实姓名、头衔、秘密姓名或成员偏好来列出成员。编写该程序时,请使用下面的结构:

/Benevolent Order of Programmers name structure
struct bop{
    char fullname[strsize];          //real name
    char title[strzie];              //job title
    char bopname[strsize];           //secret BOP name
    int preference;                  //0=fullname,1=title,2=bopname
};

该程序创建一个由上述结构组成的小型数组,并将其初始化为适当的值。另外,该程序使用一个循环,让用户在下面的选项中进行选择:
a.display by name b.diaplay by title
c.display by bopname d.display by preference
q.quit
注意,“display by preference”并不意味显示成员的偏好,而是意味着根据成员的偏好来列出成员。例如,如果偏好号为1,则选择d将显示程序员的头衔。该程序的运行情况如下:

Benevolent Order of Programmers Report
a. display by name         b. display by title
c. display by bopname      d. display by preference
q. quit
Enter your choice: a
Wimp Macho
Raki Rhodes
Celia Laiter
Hoppy Hipman
Pat Hand
Next choice: d
Wimp Macho
Junior Programmer
MIPS
Analyst Trainee
LOOPY
Next choice: q
Bye!
#include <iostream>
using namespace std;

const int strsize = 20;
struct bop
{
    char fullname[strsize];
    char title[strsize];
    char bopname[strsize];
    int preference; //0 = fullname, 1 = title, 2 = bopname
};
bop bops[5] = {{"Wimp Macho", "Junior Programmer", "WM", 0},
               {"Raki Rhodes", "Junior Programmer", "RR", 1},
               {"Celia Laiter", "Junior Programmer", "CL", 2},
               {"Hoppy Hipman", "Analyst Trainee", "HH", 1},
               {"Pat Hand", "Trainer", "PH", 2}};

void makeChoice(char ch)
{
    switch (ch)
    {
    case 'a':
        for (int i = 0; i < 5; i++)
        {
            cout << bops[i].fullname << endl;
        }
        cout << "Next choice: ";
        break;
    case 'b':
        for (int i = 0; i < 5; i++)
        {
            cout << bops[i].title << endl;
        }
        cout << "Next choice: ";
        break;
    case 'c':
        for (int i = 0; i < 5; i++)
        {
            cout << bops[i].bopname << endl;
        }
        cout << "Next choice: ";
        break;
    case 'd':
        for (int i = 0; i < 5; i++)
        {
            if (bops[i].preference == 0)
            {
                cout << bops[i].fullname << endl;
            }
            else if (bops[i].preference == 1)
            {
                cout << bops[i].title << endl;
            }
            else
            {
                cout << bops[i].bopname << endl;
            }
        }
        cout << "Next choice: ";
        break;
    }
}

int main()
{
    cout << "Benevolent Order of Programmers Report" << endl;
    cout << "a. display by name          b. display by title" << endl;
    cout << "c. display by bopname       d. display by preference" << endl;
    cout << "q. quit" << endl;
    cout << "Enter your choice: ";
    char choice;
    while (cin.get(choice) && choice != 'q')
    {
        switch (choice)
        {
        case 'a':
            makeChoice('a');
            break;
        case 'b':
            makeChoice('b');
            break;
        case 'c':
            makeChoice('c');
            break;
        case 'd':
            makeChoice('d');
            break;
        }
    }
    cout << "Bye!" << endl;
    return 0;
}

5.在Neutronia王国,货币单位是tvarp,收入所得税的计算方式如下:
5000 tvarps: 不收税
5001~15000 tvarps: 10%
15001~35000 tvarps: 15%
35000 tvarps以上: 20%
例如,收入为38000 tvarps时,所得税为5000×0.00+10000×0.10+2000×0.15+3000×0.20,即 4600tvarps。请编写一个程序,使用循环来要求用户输入收入,并报告所得税,当用户输入负数或非数字时,循环将结束。

#include <iostream>
using namespace std;

int main()
{
    cout << "Enter your income: ";
    double income, tax;
    while ((cin >> income) && (income >= 0))
    {
        if (income <= 5000)
        {
            tax = 0.0;
        }
        else if (income >= 5001 && income < 15000)
        {
            tax = (income - 5000) * 0.10;
        }
        else if (income >= 15001 && income < 35000)
        {
            tax = 10000 * 0.10 + (income - 15000) * 0.15;
        }
        else
        {
            tax = 10000 * 0.10 + 20000 * 0.15 + (income - 35000) * 0.20;
        }
        cout << "your tax: " << tax << " tvarps \n";
        cout << "Enter your income:";
    }
    return 0;
}

6.编写一个程序,记录捐助给"维护合法权利团体"的资金。该程序要求用户输入捐赠者数目,然后要求用户输入每一个捐献者的姓名和款项。这些信息被存储在一个动态分配的结构数组中.每个数据结构有两个成员:用来存储姓名的字符串数组(或string对象)和用来存储款项的double成员。读取所有的数据后,程序将显示所有捐款超过10000的捐款着姓名及其捐款数额。该列表前应包含一个标题,指出下面的捐款者是重要捐款人(Grand Patrons)。然后,程序将列出其他的捐款者,该列表要以Partons开头。如果某种类别没有捐款者,则程序将打印单词"none"。该程序只显示这两种类别,而不进行排序。

#include <iostream>
using namespace std;

struct donor
{
    char name[20];
    double donation;
};

void display(donor donors[], int number, bool isGrand)
{
    int count = 0;
    if (isGrand)
    {
        for (int i = 0; i < number; i++)
        {
            if (donors[i].donation > 10000)
            {
                count++;
                cout << donors[i].name << endl;
                cout << donors[i].donation << endl;
            }
        }
    }
    else
    {
        for (int i = 0; i < number; i++)
        {
            if (donors[i].donation <= 10000)
            {
                count++;
                cout << donors[i].name << endl;
                cout << donors[i].donation << endl;
            }
        }
    }
    if (count == 0)
        cout << "none" << endl;
}

int main()
{
    cout << "Enter the number of donors: ";
    int number;
    cin >> number;
    donor *donors = new donor[number];
    for (int i = 0; i < number; i++)
    {
        cout << "donor #" << i+1 << ": "<< endl;
        cout << "Enter the donor name: ";
        cin >> donors[i].name;
        cout << "Enter the donation amount: ";
        cin >> donors[i].donation;
    }
    cout << "******Grand Partons******" << endl;
    display(donors, number, true);
    cout << "******Partons******" << endl;
    display(donors, number, false);
    delete[] donors;
    return 0;
}

7.编写一个程序,它每次读取一个单词,直到用户只输入q。然后,该程序指出有多少个单词以元音打头,有多少个单词以辅音打头,还有多少个单词不属于这两类。为此,方法之一是,使用isalpha()来区分以字母和其他字母打头的单词,然后对于通过isalpha()测试的单词,使用if或switch语句来确定哪些以元音打头。该程序的运行情况如下:

Enter words (q to quit):
The 12 awesome oxem ambled
quiety across 15 meters of lawn. q
5 words beginning with vowels
4 words beginning with consonants
2 others
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main()
{
    cout << "Enter words (q to quit): ";
    string word;
    int vowel = 0;
    int consonant = 0;
    int others = 0;
    while ((cin >> word) && (word != "q"))
    {

        if (isalpha(word[0]))
        {
            switch (word[0])
            {
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
            case 'A':
            case 'E':
            case 'I':
            case 'O':
            case 'U':
                vowel++;
                break;
            default:
                consonant++;
            }
        }
        else
        {
            others++;
        }
    }
    cout << vowel << " words beginning with vowels \n";
    cout << consonant << " words beginning with consonants \n";
    cout << others << " others \n";
    return 0;
}

8.编写一个程序,他打开一个文件,逐个字地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符。

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
const int SIZE = 60;

int main()
{
    char filename[SIZE];
    ifstream inFile;
    cout << "Enter name of data file: ";
    cin.getline(filename, SIZE);
    inFile.open(filename);
    if (!inFile.is_open())
    {
        cout << "Could not open the file. " << filename << endl;
        cout << "Program terminate. \n";
        exit(EXIT_FAILURE);
    }

    char ch;
    int count = 0;
    inFile >> ch;
    while (inFile.good())
    {
        ++count;
        inFile >> ch;
    }
    if (inFile.eof())
    {
        cout << "End of file reached. \n";
    }
    else if (inFile.fail())
    {
        cout << "Input terminated by data mismatch. \n";
    }
    else
    {
        cout << "Input terminated for unknown reason. \n";
    }

    if (count == 0)
    {
        cout << "No data processed. \n";
    }
    else
    {
        cout << "char read: " << count << endl;
    }

    inFile.close();
    return 0;
}

9.完成编程练习6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。即该文件类似于下面:

4
Sam Stone
2000
Freida Flass
100500
Tammy Tubbs
5000
Rich Raptor
55000

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
const int SIZE = 60;

struct donor
{
    char name[20];
    double donation;
};

void display(donor donors[], int number, bool isGrand)
{
    int count = 0;
    if (isGrand)
    {
        for (int i = 0; i < number; i++)
        {
            if (donors[i].donation > 10000)
            {
                count++;
                cout << donors[i].name << endl;
                cout << donors[i].donation << endl;
            }
        }
    }
    else
    {
        for (int i = 0; i < number; i++)
        {
            if (donors[i].donation <= 10000)
            {
                count++;
                cout << donors[i].name << endl;
                cout << donors[i].donation << endl;
            }
        }
    }
    if (count == 0)
        cout << "none" << endl;
}

int main()
{
    char filename[SIZE];
    ifstream inFile;
    cout << "Enter name of data file: ";
    cin.getline(filename, SIZE);
    inFile.open(filename);
    if (!inFile.is_open())
    {
        cout << "Could not open the file. " << filename << endl;
        cout << "Program terminate. \n";
        exit(EXIT_FAILURE);
    }

    int number = 0;
    inFile >> number;
    char ch[30];
    inFile.getline(ch, 1);
    donor *donors = new donor[number];
    for (int i = 0; i < number; i++)
    {
        inFile.getline(donors[i].name, 30);
        inFile >> donors[i].donation;
        inFile.getline(ch, 1);
    }
    cout << "******Grand Partons******" << endl;
    display(donors, number, true);
    cout << "******Partons******" << endl;
    display(donors, number, false);
    delete[] donors;
    return 0;
}
发布了8 篇原创文章 · 获赞 1 · 访问量 685

猜你喜欢

转载自blog.csdn.net/Heisenberg_Li/article/details/103927942