《C++ Primer》第5章 5.5节习题答案

《C++ Primer》第5章 语句

5.5节 跳转语句

练习5.15:说明下列循环的含义并改正其中的错误。
(a)    for(int ix = 0; ix != sz; ++ix) { /* ... */}
        if(ix != sz)
        // ...
(b)    int ix;
        for(ix != sz; ++ix) { /* ... */ }
(c)    for(int ix = 0; ix != sz; ++ix, ++sz) { /* ... */ }
【出题思路】
理解for循环的语法规则,特别是for循环控制结构中三条语句的作用。理解循环控制变量与循环终止条件的关系,从而能够判断循环是否会无限执行下去。
【解答】
(a)的错误是在for语句中定义了变量ix,然后试图在for语句之外继续使用ix。因为ix定义在for语句的内部,所以其作用域仅限于for语句。在if语句中ix已经失效,因此程序无法编译通过。修改后的程序如下:
int ix;
for(ix = 0; ix != sz; ++ix) { /* ... */}
if(ix != sz)
// ...
(b)的错误有两个,一是变量ix未经初始化就直接使用,二是for语句的控制结构缺少一句话,在语法上是错误的。修改后的程序如下:
int ix;
for(ix = 0; ix != sz; ++ix) { /* ... */ }
(c)的错误是一旦进入循环,程序就会无休止地执行下去。也就是说,当初始情况下ix != sz时,由题意可知ix和sz一直同步增长,循环的终止条件永远不会满足,所以该循环是一个死循环。修改后的程序如下:
for(int ix = 0; ix != sz; ++ix) { /* ... */ }

练习5.16:while循环特别适用于那种条件保持不变、反复执行操作的情况,例如,当未达到文件末尾时不断读取下一个值。for循环则更像是在按步骤迭代,它的索引值在某个范围内依次变化。根据每种循环的习惯用法各自编写一段程序,然后分别用另一种循环改写。如果只能使用一种循环,你倾向于使用哪种呢?为什么?
【出题思路】
一般情况下,while循环和for循环可以互相转换,不论哪种循环形式关键点都有三个:循环控制变量的初始值、循环控制变量的变化规则、循环终止条件。编写循环语句时除了要满足应用需求,还必须时刻关注循环控制变量和循环终止条件,谨防写出死循环。
【解答】
从标准输入流读取数据的程序一般使用while循环,其形式是:

#include <iostream>

using namespace std;

int main()
{
    int forCount = 0;
    for(int i = 0; i < 10; ++i)
    {
        forCount += i;
    }
    cout << "forCount=============" << forCount << endl;;
    
    int whileCount = 0, j = 0;
    while(j < 10)
    {
        whileCount += j;
        ++j;
    }
    cout << "whileCount============" << whileCount << endl;
    
    return 0;
}

运行结果:

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

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v1 = {0, 1, 1, 2};
    vector<int> v2 = {0, 1, 1, 2, 3, 5, 8};
    vector<int> v3 = {3, 5, 8};
    vector<int> v4 = {3, 5, 0, 9, 2, 7};
    
    auto it1 = v1.cbegin();   //定义v1的迭代器
    auto it2 = v2.cbegin();   //定义v2的迭代器
    auto it3 = v3.cbegin();   //定义v3的迭代器
    auto it4 = v4.cbegin();   //定义v4的迭代器
    
    //设定循环条件:v1和v2都尚未检查完
    while(it1 != v1.cend() && it2 != v2.cend())
    {
        //如果当前位置的两个元素不相等,则肯定没有前缀关系,退出循环
        if(*it1 != *it2)
        {
            cout << "v1和v2之间不存在前缀关系" << endl;
            break;
        }
        ++it1;  //迭代器移动到下一个元素
        ++it2;  //迭代器移动到下一个元素
    }
    if(it1 == v1.cend())   //如果v1较短
    {
        cout << "v1是v2的前缀" << endl;
    }
    
    if(it2 == v2.cend())   //如果v2较短
    {
        cout << "v2是v1的前缀" << endl;
    }
    //v3 v4之间不存在前缀关系
    return 0;
}

运行结果:

 

练习5.18:说明下列循环的含义并改正其中的错误。
(a)    do
        int v1, v2;
        cout << "Please enter two numbers to sum:";
        if(cin >> v1 >> v2)
            cout << "Sum is:" << v1 + v2 << endl;
        while(cin);
(b)    do {
        // ...
    }while(int ival = get_response());
(c)    do {
        int ival = get_response();
    }while(ival);
【出题思路】
理解do-while循环的语法规则。do-while与while的最主要区别是:do-while语句至少会执行一次循环体;而while有可能一次都不执行循环体。
【解答】
(a)的含义是每次循环读入两个整数并输出它们的和。因为do-while语句的循环体必须是一条语句或者一个语句块,所以在本题中应该把循环体的内容用花括号括起来。修改后的程序是:
do {
    int v1, v2;
    cout << "Please enter two numbers to sum:";
    if(cin >> v1 >> v2)
        cout << "Sum is:" << v1 + v2 << endl;
}while(cin);
(b)的含义是当get_response的返回值不为0时执行循环体。因为do-while语句不允许在循环条件内定义变量,所以该程序是错误的。修改后的程序是:
int ival;
do {
    ival = get_response()
}while(ival);
(c)的含义是当get_response的返回值不为0时执行循环体。因为出现在do-while语句条件部分的变量必须定义在循环体之外,所以该程序是错误的。修改后的程序是:
int ival;
do {
    ival = get_response();
}while(ival);

练习5.19:编写一段程序,使用do-while循环重复地执行下述任务:首先提示用户输入两个string对象,然后挑出较短的那个并输出它。
【出题思路】
把题目要求的任务写在do-while循环体中即可,该程序至少会执行一次比较操作。把字符串定义成string对象,调用size函数即可得到string对象的长度。
【解答】
满足题意的程序如下所示:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    do{
        cout << "请输入两个字符串:" << endl;
        string str1, str2;
        cin >> str1 >> str2;
        if(str1.size() < str2.size())
            cout << "长度较小的字符串是:" << str1 << endl;
        else if(str1.size() > str2.size())
            cout << "长度较小的字符串是:" << str2 << endl;
        else
            cout << "两个字符串等长" << endl;
        
    }while(cin);
    
    return 0;
}

运行结果:

练习5.20:编写一段程序,从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次时使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有任何单词是连续重复出现的。
【出题思路】
break语句是一种跳转语句,负责终止离它最近的while、do-while、for和switch语句,并把程序的控制权交给这些语句之后的第一条语句。
【解答】
满足题意的程序如下所示:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string currString, preString;
    bool b1 = true;
    cout << "请输入一组字符串:" << endl;
    while(cin >> currString)
    {
        if(currString == preString)
        {
            b1 = false;
            cout << "连续出现的字符串是:" << currString << endl;
            break;
        }
        preString = currString;
    }
    
    if(b1)
        cout << "没有连续出现的字符串" << endl;
    
    return 0;
}

运行结果:

 练习5.21:修改5.5.1节(第171页)练习题的程序,使其找到的重复单词必须以大写字母开头。
【出题思路】
continue语句是一种跳转语句,负责终止最近的循环中的当前迭代并立即开始下一次迭代。与break语句的区别是,continue虽然终止了当前迭代,但是并不终止循环;而break语句则直接跳出循环。
【解答】
根据题目的要求,我们首先检查读入的单词是否以大写字母开头,如果不是则终止当前迭代并开始下一次循环。满足题意的程序是:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string currString, preString;
    bool b1 = true;
    cout << "请输入一组字符串:" << endl;
    while(cin >> currString)
    {
        if(currString == preString)
        {
            b1 = false;
            cout << "连续出现的字符串是:" << currString << endl;
            break;
        }
        preString = currString;
    }
    
    if(b1)
        cout << "没有连续出现的字符串" << endl;
    
    return 0;
}

运行结果:

 

练习5.22:本节的最后一个例子跳回到begin,其实使用循环能更好地完成该任务。重写这段代码,注意不再使用goto语句。
【出题思路】
goto语句的作用是从goto语句无条件跳转到同一函数的另一条语句。但是一般情况下,不建议读者使用goto语句,因为它使得程序既难理解又难修改。
【解答】
用do-while语句改写后的程序如下所示:
int sz;
do{
    sz = get_size();
}while(sz <= 0);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值