C++primer习题第五章

来源:互联网 发布:cad软件锁不起作用 编辑:程序博客网 时间:2024/05/12 21:17


练习5.1:什么是空语句?什么时候会用到空语句?

答:(标准)

  空语句是最简单的语句,空语句有一个单独的分号构成。如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该使用空语句,空语句什么也不做。

  一种常见的情况是,当循环的全部工作在条件部分就可以完成时,我们通常会用到空语句。使用空语句时候最好加上注释,从而令代码的阅读者知道这条语句是有意省略内容的。


练习5.2:什么是块?什么时候会用到块?

答:(标准)

块是指用花括号括起来的语句和声明的序列,也称为复合语句。一个块就是一个作用域,在块中引入的名字只能在块内部以及嵌套在块中的字块里访问。

如果在程序的某个地方,语法上需要一条语句,但是逻辑上需要多条语句,此时应该使用块。


练习5.3:使用逗号运算符重写1.4.1节的while循环,使它不再需要块,观察改写之后的代码的可读性提高了还是降低了。

#include<iostream>int main(){    int sum =0, val = 1;    while( val <=  10 )        sum += val, ++val;    std::cout << "Sum of 1 to 10 inclusive is "              << sum << std::endl;    return 0;}
很明显,改写部分的可读性下降了。


练习5.4:说明下列例子的含义,如果存在问题,试着修改它。

(a) while( string::iterator iter != s.end() ) { /* . . . */ }

iter并没有赋初值。不能用来比较。

修改为:

string::iterator iter = s.begin();

while( iter != s.end() ) { /*. . . */ }


(b)while( bool status = find( word ) ) { /* . . . */}

    if( !status ) { /* . . . */}

非法。status定义在while循环内部,所以作用域仅限于while循环。不能在if语句中使用status 。

修改为:

bool status;

while( status = find( word ) {/* . . . */}

if( !status ) { /* . . . */}


练习5.5:写一段自己的程序,使用if else语句实现把数字成绩转换成字母成绩的要求。

#include<iostream>#include<vector>using namespace std;int main(){    int grade = 0;    string letterGrade;    vector<string> alp = { "F", "D", "C", "B", "A", "A++"};    cout << "请输入一个成绩:" << endl;    while( cin >> grade && grade >=0 && grade <= 100 )    {        if( grade < 60 )            letterGrade = alp[0];        else        {            letterGrade = alp[ grade / 10 - 5 ];            if( grade != 100 )                if( grade % 10 <= 3 )                    letterGrade += '-';                else if( grade % 10 >=88 7 )                    letterGrade += '+';        }        cout << "你的成绩等级为:" << letterGrade << endl;        char reply;        cout << "你仍想继续输入吗?回答: Y or N" << endl;        if( cin >> reply && ( reply == 'y' || reply == 'Y' ) )            cout << "请再输入一个成绩:" << endl;        else        {            cout << "程序结束,拜" << endl;            break;        }        cin.sync();    }


练习5.6:改写上一题的程序,使用条件运算符代替if else语句。

#include<iostream>using namespace std;int main(){    int grade = 0;    cout << "请输入一个成绩:" << endl;    while( cin >> grade )    {        if( grade < 0 || grade > 100 )        {            cout << "无效成绩!" << endl;            return -1;        }        string letterGrade, postfix;        int sd, td; // single digit & tens digit        sd = grade % 10;        td = grade / 10;        letterGrade = ( td == 9 ) ? "A"                                    : ( td == 8 ) ? "B"                                                    : ( td == 7 ) ? "C"                                                                    : ( td == 6 ) ? "D" : "";        postfix = ( sd <= 3 ) ? "-"                                : ( sd >= 7 ) ? "+" : "";        letterGrade += postfix;        if( grade == 100 )            letterGrade = "A++";        if( grade < 60 )            letterGrade = "F";        cout << "你的成绩等级是:" << letterGrade << endl;        char reply;        cout << "你是否想继续输入成绩?回答:Y or N 。" << endl;        if( cin >> reply  &&  reply != 'y' && reply != 'Y'  )        {            cout << "程序结束,拜!" << endl;            break;        }        cout << "请再输入一个成绩:" << endl;        cin.sync();    }    return 0;}

练习5.7:改正下列代码中的错误。

略了。


练习5.8:什么是“悬垂else”?C++语言是怎么处理else子句的?

(标准)

答:悬垂else是指当程序中的if分支多于else分支时,如何为else寻找与之匹配的if分支的问题。

C++规定,else与离它最近的尚未匹配的if匹配,从而消除了二义性。


练习5.9:编写一段程序,使用一系列if语句统计从cin读入的文本中有多少元音字母?

#include<iostream>using namespace std;int main(){    char ch;    unsigned vowel_cnt = 0;    cout << "请输入一段文本:" << endl;    while( cin >> ch )    {        if( ch == 'a' || ch == 'A' )            ++vowel_cnt;        else if( ch == 'e' || ch == 'E' )            ++vowel_cnt;        else if( ch == 'i' || ch == 'I' )            ++vowel_cnt;        else if( ch == 'o' || ch == 'O' )            ++vowel_cnt;        else if( ch == 'u' || ch == 'U' )            ++vowel_cnt;        else            ;    }    cout << "您的输入中含有元音字母的个数为:" << vowel_cnt << endl;    return 0;}

练习5.10:我们之前的统计元音字母的程序存在一个问题:如果原因字母以大写形式出现,不会被统计在内。编写一段程序,既统计元音字母的小写形式,也统计大写形式,也就是说,新程序遇到'a'和'A'都应该递增aCnt的值,以此类推。

#include<iostream>using namespace std;int main(){    char ch;    unsigned aCnt =0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt= 0;    cout << "请输入一段文本:" << endl;    while( cin >> ch )        switch( ch )        {            case 'a':            case 'A':++aCnt;                     break;            case 'e':            case 'E':++eCnt;                     break;            case 'i':            case 'I':++iCnt;                     break;            case 'o':            case 'O':++oCnt;                     break;            case 'u':            case 'U':++uCnt;            default:;        }    cout << "元音字母a/A出现了" << aCnt << "次" << endl;    cout << "元音字母e/E出现了" << eCnt << "次" << endl;    cout << "元音字母i/I出现了" << iCnt << "次" << endl;    cout << "元音字母o/O出现了" << oCnt << "次" << endl;    cout << "元音字母u/U出现了" << uCnt << "次" << endl;    return 0;}


练习5.11:修改统计原因字母的程序,使其也能统计空格、制表符和换行符的数量。

#include<iostream>#include<string>using namespace std;int main(){    char ch;    unsigned aCnt =0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt= 0;    unsigned space_Cnt = 0, t_Cnt = 0, n_Cnt = 0; //t means \t, n means \n;    cout << "请输入一段文本:" << endl;    /* cin会自动过滤掉不可见字符     * 所以采用 cin.get(ch) 而不是用cin >> ch     * 或者使用 cin >> noskipws >> ch;    */    while( cin.get( ch ) )        switch( ch )        {            case 'a':            case 'A':++aCnt;                     break;            case 'e':            case 'E':++eCnt;                     break;            case 'i':            case 'I':++iCnt;                     break;            case 'o':            case 'O':++oCnt;                     break;            case 'u':            case 'U':++uCnt;                     break;            case ' ':++space_Cnt;                     break;            case '\t':++t_Cnt;                     break;            case '\n':++n_Cnt;            default:;        }    cout << "元音字母a/A出现了" << aCnt << "次" << endl;    cout << "元音字母e/E出现了" << eCnt << "次" << endl;    cout << "元音字母i/I出现了" << iCnt << "次" << endl;    cout << "元音字母o/O出现了" << oCnt << "次" << endl;    cout << "元音字母u/U出现了" << uCnt << "次" << endl;    cout << "空格出现了" << space_Cnt << "次" << endl;    cout << "制表符出现了" << t_Cnt << "次" << endl;    cout << "换行符出现了" << n_Cnt << "次" << endl;    return 0;}

练习5.12:修改统计元音字母的程序,使其能统计以下含有两个字符的字符的字符序列的数量:ff、fl和fi 。

#include<iostream>using namespace std;int main(){    bool first_f = 0;    char ch, last_ch;    unsigned aCnt =0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt= 0;    unsigned ff_Cnt = 0, fl_Cnt = 0, fi_Cnt = 0;    unsigned space_Cnt = 0, t_Cnt = 0, n_Cnt = 0; //t means \t, n means \n;    cout << "请输入一段文本:" << endl;    /* cin会自动过滤掉不可见字符     * 所以采用 cin.get(ch) 而不是用cin >> ch     * 或者使用 cin >> noskipws >> ch;    */    while( cin.get( ch ) )    {       switch( ch )        {            case 'a':            case 'A':++aCnt;                     break;            case 'e':            case 'E':++eCnt;                     break;            case 'i':                if( last_ch == 'f' && first_f )                {                    ++fi_Cnt;                    first_f = 0;                }            case 'I':++iCnt;                     break;            case 'o':            case 'O':++oCnt;                     break;            case 'u':            case 'U':++uCnt;                     break;            case 'f':                if( first_f )                {                    if( last_ch == 'f' )                    {                        ++ff_Cnt;                        first_f = 0;                    }                }                else                    first_f = 1;                break;            case 'l':                if( last_ch == 'f' && first_f )                 {                    ++fl_Cnt;                    first_f = 0;                 }            case ' ':++space_Cnt;                     break;            case '\t':++t_Cnt;                     break;            case '\n':++n_Cnt;            default:;        }        last_ch = ch;    }    cout << "元音字母a/A出现了" << aCnt << "次" << endl;    cout << "元音字母e/E出现了" << eCnt << "次" << endl;    cout << "元音字母i/I出现了" << iCnt << "次" << endl;    cout << "元音字母o/O出现了" << oCnt << "次" << endl;    cout << "元音字母u/U出现了" << uCnt << "次" << endl;    cout << "空格出现了" << space_Cnt << "次" << endl;    cout << "制表符出现了" << t_Cnt << "次" << endl;    cout << "换行符出现了" << n_Cnt << "次" << endl;    cout << "ff出现了" << ff_Cnt << "次" << endl;    cout << "fl出现了" << fl_Cnt << "次" << endl;    cout << "fi出现了" << fi_Cnt << "次" << endl;    return 0;}




练习5.13:下面显示的每个程序都含有一个常见的编译错误,指出错误在哪里,然后修改它们。

略了。


练习5.14:编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词。所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应的单词。如果这样的单词存在,输出重复出现的最大次数;如果不存在,输出一条信息说明任何单词都没有连续出现过。

#include<iostream>using namespace std;int main(){    string currStr, preStr = "", maxStr;    unsigned cnt = 1, maxcnt = 0;    cout << "请输入多个字符串:" << endl;    while( cin >> currStr )    {        if( currStr == preStr )        {            ++cnt;            if( cnt > maxcnt )            {                maxcnt = cnt;                maxStr = currStr;            }        }        else        {            preStr = currStr;            cnt = 1;        }    }    if( cnt != 1)        cout << "连续重复出现最大次数的单词是:" << maxStr << ",它出现了"             << maxcnt << "次" << endl;    else    {        cout << "没有任何单词重复出现过!" << endl;        return -1;    }    return 0;}

练习5.15:说明下列循环的含义并改正其中的错误。

略了。


练习5.16:while循环特别适用于那种条件保持不变、反复执行操作的情况,例如,当未达到文件末尾时不断读取下一个值。for循环则更像是在按步骤迭代,它的索引值在某个范围内依次变化。根据每种循环的习惯各自编写一段程序,然后分别用另一种循环改写。如果只能使用一种循环, 你倾向于使用哪种呢?为什么?

答:大多情况下,两种循环能够相互转换。如果只用一种,倾向于使用for循环,for循环结构严谨,便于控制程序的逻辑。


练习5.17:假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。为了实现这一目标,对于两个不等长的vector对象,只需挑出长度较短的那个,把它的所有元素和另一个vector对象比较即可。例如:如果两个vector对象的元素分别是0、1、1、2和0、1、1、2、3、5、8,则程序返回结果应该为真。

#include<iostream>#include<vector>using namespace std;void IsPrefix( vector<int> &v1, vector<int> &v2 );int main(){    vector<int> ivec1, ivec2;    int iData = 0;    cout << "请分别为两个容器输入数据:" << endl;    cout << "容器1: " ;    while( cin >> iData )        ivec1.push_back( iData );    cout << endl;    cin.clear();    cin.sync();    cout << "容器2:" << endl;    while( cin >> iData )        ivec2.push_back( iData );    cout << endl;    IsPrefix( ivec1, ivec2 );    return 0;}void IsPrefix( vector<int> &v1, vector<int> &v2 ){    vector<int>::size_type len;    len = ( ( v1.size() < v2.size() )? v1.size() : v2.size() );    decltype( len ) i;    for( i = 0; i != len; ++i )        if( v1[i] != v2[i] )            break;    if( len == v1.size() && i == len )        cout << "容器1是容器2的前缀。" << endl;    else if( len == v2.size() && i == len )        cout << "容器2是容器1的前缀。" << endl;    else        cout << "容器1和容器2互不为对方前缀。" << endl;}

练习5.18:说明下列循环的含义并改正其错误。

略了。


练习5.19:编写一段程序,使用do-while循环重复地执行下述任务:首先提示用户输入两个string对象,然后挑出较短的那个并输出它。

#include<iostream>using namespace std;int main(){    string str1, str2;    do    {        cout << "请输入两个字符串:" << endl;        cin >> str1 >> str2;        if( str1.size() < str2.size() )            cout << "较短的字符串为:" << str1 <<endl;        else if( str1.size() > str2.size() )            cout << "较短的字符串为:" << str2 << endl;        else            cout << str1 << "和" << str2 << "等长" << endl;    }    while( cin );    return 0;}

练习5.20:编写一段程序,从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有单词读完为止。
#include<iostream>using namespace std;int main(){    string word, lastWord;    bool Exist = 0;    cout << "请输入多个单词:" << endl;    while( cin >> word )    {        if( word == lastWord )        {            Exist = true;            break;        }        lastWord = word;    }    if( !Exist )    {       cout << "不存在连续重复重现的单词。" << endl;       return -1;    }    cout << "连续重复出现的单词是:" << word << endl;    return 0;}


练习5.21:修改5.5.1节练习题的程序,使其找到的重复单词必须以大写字母开头。

#include<iostream>#include<cctype>using namespace std;int main(){    string word, lastWord;    bool Exist = 0;    cout << "请输入多个单词:" << endl;    while( cin >> word )    {        if( word == lastWord && isupper( word[0] ) )        {            Exist = true;            break;        }        lastWord = word;    }    if( !Exist )    {       cout << "不存在连续重复重现的首字母大写的单词。" << endl;       return -1;    }    cout << "连续重复出现的首字母大写的单词是:" << word << endl;    return 0;}



练习5.22:本节的最后一个例子跳回到begin,其实使用循环能更好地完成该任务。重写这段代码,注意不再使用goto语句。
int sz;

do

sz = get_size();

while( sz <= 0 );



练习5.23:编写一段程序,从标准输入读取两个整数,输出第一个数除以第二个数的结果。

略了。


练习5.24:修改你的程序,使得当第二个数是0时抛出异常。先不要设定catch子句,运行程序并真的为除数输入0,看看会发生什么?

#include<iostream>#include<stdexcept>using namespace std;int main(){    int iva1,iva2;    cout << "请依次输入一个被除数和除数:" << endl;    cin >> iva1 >> iva2;    if( iva2 == 0 )        throw runtime_error( "除数不能为0" );    cout << iva1 << "除以" << iva2 << "的结果为:"         << iva1 / iva2 << endl;    return 0;}


练习2.25:修改上一题的程序,使用try语句块去捕获异常。catch子句应该为用户输出一条提示信息,询问其是否输入新数并重新执行try语句块的内容。

#include<stdexcept>using namespace std;int main(){    int iva1,iva2;    cout << "请依次输入一个被除数和除数:" << endl;    while( cin >> iva1 >> iva2 )    {        try{            if( iva2 == 0 )                throw runtime_error( "除数不能为0" );            cout << iva1 << "除以" << iva2 << "的值为:"                 << iva1 / iva2 << endl;        }catch( runtime_error err ){            cout << err.what() << endl;            cout << "Try again? Enter y or n" << endl;            char c;            cin >> c;        if( !cin || c == 'n' )            break;        }        cout << "请依次输入一个被除数和除数:" << endl;    }    return 0;}



原创粉丝点击