c++ primer第五章(习题解答):语句

前言

我发现相比于写知识点,还是写把习题答案写下来可能比较好一点。把知识点写下来太繁杂了,当然我觉得十分重要或者比较难懂的知识点还是会写下来,由于c++ primer的习题本就比较少,所以我也有信心可以把习题全部做完。

习题

5.1节练习

5.1
什么是空语句?什么时候会用到空语句?
答:语句中之后一个分号,可以在while循环中用空语句中起到阻塞作用
5.2
什么是块?什么时候会用到块?
答:用花括号括起来的那个区域?在逻辑上需要多条语句的时候需要使用。
5.3
使用逗号运算符重写1.4.1节的while循环,使它不再需要块,观察改写之后的可读性是提高了还是降低了
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	int sum = 0, val = 1;
	while (val <= 10)
		sum += val, ++val;
	cout << "sum of 1 to 10 inclusize is " << sum << endl;
	return 0;
};
可读性降低了。

5.2节练习

5.4
说明下列例子的含义,如果存在问题,试着修改它。
(a)while(string::iterator iter!=s.end()){}
答:当迭代器iter的值不等于s.end()时,执行while()块中
(b)while(bool status=find(word)){}
if(!status){}
答:当status==false时跳出循环,执行if语句

5.3.1节练习

5.5
写一段自己的程序,使用if else语句实现把数学成绩转换成字母成绩的要求
答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	int score;
	cin >> score;
	if (score / 10 >=9) {
		cout << "A" << endl;
	}
	else if (score / 10 ==8) {
		cout << "B" << endl;
	}
	else if (score / 10 == 7) {
		cout << "C" << endl;
	}
	else if (score / 10 == 6) {
		cout << "D" << endl;
	}
	else {
		cout << "E" << endl;
	}
	return 0;
};
5.6
改写上一题程序,使用条件运算符代替if else语句
答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	int score;
	cin >> score;
	int count = score / 10;
	char char_score = (count >= 9) ? 'A' : (count == 8) ? 'B' : (count == 7) ? 'C' : (count == 6) ? 'D' : 'E';
	cout << char_score << endl;
	return 0;
};
5.7
改写下列代码段中的错误
(a)if(ival1!=ival2)
		ival1=ival2
   else ival1=ival2=0;
答:ival1=ival2;
(b)if(ival<minval)
		minval=ival;
		occurs=1;
答:occurs=1未在if语句中,需要加上语句块
(c)if(int ival=get_value())
	cout<<"ival="<<ival<<endl;
   if(!ival)
   		cout<<"ival=0\n";
答:在if条件中定义的ival只能在if语句块中使用
(d)if(ival=0)
	ival=get_value();
答:ival=0是赋值语句,这样ival永远都是0,if中的语句永远都不会执行
5.8
什么是"悬挂else"?c++是如何处理else子句的?
答:当if语句和else嵌套使用时,需要决定else匹配那个if这就是悬挂else c++是根据就近原则,else 与离得最近的if 匹配

5.3.2节练习

5.9
编写一段程序,使用一系列if语句统计从cin读入的文本中有多少元音字母。
答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	string s;
	int aCnt = 0;
	cin >> s;
	for (auto &ch : s) {
		if (ch == 'a' ||ch=='A' ||ch=='e' ||ch== 'E' ||ch== 'i' ||ch== 'I' ||ch== 'o' ||ch== 'O' ||ch== 'u' ||ch== 'U') {
			++aCnt;
		}
	}
	cout << aCnt << endl;
	return 0;
};
5.10
我们之前按统计的元音字母没有包括大小写,这次把大小写包括进去。
答:同上
5.11
修改统计元音字母的程序,使其也能够统计空格、制表符、和换行符的数量
答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	string s;
	int aCnt = 0;
	int space_cnt = 0;
	int table_cnt = 0;
	int row_cnt = 0;
	getline(cin, s);
	for (auto &ch : s) {
		if (ch == 'a' ||ch=='A' ||ch=='e' ||ch== 'E' ||ch== 'i' ||ch== 'I' ||ch== 'o' ||ch== 'O' ||ch== 'u' ||ch== 'U') {
			++aCnt;
		}
		if (ch == ' ')
			space_cnt++;
		if (ch == '\t')
			table_cnt++;
		if (ch == '\n')
			row_cnt++;
	}
	cout << space_cnt << endl;
	cout << table_cnt << endl;
	cout << row_cnt << endl;
	cout << aCnt << endl;
	return 0;
};
5.12
修改统计元音字母的程序,使其能够统计一下含有两个字符序列的数量 ff fl fi
答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
	string s;
	getline(cin, s);
	int ff_cnt, fl_cnt, fi_cnt;
	ff_cnt = fl_cnt = fi_cnt = 0;
	for (int i = 0; i < s.size(); i++) {
		if (s[i] == 'f') {
			if (i + 1 < s.size()) {
				switch (s[i + 1]) {
				case 'f':ff_cnt++;
					break;
				case 'l':fl_cnt++;
					break;
				case 'i':fi_cnt++;
					break;
				}
			}
		}
	}
	cout << "ff_cnt:" << ff_cnt << endl;
	cout << "fl_cnt:" << fl_cnt << endl;
	cout << "fi_cnt:" << fi_cnt << endl;
	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++;
}
答:没有在case后加上break
(b)unsigned index=some_value();
switch(index){
case 1:
	int ix=get_value();
	ivec[ix]=index;
default :
	ix=ivec.size()-1;
	ivec[ix]=index;
}
答:在default分支中使用了未定义的ix,将ix在switch外定义比较好
(c)unsigned eventCnt=0,oddCnt=0;
int digit=get_num()%10;
switch(digit){
	case 1,3,5,7,9:
		oddCnt++;
		break;
	case 2,4,6,8,10
		eventCnt++;
		break;
}
答:逗号运算符用错了,逗号运算符表示从左往右运算,但是case只能选择一个,可以
case 1:
case 3:
case 5:
case 7:
case 9:
oddCnt++;
break;
(d)unsigned ival=512,javl=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;
}
答:case标签必须是整型常量表达式,所以需要const unsigned ival=512,javl=1024,kval=4096;

5.4.1节练习

5.14
编写一段程序,从标准输入中读取若干个string对象并查找连续重复出现单词。所谓连续重复出现就是:一个单词后面
紧跟这个单词本身。要求记录的连续出现次数以及对应的单词。如果这样的单词存在,输出重复出现的最大次数:如果
不存在,输出一条信息说明任何单词都没有连续出现过。例
如:如果输入是 how now now now brown cow cow
那么输出应该表明单词now出现了三次
答:
//我的
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	string s;
	int max_count = 0;
	int num = 0;
	string *str=new string[1000];
	getline(cin, s);
	int i = 0;
	while (s[i] == ' ')
		i++;
	for (int j=i; j < s.size(); j++) {
		if (s[j] == ' '||j==s.size()-1) {
			if (j == s.size() - 1)
				j++;
			str[num++] = s.substr(i, j - i);
			cout << str[num - 1] << endl;
			i = j;
			while (s[i] == ' '&&i<s.size())
				i++;
			j = i;
		}
		
	}
	string target_str;
	for (int i = 0; i < num; i++) {
		int count = 0;
		if (str[i].compare(str[i + 1])==0) {
			int j = i;
			while (str[i].compare(str[j]) == 0&&j<num) {
				j++;
				count++;
			}
		}
		if (count > max_count) {
			max_count = count;
			target_str = str[i];
		}
	}
	if (!max_count)cout << "no this string" << endl;
	else
		cout << "max_count_string:" << target_str << " " << "count:" << max_count << endl;
	return 0;
};
//答案
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	string currstring, prestring = "";
	string max_count_string;
	int max_count = 1;
	int count = 1;
	while (cin >> currstring) {
		if (currstring == prestring) {
			count++;
			if (count > max_count) {
				max_count = count;
				max_count_string = currstring;
			}
		}
		else {
			count = 1;
		}
		prestring = currstring;

	}
	if (max_count>1) {
		cout << "max_count_string:" << max_count_string << " count:" << max_count << endl;
	}
	else
		cout << "no this string" << endl;
	return 0;
};

5.4.2节练习

5.15
说明下列循环含义并改正其中的错误。
(a)for(int ix=0;ix!=sz;++ix){}
	if(ix!=sz)
答:在for循环中定义的ix不能用在for块外
(b)int ix;
for(ix!=sz;++ix){}
答:for循环中需要两个分号来分隔
(c)for(int ix=0;ix!=sz;++ix,++sz){}
答:会是个死循环
5.16
while循环特别适用于那种条件保持不变、反复执行的情况例如,当未达到文件末尾时不断读取下一个值。for循环更像是在按步骤迭代,它的索引值在某个范围内变化。我倾向于视情况而定来使用。
5.17
假设有两个包含整数vector对象,编写一段程序,检验其中一个vector对象是否是另一个前缀。为了实现这个目标,对于两个不等长的vector对象,只需要抛出长度最短的那个,把它的所有元素和另一个vector对象比较即可。例如,如果有个vector对象的元素分别是0,1,1,20,1,1,2,3,5,8,则程序返回的结果应该为真。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	vector<int>a = { 0,1,1,2 };
	vector<int>b = { 0,1,1,2,3,4,5 };
	int len = a.size() > b.size() ? b.size() : a.size();
	bool  ispre=false;
	for (int i = 0; i < len; i++) {
		if (a[i] != b[i]) {
			cout << "不是前缀" << endl;
			ispre = true;
			break;
		}
	}
	if (!ispre)cout << "是前缀" << endl;
	return 0;
};

5.4.4练习

5.18
说明下列循环的含义并纠正其中的错误。
(a)do
	int v1,v2;
	cout<<"Please enter two number 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)
答:出现在条件语句的变量必须要定义在循环体之外
5.19
编写一段程序,使用do while循环重复的执行下列任务:首先提示用户输入两个string对象,然后输出短的string
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	string a, b;
	do {
		cout << "输入两个string" << endl;
		cin >> a >> b;
		cout << ((a.size() < b.size()) ? a : b )<< endl;
	} while (cin);
	return 0;
};

5.1.1节练习

5.20
编写一段程序,从标准输入中读取string对象的序列直到连
续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现时使用
break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有任何单词是连续出现的。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	string currString, preString = "";
	bool flag = false;
	while (cin >> currString) {
		if (currString == preString) {
			cout << currString << endl;
			flag = true;
			break;
		}
		preString = currString;
	}
	if (!flag)
		cout << "no this string" << endl;
	return 0;
};

5.5.2节练习

5.21
修改5.1.1节(171页)练习题的程序,使找到的重复单词必须以大写字母开头。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	string currString, preString = "";
	bool flag = false;
	while (cin >> currString) {
		if (currString == preString) {
			if (!isupper(currString[0]))
				continue;
			cout << currString << endl;
			flag = true;
			break;
		}
		preString = currString;
	}
	if (!flag)
		cout << "no this string" << endl;
	return 0;
};

5.5.3练习

5.22
本节的最后一个例子跳回到begin其实使用循环能更好的完成任务。重写该代码,注意不要使用goto语句
答:
int sz;
do{
	sz=get_size();
}while(sz<=0);

5.6.3节练习

5.23
编写一段程序,从标准输入读取两个整数,输出第一个整数除以第二个整数的结果。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	int a, b;
	cout << "Please enter two number" << endl;
	cin >> a >> b;
	cout << "the result is:" << a / (double)b << endl;
	return 0;
};
5.24
修改你的程序,使得当第二个数是0使抛出异常。先不要设置catch子句,运行程序并真的为除数输入0,看看会发生啥。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	int a, b;
	cout << "Please enter two number" << endl;
	cin >> a >> b;
	if (b == 0) 
		throw runtime_error("除数不能为0");
	double result = a / (double)b;
	cout << "the result is:" << result << endl;
	return 0;
};
5.25
修改上一题程序,使用try语句块去捕获异常,catch子句应该为用户输出一条提示信息,询问其是否输入新数并重新执行try语句块的内容。
答:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main() {
	int a, b;
	cout << "Please enter two number" << endl;
begin:try {
		cin >> a >> b;
		if (b == 0) {
			throw runtime_error("除数不能为0");
		}
	}
	catch (runtime_error) {
		cout << "是否重新输入(y/n)" << endl;
		char ch;
		cin >> ch;
		if (ch == 'y' || ch == 'Y')
			goto begin;
		else
			return 0;
	}
	double result = a / (double)b;
	cout << "the result is:" << result << endl;
	return 0;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值