【C++Primer练习】第5章 语句·

练习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;
    system("pause");
    return 0;
}

可读性降低。

练习5.4

说明下列例子的含义,如果存在问题,试着修改

(a)while(string::iterator iter != s.end()){/*...*/}
(b)while(bool status=find(word)){/*...*/}
		if(!status){/*...*/}

(a)控制结构中定义的变量需要初始化,修改:

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

(b)status定义在while块内,跳出while以后就被销毁,不能够被if使用,修改:

bool status=find(word);
while(status){/*...*/}
if(!status){/*...*/}

练习5.5

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

#include <iostream>
#include <vector>
#include <string>
using std::cin;
using std::cout;
using std::string;
using std::vector;
int main()
{
    const vector<string> scores = {"F", "E", "D", "C", "B", "A", "A++"};
    int grade = 0;
    cin >> grade;
    string lettergrade;
    if (grade < 60)
        lettergrade = scores[0];
    else
    {
        lettergrade = scores[(grade - 50) / 10];
        if (grade != 100)
        {
            if (grade % 10 > 7)
                lettergrade += '+';
            else if (grade % 10 < 3)
                lettergrade += '-';
        }
    }
    cout << "numgrade: " << grade << ", lettergrade: " << lettergrade;
    system("pause");
    return 0;
}

练习5.6

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

#include <iostream>
#include <vector>
#include <string>
using std::cin;
using std::cout;
using std::string;
using std::vector;
int main()
{
    const vector<string> scores = {"F", "E", "D", "C", "B", "A", "A++"};
    int grade = 0;
    cin >> grade;
    string lettergrade;
    (grade < 60) ? lettergrade = scores[0] : lettergrade = scores[(grade - 50) / 10];
    if (grade != 100)
    {
        (grade % 10 > 7) ? lettergrade += '+' : (grade % 10 < 3) ? lettergrade += '-'
                                                                 : lettergrade = lettergrade;
    }

    cout << "numgrade: " << grade << ", lettergrade: " << lettergrade;
    system("pause");
    return 0;
}

练习5.7

改写下列代码段的错误。

(a) if(ival1!=ival2)
		ival1=ival2
	else ival1=ival2=0;
(b) if(ival<minval)
		minval=ival;
		occurs=1;
(c) if(int ival=get_value())
		cout<<"ival="<<ival<<endl;
	if(!ival)
		cout<<"ival=0\n";
(d) if(ival=0)
		ival=get_value();

(a)if后面的语句缺少分号,不合法:

if(ival1!=ival2)
		ival1=ival2;
else ival1=ival2=0;

(b)根据缩进来看是想要判断if为真后执行后面两条语句,但没有包含在花括号内,导致无论if判断是何结果都将执行occurs=1。

if(ival<minval){
	minval=ival;
	occurs=1;
}	

(c)ival定义在第一个if中,退出该if后ival就销毁了不能再被第二个if使用。

int ival=get_value();
if(ival)
	cout<<"ival="<<ival<<endl;
if(!ival)
	cout<<"ival=0\n";

(d)if条件中将0赋值给ival,然后判断if(ival)将始终为假。

if(ival==0)
	ival=get_value();

练习5.8

什么是“悬垂else”?C++如何处理else子句?

当使用if语句嵌套时,可能出现if分支多于else分支,会出现else不知道匹配的是哪一个if的问题,这就是“悬垂else”;C++规定else与离它最近的未匹配的if相匹配。

练习5.9

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

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
int main()
{
    int aCnt = 0, oCnt = 0, eCnt = 0, iCnt = 0, uCnt = 0;
    char c;
    while (cin >> c)
    {
        if (c == 'a')
            aCnt++;
        else if (c == 'o')
            oCnt++;
        else if (c == 'e')
            eCnt++;
        else if (c == 'i')
            iCnt++;
        else if (c == 'u')
            uCnt++;
        cin.ignore();
        if (cin.get() == '\n')
            break;
    }
    cout << "a count: " << aCnt << endl;
    cout << "o count: " << oCnt << endl;
    cout << "e count: " << eCnt << endl;
    cout << "i count: " << iCnt << endl;
    cout << "u count: " << uCnt << endl;
    system("pause");
    return 0;
}

练习5.10

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

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
int main()
{
    int aCnt = 0, oCnt = 0, eCnt = 0, iCnt = 0, uCnt = 0;
    char c;
    while (cin >> c)
    {
        switch (c)
        {
        case 'A':
        case 'a':
            aCnt++;
            break;
        case 'O':
        case 'o':
            oCnt++;
            break;
        case 'E':
        case 'e':
            oCnt++;
            break;
        case 'I':
        case 'i':
            oCnt++;
            break;
        case 'U':
        case 'u':
            oCnt++;
            break;
        }
        cin.ignore();
        if (cin.get() == '\n')
            break;
    }
    cout << "a count: " << aCnt << endl;
    cout << "o count: " << oCnt << endl;
    cout << "e count: " << eCnt << endl;
    cout << "i count: " << iCnt << endl;
    cout << "u count: " << uCnt << endl;
    system("pause");
    return 0;
}

== 练习5.11==

修改统计元音字母的程序,使其也能统计空格、制表符、和换行符的数量。

练习5.12

修改统计元音字母的程序,使其能统计以下含有两个字符的字符序列的数量。

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
/*
输入输出:
24
flxwrffwrwfieffffffxspfl
ff count: 6
fi count: 1
fl count: 2
*/

int main()
{
    int ffCnt = 0, fiCnt = 0, flCnt = 0;
    int length = 0;                     //输入字符序列长度
    char c;
    bool f_flag = false;
    cin >> length;
    for (int i = 0; i < length; ++i)
    {
        cin >> c;
        if (f_flag)
        {
            switch (c)
            {
            case 'f':
                ++ffCnt;
                f_flag = false;
                break;
            case 'i':
                ++fiCnt;
                break;
            case 'l':
                ++flCnt;
                break;
            default:
                f_flag = false;
                break;
            }
        }
        else
        {
            if (c == 'f')
                f_flag = true;
        }
    }
    cout << "ff count: " << ffCnt << endl;
    cout << "fi count: " << fiCnt << endl;
    cout << "fl count: " << flCnt << endl;
    system("pause");
    return 0;
}

练习5.13

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

(a) unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
    char ch = next_text();
    switch (ch) {
        case 'a': aCnt++;
        case 'e': eCnt++;
        default: iouCnt++;
    }
(b) unsigned index = some_value();
    switch (index) {
        case 1:
            int ix = get_value();
            ivec[ ix ] = index;
            break;
        default:
            ix = ivec.size()-1;
            ivec[ ix ] = index;
    }
(c) unsigned evenCnt = 0, oddCnt = 0;
    int digit = get_num() % 10;
    switch (digit) {
        case 1, 3, 5, 7, 9:
            oddcnt++;
            break;
        case 2, 4, 6, 8, 10:
            evencnt++;
            break;
    }
(d) unsigned ival=512, jval=1024, kval=4096;
    unsigned bufsize;
    unsigned swt = get_bufCnt();
    switch(swt) {
        case ival:
            bufsize = ival * sizeof(int);
            break;
        case jval:
            bufsize = jval * sizeof(int);
            break;
        case kval:
            bufsize = kval * sizeof(int);
            break;
    }

(a)缺乏break,将按序执行对应case label之后所有的语句。

unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch (ch) {
    case 'a': aCnt++;break;
    case 'e': eCnt++;break;
    default: iouCnt++;break;
}

(b)case1之后定义的int ix不能在case 2中使用

unsigned index = some_value();
int ix=0;
switch (index) {
	case 1:
      	ix = get_value();
      	ivec[ ix ] = index;
      	break;
   	default:
      	ix = ivec.size()-1;
      	ivec[ ix ] = index;
}

(c)case-label书写不正确

unsigned evenCnt = 0, oddCnt = 0;
int digit = get_num() % 10;
switch (digit) {
	case 1:case 3:case 5:case 7:case 9:
		oddcnt++;
		break;
	case 2:case 4:case 6:case 8:case 10:
		evencnt++;
		break;
}

(d)case label必须是整型常量表达式。

unsigned ival=512, jval=1024, kval=4096;
unsigned bufsize;
unsigned swt = get_bufCnt();
switch(swt) {
	case 512:
		bufsize = ival * sizeof(int);
		break;
	case 1024:
		bufsize = jval * sizeof(int);
		break;
	case 4096:
		bufsize = kval * sizeof(int);
		break;
}

练习5.14

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main()
{
    string now_str;
    string last_str;
    string max_str;
    int nowCnt = 0;
    int maxCnt = 0;
    while (cin >> now_str)
    {
        if (now_str == last_str)
            ++nowCnt;
        else
            nowCnt = 1;
        if (nowCnt > maxCnt)
        {
            maxCnt = nowCnt;
            max_str = now_str;
            cout << max_str << endl;
        }
        last_str = now_str;
        if (cin.get() == '\n')
            break;
    }
    if (maxCnt)
        cout << "单词" << max_str << "出现次数最多," << maxCnt << "次";
    else
        cout << "没有单词连续出现";
    system("pause");
    return 0;
}

练习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}{/*...*/}

(a)ix在for循环条件中声明并初始化,作用域仅在该for循环中,所以if不能再使用ix。

int ix;
for(ix=0;ix!=sz;++ix)/*...*/}
if(ix!=sz)
	//...

(b)for循环中init-statement可以省略但是必须用空语句表示。

int ix;
for(;ix!=sz;++ix){/*...*/}

(c)如果sz的初始值不为0,不会进入该循环;如果sz的初始值为0,sz和ix同时++,则永远不会出现ix!=sz,该循环将成为一个无穷循环。

练习5.16

while 循环特别适用于那种条件不变、反复执行操作的情况,例如,当未达到文件末尾时不断读取下一个值。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 std::cin;
using std::cout;
using std::endl;
using std::vector;
int main()
{
    vector<int> v1 = {0, 1, 1, 2};
    vector<int> v2 = {0, 1, 1, 2, 3, 5, 8};
    int length = (v1.size() < v2.size() ? v1.size() : v2.size());
    int flag = true;
    for (int i = 0; i < length; ++i)
    {
        if (v1[i] != v2[i])
            flag = false;
    }
    if (flag)
        cout << "true" << endl;
    else
        cout << "false" << endl;
    system("pause");
    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);

(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)condition中不可以定义变量

int ival=get_response();
do{
	//...
}while(ival);

(c)ival定义在do的块内,也就是do执行完以后,ival就被销毁了,条件语句中不能够再使用。

int ival;
do{
	int ival=get_response();
}while(ival);

练习5.19

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
/*样例:
You can enter 'q' to quit.
Please enter two string:
hello
cpp
The shorter one is: cpp
Please enter two string:
cpp
primer
The shorter one is: cpp
Please enter two string:
q
Done!
*/
int main()
{
    string str1, str2;
    cout << "You can enter 'q' to quit." << endl;
    do
    {
        cout << "Please enter two string: \n";
        cin >> str1;
        if (!(str1 == "q"))
        {
            cin >> str2;
            cout << "The shorter one is: ";
            if (str1.size() < str2.size())
                cout << str1 << endl;
            else
                cout << str2 << endl;
        }
        else
            break;
    } while (cin.get() != 'q');
    cout << "Done!" << endl;
    system("pause");
    return 0;
}

练习5.20

编写一段程序,从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有的单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次时使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有任何单词是连续重复出现的。

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
/*样例:
i: hello world hello hello
o: hello

i: hello
o: No word is repeated.
*/
int main()
{
    string last_str, now_str;
    bool r_flag = false;
    while (cin >> now_str)
    {
        if (now_str != last_str)
            last_str = now_str;
        else if (now_str == last_str)
        {
            r_flag = true;
            break;
        }
        if (cin.get() == '\n')
            break;
    }
    if (r_flag)
        cout << now_str;
    else
        cout << "No word is repeated.";
    system("pause");
    return 0;
}

练习5.21

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
/*样例:
i: apple apple
o: No word is repeated.

i: hello
o: No word is repeated.

i: Apple apple Orange Orange
o: Orange
*/
int main()
{
    string last_str, now_str;
    bool r_flag = false;
    char boundary = 'a';
    while (cin >> now_str)
    {
        if (now_str != last_str)
            last_str = now_str;
        else if (now_str == last_str)
        {
            if (now_str[0] < boundary)
            {
                r_flag = true;
                break;
            }
            last_str = now_str;
        }
        if (cin.get() == '\n')
            break;
    }
    if (r_flag)
        cout << now_str;
    else
        cout << "No word is repeated.";
    system("pause");
    return 0;
}

练习5.22

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

do{
	sz=get_size();
}while(size<=0);

练习5.23

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;

/*样例:
i: 20 10
o: 2
*/
int main()
{
    int a, b;
    cin >> a >> b;
    cout << a / b;
    system("pause");
    return 0;
}

在原程序中,输入:10 0,报错如下:
在这里插入图片描述

练习5.24

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;

int main()
{
    int a, b;
    cin >> a >> b;
    if (b == 0)
        throw std::runtime_error("b不能为0");
    cout << a / b;
    system("pause");
    return 0;
}

输入:10 0后程序直接退出

练习5.25

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

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
/*样例
i: 10 0
o: 除数不得为0
   再来一次吗?输入y或者n
   y
   20 10
   2
*/
int main()
{
    int a, b;
    while (cin >> a >> b)
    {
        try
        {
            if (b == 0)
                throw std::runtime_error("除数不得为0");
            cout << a / b << endl;
        }
        catch (std::runtime_error err)
        {
            cout << err.what() << endl;
            cout << "再来一次吗?输入y或者n" << endl;
            char c;
            cin >> c;
            if (!cin || c == 'n')
                break;
            else
                continue;
        }
        if (cin.get() == '\n')
            break;
    }
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值