C++ Primer 第 5 版 第 5 章习题答案

文章目录

  • 5.1
  • 5.2
  • 5.3
  • 5.4
  • 5.5
  • 5.6
  • 5.7
  • 5.8
  • 5.9
  • 5.10
  • 5.11
  • 5.12
  • 5.13
  • 5.14
  • 5.15
  • 5.16
  • 5.17
  • 5.18
  • 5.19
  • 5.20
  • 5.21
  • 5.22
  • 5.23
  • 5.24
  • 5.25

5.1

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

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

5.2

块:用花括号括起来的语句和声明的序列,也称为复合语句。一个块就是一个作用域,在块中引入的名字只能在块内部以及嵌套在块中的子块里访问。如果在程序的某个地方,语法上需要一条语句,但是逻辑上需要多条语句,此时应该使用块。块不需要以分号结束。

例如,循环体必须是一条语句,但是我们通常需要在循环体内做很多事情,此时就应该把多条语句用花括号括起来,从而把语句序列转换成块。

5.3

可读性会降低

while (val <= 10)
    sum += val, ++val;

5.4

(a)是非法的

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

(b)是非法的

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

5.5

#include

using namespace std;

int main(){
	char socres[5]={'A','B','C','D','E'};
	int socre;
	cout<< "input socre:";
	cin>>socre;
	if (socre>90)
		cout<< socres[0] <<endl;
	else if(socre<=90&&socre>80)
		cout<< socres[1] <<endl;
	else if(socre<=80&&socre>70)
		cout<< socres[2] <<endl;	
	else if(socre<=70&&socre>60)
		cout<< socres[3] <<endl;
	else
		cout<< socres[4] <<endl;
    return 0;
}

5.6

#include 
#include 
#include 

using namespace std;

int main() {
    int grade;
    cout << "请输入您的成绩:" << endl;
    cin >> grade;
    if (grade < 0 || grade > 100) {
        cout << "该成绩不合法" << endl;
        return -1;
    }
    if (grade == 100) {                             // 处理满分的情况
        cout << "等级成绩是:" << "A++" << endl;
        return 0;
    }
    const vector<string> scores = {"F", "D", "C", "B", "A"};
    string lettergrade;
    // 如果成绩不合格,不需要考虑添加加号减号的问题
    if (grade < 60)
        lettergrade = scores[0];
    else {
        lettergrade = scores[(grade - 50) / 10];    // 获得字母形式的成绩
        if (grade != 100)       // 只要不是 A++,就考虑添加加号减号
            // 末尾是 8 或者 9 的成绩添加一个加号
            // 末尾是 0、1 或者 2 的成绩添加一个减号
            // 注意运算符的优先级和结合性,不确定的可以加括号
            lettergrade += grade % 10 > 7 ? "+" : grade % 10 < 3 ? "-" : "";
    }
    cout << "等级成绩是:" << lettergrade << endl;

    return 0;
}

5.7

(a)if 语句的循环体应该是一条语句,需要以分号结束,程序修改为:

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

(b)if 语句的循环体只能是一条语句,本题从代码的缩进格式上来说需要做两件事,一是修改 minval 的值,二是重置 occurs 的值,所以必须把这两条语句放在一个块里。

程序修改为:

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

(c)ival 是定义在 if 语句中的变量,其作用域仅限于第一个 if 语句,要想在第二个 if 语句中也使用它,就必须把它定义在两个 if 语句的外部。程序修改为:

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

(d)程序的原意是判断 ival 的值是否是 0,原题使用赋值运算符的结果是把 0 赋给了 ival,然后检验 ival 的值,这样使得条件永远不会满足。程序修改为:


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

5.8

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

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

5.9

#include

using namespace std;

int main(){
    char str[21];
    cin>>str;
    char *p = str;
    int sum{0};
    while(*p){
        if (*p=='a'||*p=='e'||*p=='i'||*p=='o'||*p=='u')
            ++sum;
        ++p;
    }
    cout<< sum <<endl;

    return 0;
}


5.10

#include

using namespace std;

int main(){
    char str[51];
    cout<<"请输入:";
    cin>>str;
    char *p = str;
    int aSum{0},eSum{0},iSum{0},oSum{0},uSum{0};
    while(*p){
        switch (*p) {
            case 'a':
            case 'A':
                ++aSum;
                break;
            case 'e':
            case 'E':
                ++eSum;
                break;
            case 'i':
            case 'I':
                ++iSum;
                break;
            case 'o':
            case 'O':
                ++oSum;
                break;
            case 'u':
            case 'U':
                ++uSum;
                break;
        }
        ++p;
    }
    cout<< "a有" <<aSum<<"个"<<endl;
    cout<< "e有" <<eSum<<"个"<<endl;
    cout<< "i有" <<iSum<<"个"<<endl;
    cout<< "o有" <<oSum<<"个"<<endl;
    cout<< "u有" <<uSum<<"个"<<endl;
    return 0;
}

5.11

#include 

using namespace std;

int main() {
    unsigned int aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
    unsigned int spaceCnt = 0, tabCnt = 0, newlineCnt = 0;
    char ch;
    cout << "请输入一段文本:" << endl;
    while (cin.get(ch) && ch != 'Q') {
        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 '\t':
                ++tabCnt;
                break;
            case '\n':
                ++newlineCnt;
                break;
        }
    }
    cout << "元音字母 a 的数量是:" << aCnt << endl;
    cout << "元音字母 e 的数量是:" << eCnt << endl;
    cout << "元音字母 i 的数量是:" << iCnt << endl;
    cout << "元音字母 o 的数量是:" << oCnt << endl;
    cout << "元音字母 u 的数量是:" << uCnt << endl;
    cout << "空格的数量是:" << spaceCnt << endl;
    cout << "制表符的数量是:" << tabCnt << endl;
    cout << "换行符的数量是:" << newlineCnt << endl;

    return 0;
}

5.12

#include
#include
using namespace std;

int main(){
	string s;
	 cout<< "请输入一个字符序列:";
	 cin>>s;
	size_t len = s.length();
	int ff{0},fl{0},fi{0};
	for (int i = 0; i < len; ++i){
		if (s[i]=='f'&&i!=len-1){
			switch(s[i+1]){
			case 'i':
				++fi;break;
			case 'f':
				++ff;break;
			case 'l':
				++fl;break;
			}
        ++i;
		}
	}
	cout<< "在" <<s<< "中:" <<endl;

	cout<< "ff的个数为:" <<ff<<endl;
	cout<< "fl的个数为:" <<fl<<endl;
	cout<< "fi的个数为:" <<fi<<endl;
    return 0;
}

5.13

(a)的错误是在每个 case 分支中都缺少了 break; 语句,造成的后果是一旦执行了前面的 case 分支,必定还会继续执行接下来的其他 case 分支。举例说明,如果 ch 的内容是字符 a ,则 aCnt、eCnt 和 iouCnt 的值都会增加;如果 ch 的内容是字符 e ,则 eCnt 和 iouCnt 的值都会增加,这显然与程序的预期是不相符的。

修改后的程序如下所示:

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)的错误是在 case 分支中定义并初始化了变量 ix,同时在 default 分支中使用了该变量,此时如果控制流跳过 case 分支而直接到达 default 分支,则会试图使用未经初始化的变量,因而该程序无法通过编译。解决办法是,把 ix 的定义放在 switch 语句之前。

修改后的程序如下所示:

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

(c)的错误是在同一个 case 标签中放置了多个值,而 C++ 规定一个 case 标签只能对应一个值。修改后的程序如下所示:


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:
    evenCnt++;
    break;
}

(d)的错误是使用变量作为 case 标签的内容,C++ 规定,case 标签的内容只能是整型常量表达式。修改后的程序如下所示:

const 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;
}

5.14

#include 

using namespace std;

int main() {
    string curStr,preStr,maxStr;
    int curIndex{1},maxIndex{1};
    while (cin>>curStr&&curStr!="Q"){
        if(preStr==curStr){
            ++curIndex;
            if(curIndex>maxIndex){
                maxIndex=curIndex;
                maxStr=curStr;
            }
        } else
            curIndex=1;
        preStr=curStr;
    }
    cout<< maxStr <<endl;
    cout<< maxIndex <<endl;
    return 0;
}

5.15

a、
ix是在for内定义的,但试图在for循环外部访问他

b、for循环只有一个分号 不符合for循环的写法

c、ix和sz都++,回到子ix一直和sz的相对位置保持不变

5.16

一般情况下,while 循环和 for 循环可以相互转换,不论哪种循环形式关键点都有三个:循环控制变量的初始值、循环控制变量的变化规则、循环终止条件。编写循环语句时除了要满足应用的需求,还必须时刻关注循环控制变量和循环终止条件,谨防写出死循环。

5.17

#include 
#include

using namespace std;
bool isInclude(const vector<int>&v1,const vector<int>&v2){
    int minLen = v1.size()>v2.size()?v2.size():v1.size();
    for (int i = 0; i < minLen; ++i)
        if(v1[i]!=v2[i])return false;
    return true;
}
int main() {
    vector<int> v1,v2;
    for (int i = 0; i < 5; ++i) {
        v1.push_back(i);
    }
    for (int i = 0; i < 10; ++i) {
        v2.push_back(i+1);
    }

    cout<< isInclude(v1,v2) <<endl;
    return 0;
}

5.18

a、
应该把循环体的内容用花括号括起来

b、
出现在 do-while 语句条件部分的变量必须定义在循环体之外

c、
当 get_response 的返回值不为 0 时执行循环体。因为出现在 do-while 语句条件部分的变量必须定义在循环体之外,所以该程序是错误的

5.19

#include
#include
using namespace std;

int main(){
	string s1,s2;
	do{
		cout<< "input tow strings:" <<endl;
		cin>>s1>>s2;
		int len1=s1.size(),len2=s2.size();
		if (len1>len2)
			cout<< s1 <<">"<<s2<<endl;
		else if (len1<len2)
			cout<< s1 <<"<"<<s2<<endl;
		else
			cout<< s1 <<"="<<s2<<endl;
	}while(cin);
    return 0;
}

5.20

#include
#include
using namespace std;

int main(){
	// how now nn yy how how
	string curStr,preStr;
	while(cin>>curStr&&curStr!="Q"){
		if (curStr!=preStr){
			preStr=curStr;			
		}else
			break;
	}
	if (curStr!="Q")
		cout<< curStr <<endl;
	else
		cout<< "no" <<endl;
		
    return 0;
}

5.21

#include
#include
using namespace std;

int main(){
	// how now nn yy how how
	string curStr,preStr;
	while(cin>>curStr&&curStr!="Q"){
		if (curStr!=preStr){
			preStr=curStr;			
		}else
			break;
	}
	if (curStr!="Q"){
		curStr[0]=toupper(curStr[0]);
		cout<< curStr <<endl;
	}
	else
		cout<< "no" <<endl;
    return 0;
}

5.22

#include
#include 
using namespace std;

int get_size(){
	srand((unsigned int)time(nullptr));
	return rand()%100-50;
}

int main(){
	int sz = get_size();
	while(sz<=0){
		cout<< sz <<endl;
		sz=get_size();
	}
    return 0;
}

5.23

#include 

using namespace std;

int main() {
    cout << "请依次输入被除数和除数:" << endl;
    int ival1, ival2;
    cin >> ival1 >> ival2;
    if (ival2 == 0) {
        cout << "除数不能为 0" << endl;
        return -1;
    }
    cout << "两数相除的结果是:" << ival1 / ival2 << endl;

    return 0;
}

5.24

#include 
#include 

using namespace std;

int main() {
    cout << "请依次输入被除数和除数:" << endl;
    int ival1, ival2;
    cin >> ival1 >> ival2;
    if (ival2 == 0) {
        throw runtime_error("除数不能为 0");
    }
    cout << "两数相除的结果是:" << ival1 / ival2 << endl;

    return 0;
}

请依次输入被除数和除数:
200 0
terminate called after throwing an instance of ‘std::runtime_error’
what(): 除数不能为 0

5.25

#include 
#include 

using namespace std;

int main() {
    cout << "请依次输入被除数和除数:" << endl;
    int ival1, ival2;
    while (cin >> ival1 >> ival2) {
        try {
            if (ival1 == 0) {
                throw runtime_error("除数不能为 0");
            }
            cout << "两数相除的结果是:" << ival1 / ival2 << endl;
        } catch (runtime_error err) {
            cout << err.what() << endl;
            cout << "需要继续吗(y or n)?";
            char ch;
            cin >> ch;
            if (!cin && ch == 'n')
                break;      // 跳出 while 循环
        }
    }

    return 0;
}

你可能感兴趣的:(C++,c++,算法,开发语言)