C++ Primer第5版 第五章课后练习答案

练习5.1

空语句只包含有一个单独的分号,如果在程序的某个地方,语法上需要一条语句但逻辑上不需要,应使用空语句。

练习5.2

指用花括号括起来的语句和声明的序列。如果在程序的某个地方,语法上需要一条语句但逻辑上需要多条,则用块。

练习5.3

#include <iostream>

int main()
{
    int sum = 0, val = 50;
    while (val <= 100) 
        sum += val, ++val;
    
    std::cout << "Sum of 50 to 100 inclusive is " << sum << std::endl;
    return 0;
}
#include <iostream>

int main()
{
    int val = 10;
    while (val >= 0) 
        std::cout << val << std::endl, --val;
    return 0;
}
#include <iostream>

int main()
{
    std::cout << "Please enter the two integers" << std::endl;
    int start, end;
    //我这里没有对传入格式进行判断,如果大家有需要可以添加这个功能
    std::cin >> start >> end;
    if (start > end) {
        std::swap(start, end);
    }
    while (start <= end) 
        std::cout << start << std::endl,++start;    
    return 0;
}

可读性降低了。

练习5.4

(a)while语句不断循环,直到迭代器指向尾后迭代器。

(b)find()函数返回值赋给变量status,若所赋值为真则不断循环,因此退出循环后的status必为假。

练习5.5

int main()
{
    int grade;
    cin >> grade;
    const vector<string> scores = { "F","D","C","B","A","A++" };
    string lettergrade;
    if (grade < 60)
        lettergrade = scores[0];
    else
        lettergrade = scores[(grade - 50) / 10];
    cout << lettergrade;
}

练习5.6

int main()
{
    int grade;
    cin >> grade;
    const vector<string> scores = { "F","D","C","B","A","A++" };
    string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10];
    cout << lettergrade;
}

练习5.7

(a)

int ival1, ival2;
if (ival1 != ival2)
    ival1 = ival2;//少了分号
else ival1 = ival2 = 0;

(b)

if (ival1 < minval)
    minval=ival1;
    occurs = 1;//因为没有花括号将两句组成复合语句因此occurs必然在条件语句结束后执行

(c)

if (int ival = get_value())
    cout << "ival = " << ival << endl;
if (!ival)
    cout << "ival = 0
";        
// 第二个if中的ival未定义,ival的作用域仅限于第一个if循环中

(d)

if (ival = 0)
    ival = get_value();            
// if中的判断应写为 if (0 == ival),因为ival会将所赋的值当作判断条件,此时if语句必然失败

练习5.8

“悬垂else”:我们怎么知道某个给定的else是和哪个if匹配呢?C++规定else与离它最近的尚未匹配的if匹配

练习5.9

char ch;
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
while (cin >> ch) {
    if(ch=='a')
        ++aCnt;
    else if(ch=='e')
        ++eCnt;
    else if (ch=='i')
        ++iCnt;
    else if (ch=='o')
        ++oCnt;
    else if (ch=='u')
        ++uCnt;       
}

练习5.10

unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
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;
        break;
    default:
        break;
    }
}

练习5.11

char ch;
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, tableCnt = 0, rowCnt = 0;
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;
        break;
    case' ':
        ++spaceCnt;
        break;
    case'	':
        ++tableCnt;
        break;
    case'
':
        ++rowCnt;
        break;
    default:
        break;
    }
}

练习5.12

char ch,ch_before=' ';
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0;
while (cin >> ch) {
    switch (ch)
    {
    case'a':case'A':
        ++aCnt;
        break;
    case'e':case'E':
        ++eCnt;
        break;
    case'i':
        if (ch_before == 'f')
            ++fiCnt;
    case'I':
        ++iCnt;
        break;
    case'o':case'O':
        ++oCnt;
        break;
    case'u':case'U':
        ++uCnt;
        break;
    case'f':
        if(ch_before=='f')
        ++ffCnt;
        break;
    case'l':
        if (ch_before == 'f')
            ++flCnt;
        break;
    default:
        break;
    }
    ch_before = ch;
}

练习5.13

(a)少加break,导致程序执行匹配成功的标签代码后跨越case边界执行其他代码

(b)控制流可能绕过一个在作用域内初始化的变量

(c)case标签必须是整型常量表达式,不能用,代替case 1:case 2:

(d)case标签必须是整型常量表达式

练习5.14

int main()
{
    string str,str_before,max_str;
    unsigned strCnt = 0, flag = 0;
    while (cin >> str) {
        if (str == str_before)
            ++strCnt;
        else {
            if (strCnt > 1 && strCnt > flag) {
                max_str = str;
                flag = strCnt;
            }
            strCnt = 1;
        }
        str_before = str;
    }
    if (flag) {
        cout << "不存在重复出现的单词" << endl;
    }
    else {
        cout << str << " " << strCnt << endl;
        flag = true;
    }
}

练习5.15

(a):ix应该在循环外定义

(b):缺少一个;号,没有初始化ix

(c):++sz,永远也结束不了

练习5.16

我更倾向于使用for循环,因为for循环比较简洁

练习5.17

template <typename T>
bool compare(vector<T> const& a, vector<T> const& b)
{
    auto size = b.size();
    if (a.size() < b.size()) {
        size = a.size();
    }
    for (decltype(size) i = 0; i < size; i++) {
        if (a[i] != b[i])return false;
    }
    return true;
}

练习5.18

(a):打印语句,然后传入两个值并输出两个值的和。do后面那么多条语句,需要使用花括号

(b):因为do循环体中肯定还需要使用到ival这个变量,所以应该将其定义在循环体外部

(c):同上

练习5.19

do {
    string v1, v2;
    cout << "Please input two string" << endl;
    if (cin >> v1 >> v2)
        cout << (v1.size() > v2.size() ? v2 : v1) << endl;
} while (cin);

练习5.20

int main()
{
    string  str, str_pre;
    bool flag = false;
    do{    
        cin >> str;
        if (str==str_pre) {
            cout << str;
            break;
        }
        str_pre = str;
    } while (cin);
    if (flag)cout << "没有任何单词是连续重复出现的" << endl;
}

练习5.21

int main()
{
    string  str, str_pre;
    bool flag = false;
    do{    
        cin >> str;
        if (str==str_pre&&isupper(str_pre.at(0))) {
            cout << str;
            break;
        }
        str_pre = str;
    } while (cin);
    if (flag)cout << "没有任何单词是连续重复出现的" << endl;
}

练习5.22

int sz;
do {
    sz = get_size();

} while (sz <= 0);

练习5.23

int num1,num2;
while (cin >> num1 >> num2) {
    cout << num1 / num2 << endl;
} 

练习5.24

int main()
{
    int num1,num2;
    while (cin >> num1 >> num2) {
        if (num2 == 0)throw std::runtime_error("被除数不能为0");
        cout << num1 / num2 << endl;
    } 
}

练习5.25

int main()
{
    int num1,num2;
    while (cin >> num1 >> num2) {      
        try
        {
            if (num2 == 0)throw std::runtime_error("除数不能为0");
            cout << static_cast<double>(num1) / num2 << endl;
        }
        catch (std::runtime_error err)
        {
            cout << err.what();
            cout << "
是否需要重新输入? Enter y or n:" << endl;
            char c;
            cin >> c;
            if (!cin || c == 'n')
                break;
        }  
    } 
}