c++ Primer 第五章:语句 练习答案记录

本文档详细解答了C++ Primer第五章关于语句的各类练习,涵盖if、switch、while、for、do-while、break、continue、goto、try-catch等语句的使用及注意事项,包括条件语句的优化、循环控制、异常处理等,并提供了实例代码以加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++ Primer 第五章:语句 练习答案记录

练习题导航

下面练习程序别忘记开头都加上这一语句

#include<iostream>

5.1 简单语句

练习5.1 什么是空语句?什么时候会用到空语句?

空语句中只含有一个单独的分号。当循环的全部工作在条件部分就可以完成时,我们通常会用到空语句。

练习5.2 什么是块?什么时候会用到块?

复合语句(块)是指用花括号括起来的(可能为空的)语句和声明的序列,复合语句也被称作块。
如果在程序的某个地方,语法上需要一条语句,但是逻辑上需要多条语句,则应该使用复合语句

练习5.3 使用逗号运算符(参见4.10节,第140页)重写1.4.1节(第10页)的while循环,使它不再需要块,观察改写之后的代码的可读性提高了还是降低了

#include<string>
using namespace std;
int main()
{
	int sum = 0, val = 1;
	while (val <= 10) {
		sum += val;
		++val;
	}

	//重写
	while (val <= 10)
		sum += val,++val;
	//可读性相对低一点
}

5.2 语句作用域

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

#include<string>
using namespace std;
int main()
{
	string::iterator iter;
	while (iter != s.end()); 
	bool status;
	while (status = find(word));
	if (!status);
}

5.3 条件语句

5.3.1 if语句

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

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

#include<string>
using namespace std;
int main()
{
	int i = 0;
	cout << "请输入成绩:" << endl;
	cin >> i;
	if (i < 60) {
		cout << "d" << endl;
	}
	else if (i < 75) {
		cout << "c" << endl;
	}
	else if (i < 90) {
		cout << "b" << endl;
	}
	else {
		cout << "a" << endl;
	}
}

在这里插入图片描述

练习5.6 改写上一题程序,使用条件运算符(参见4.7节,第134页)代替if else语句

#include<string>
using namespace std;
int main()
{
	int i = 0;
	cout << "请输入成绩:" << endl;
	cin >> i;
	string over = ((i < 60) ? "d" : ((i < 75) ? "c" : ((i < 90) ? "b" : "a")));
	cout << over << endl;
}

在这里插入图片描述

练习5.7 改正下列代码段中的错误

#include<string>
using namespace std;
int main()
{
	int ival1 = 1, ival2 = 2, minval = 3, occurs;
	//(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" << endl;        //放在里面是因为int只在if循环内有效
		}
	}

	//(d)修改后
	if (ival == 0)  //加个等于号判断
		ival = get_value();
}

练习5.8 什么是“悬垂else”?C++语言是如何处理else子句的?

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

5.3.2 switch语句

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

#include<string>
using namespace std;
int main()
{
	char str;
	int adigit = 0, edigit = 0, idigit = 0, odigit = 0, udigit = 0;
	while (cin >> str)
	{
		if (str == 'a')
			++adigit;
		else if (str == 'e')
			++edigit;
		else if (str == 'i')
			++idigit;
		else if (str == 'o')
			++odigit;
		else if (str == 'u')
			++udigit;
	}
	cout << "a:" << adigit << " " << "e:" << edigit << " " << "i:" << idigit << " " << "o:" << odigit << " " << "u:" << udigit << " " << endl;
}

在这里插入图片描述

练习5.10 我们之前实现的统计元音字母的程序存在一个问题:如果元音字母以大写形式出现,不会被统计在内。

编写一段程序,既统计元音字母的小写形式,也统计大写形式,也就是说,新程序遇到’a’和’A’都应该递增aCnt的值,以此类推

#include<string>
using namespace std;
int main()
{
	char input;
	int adigit = 0, edigit = 0, idigit = 0, odigit = 0, udigit = 0;
	while (cin >> input) {
		switch (input) {
		case 'a':
		case 'A':
			++adigit;
			break;
		case 'e':
		case 'E':
			++edigit;
			break;
		case 'i':
		case 'I':
			++idigit;
			break;
		case 'o':
		case 'O':
			++odigit;
			break;
		case 'u':
		case 'U':
			++udigit;
			break;
		}
	}
	cout << "a、A:" << adigit << " " << "e、E:" << edigit << " " << "i、I:" << idigit << " " << "o、O:" << odigit << " " << "u、U:" << udigit << " " << endl;
}

在这里插入图片描述

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

#include<string>
using namespace std;
int main()
{
	char input;
	int adigit = 0, edigit = 0, idigit = 0, odigit = 0, udigit = 0, kon = 0, zhi = 0, huan = 0;
	while (cin >> std::noskipws>>input) {   //std::noskipws不忽略空格
		switch (input) {
		case 'a':
		case 'A':
			++adigit;
			break;
		case 'e':
		case 'E':
			++edigit;
			break;
		case 'i':
		case 'I':
			++idigit;
			break;
		case 'o':
		case 'O':
			++odigit;
			break;
		case 'u':
		case 'U':
			++udigit;
			break;
		case ' ':
			++kon;
			break;
		case '\t':
		case '\v':
			++zhi;
			break;
		case '\n':
			huan++;
			break;
		}
	}
	cout << "a、A:" << adigit << " " << "e、E:" << edigit << " " << "i、I:" << idigit << " " << "o、O:" << odigit << " " << "u、U:" << udigit << " ";
	cout << "空格:" << kon << " " << "制表符:" << zhi << " " << "换行符:" << huan << endl;
}

在这里插入图片描述

练习5.12 修改统计元音字母的程序,使其能统计以下含有两个字符的字符序列的数量:ff,fl,fi

#include<string>
using namespace std;
int main()
{
	char input, cn = '\0';  //cn必须要初始化,不然会报错
	int adigit = 0, edigit = 0, idigit = 0, odigit = 0, udigit = 0, kon = 0, zhi = 0, huan = 0, fidigit = 0, ffdigit = 0, fldigit = 0;
	while (cin >> std::noskipws >> input) {   //std::noskipws不忽略空格
		switch (input) {
		case 'a':
		case 'A':
			++adigit;
			break;
		case 'e':
		case 'E':
			++edigit;
			break;
		case 'i':
			if (cn == 'f') {
				++fidigit;
			}
		case 'I':
			++idigit;
			break;
		case 'o':
		case 'O':
			++odigit;
			break;
		case 'u':
		case 'U':
			++udigit;
			break;
		case ' ':
			++kon;
			break;
		case '\t':
		case '\v':
			++zhi;
			break;
		case '\n':
			huan++;
			break;
		case 'l':
			if (cn == 'f') {
				++fldigit;
			}
			break;
		case 'f':
			if (cn == 'f') {
				++ffdigit;
			}
			break;
		}
		cn = input;
	}
	cout << "a、A:" << adigit << " " << "e、E:" << edigit << " " << "i、I:" << idigit << " " << "o、O:" << odigit << " " << "u、U:" << udigit << " ";
	cout << "空格:" << kon << " " << "制表符:" << zhi << " " << "换行符:" << huan << " " << "ff:" << ffdigit << " " << "fl:" << fldigit << " " << "fi:" << fidigit << endl;
}

在这里插入图片描述

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

#include<string>
using namespace std;
int main()
{
	//(a)修改前
	unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
	char ch = next_text();
	switch (ch) {          
	case 'a':
		aCnt++;
	case 'e':
		eCnt++;
	default:
		iouCnt++;
	}

	//(a)修改后
	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)修改前
	unsigned index = some_value();
	switch (index) {
	case 1:
		int ix = get_value();
		ivec[ix] = index;
		break;
	default:
		ix = ivec.size() - 1;
		ivec[ix] = index;
	}

	//(b)修改后
	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)修改前
	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;
	}

	//(c)修改后
	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)修改前
	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);
	case kval:
		bufsize = kval * sizeof(int);
		break;
	}

	//(d)修改后
	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);
	case kval:
		bufsize = kval * sizeof(int);
		break;
	}
}

5.4 迭代语句

5.4.1 while语句

练习5.14 编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词

所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对于单词
如果这样的单词存在,输出重复出现的最大次数;如果不存在,输出一条信息说明任何单词都没有连续出现过。 例如,如果输入是how now now
now brown cow cow那么输出应该表明单词now连续出现了3次

#include<string>
#include<vector>
using namespace std;
int main()
{
	string str,intput=" ",output;
	int digit = 0, compare = 0;
	cout << "从标准输入中读取若干string对象并查找连续重复出现的单词:" << endl;
	while (cin >> str) {
		if (str == intput) {
			++digit;
		}
		else if (digit != 0) {    //当计算器不为0时候,但是两单词又不重复时候,表面到下一个单词判断了,此时将计数器归0
			if (digit > compare) {
				compare = digit;  //由于要求记录连续重复出现的最大次数以及对于单词,这里只记录最大的
				output = intput;
			}
			digit = 0;            //将重复次数归0
		}
		intput = str;
	}
	cout << "连续重复出现的最大次数以及对于单词:" << compare+1 << " " << output << endl;
}

在这里插入图片描述

5.4.2 传统的for语句

练习5.15 说明下列循环的含义并改正其中的错误

#include<string>
#include<vector>
using namespace std;
int main()
{
	//(a)修改前
	for (int ix = 1; ix != sz; ix++) {

	}
	if (ix != sz) {
	}

	//(a)修改后
	int ix;
	for (ix = 1; ix != sz; ix++) {     //后面if语句还要用到ix,故ix在块外面定义

	}
	if (ix != sz) {
	}

	//(b)修改前
	int ix;
	for (ix != sz; ++ix) {

	}

	//(b)修改后
	int ix;
	for (; ix != sz; ++ix) {
		
	}

	//(c)修改前
	for (int ix = 0; ix != sz; ++ix, ++sz) {

	}

	//(c)修改后
	//如果sz的初始值为0,则不进入循环;如果sz的初始值不为0,则需要循环体内需要有语句退出循环,否则会无休止地执行下去。
}

练习5.16 while循环特别适用于那种条件保持不变、反复执行操作的情况,例如,当未达到文件末尾时不断读取下一个值。for循环则更像是在按步骤迭代,它的索引值在某个范围内依次变化。根据每种循环的习惯用法各自编写一段程序,然后分别用另一种循环改写。如果只能使用一种循环,你倾向于使用哪种呢?为什么?

我更倾向与用for,因为在for上定义的变量仅在for循环中有效

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	vector<int> input1, input2;
	int input, digit = 0;  //用于计数
	cout << "请输入第一个整数vector对象(当输入为-100时跳出循环):" << endl;
	for (int i = 0;; i++) {
		cin >> input;
		if (input == -100)       //当输入为-100时跳出循环
			break;
		input1.push_back(input);
	}
	cout << "请输入第二个整数vector对象(当输入为-100时跳出循环):" << endl;
	for (int i = 0;; i++) {
		cin >> input;
		if (input == -100)       //当输入为-100时跳出循环
			break;
		input2.push_back(input);
	}
	if (input1.size() >= input2.size()) {
		for (auto i = input1.begin(), j = input2.begin(); j != input2.end(); ++i, ++j) {
			if (*i != *j) {
				cout << "false" << endl;
				break;
			}
			++digit;
		}
		if ((digit) == input2.size()) {    //如果循环结束了都没找出不同,则输出true
			cout << "true" << endl;
		}
	}
	else {
		for (auto i = input1.begin(), j = input2.begin(); i != input1.end(); ++i, ++j) {
			if (*i != *j) {
				cout << "false" << endl;
				break;
			}
			++digit;
		}
		if ((digit) == input1.size()) {    //如果循环结束了都没找出不同,则输出true
			cout << "true" << endl;
		}
	}
}

输入1长度小于输入2

在这里插入图片描述

输入1长度大于输入2

在这里插入图片描述

两输入不等时

在这里插入图片描述

5.4.3 范围for语句(C++11新标准)

5.4.4 do while 语句

练习5.18 说明下列循环的含义并改正其中的错误

#include<string>
#include<vector>
using namespace std;
int main()
{
	//(a)修改前
	do
		int v1, v2;
	cout << "Pleasr enter two numbers to sum:";
	if (cin >> v1 >> v2)
		cout << "Sum is:" << v1 + v2 << endl;
	while (cin);

	//(a)修改后
	do {
		int v1, v2;
		cout << "Pleasr enter two numbers to sum:";
		if (cin >> v1 >> v2)
			cout << "Sum is:" << v1 + v2 << endl;   //输出两个整数之和
	}
	while (cin);

	//(b)修改前
	do {

	} while (int ival = get_response());

	//(b)修改后
	int ival;
	do {

	} while (ival = get_response());

	//(c)修改前
	do {
		int ival = get_response();
	} while (ival);

	//(c)修改后
	//condition使用的变量必须定义在循环体外
	int ival;
	do {
		ival = get_response();
	} while (ival);
}

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	string input1, input2;
	do {
		cout << "输入两个string对象,然后挑出较短的那个并输出它:(输入over结束循环)" << endl;
		cin >> input1;
		if (input1 == "over")
			break;
		cin >> input2;
		if (input1.size() < input2.size())
			cout << "短字符串是:" << input1 << endl;
		else if (input1.size() > input2.size())
			cout << "短字符串是:" << input2 << endl;
		else
			cout << "两字符串长度一致" << endl;
	} while (1);
}

在这里插入图片描述

5.5 跳转语句

5.5.1 break语句

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	string input, output = "\0";
	int digit = 0;  //判断是否没有任何单词是连续重复出现的
	cout << "从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止:" << endl;
	while (cin >> input) {
		if (output == input) {
			cout << "重复出现" << endl;
			++digit;
			break;
		}
		output = input;
	}
	if (digit == 0) {
		cout << "没有任何单词是连续重复出现的" << endl;
	}
}

在这里插入图片描述

在这里插入图片描述

5.5.2 continue语句

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	string input, output = "\0";
	int digit = 0;  //判断是否没有任何单词是连续重复出现的
	cout << "从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止:" << endl;
	while (cin >> input) {
		if (output == input) {
			if (output[0] != toupper(output[0]))    //如果首字母开头不是大写,则继续循环
				continue;
			cout << "重复出现" << endl;
			++digit;
			break;
		}
		output = input;
		
	}
	if (digit == 0) {
		cout << "没有任何单词是连续重复出现的" << endl;
	}
}

在这里插入图片描述

5.5.3 goto语句

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	doint sz = get_size();while(sz <= 0);
}

5.6 try语句块和异常处理

5.6.1 throw表达式

5.6.2 try语句块

5.6.3 标准异常

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	int digit1, digit2;
	cin >> digit1 >> digit2;
	cout << digit1 / digit2 << endl;
}

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

#include<string>
#include<vector>
using namespace std;
int main()
{
	int digit1, digit2;
	cin >> digit1 >> digit2;
	if (digit2 == 0) {
		throw runtime_error("divisor can't be 0");
	}
	cout << digit1 / digit2 << endl;
}

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

#include<string>
#include<vector>
#include <stdexcept>
using namespace std;
int main()
{
	int i1, i2;
	while (cin >> i1 >> i2)
	{
		try{
			if (i2 == 0){
				throw runtime_error("不能输入除数0");
			}
			cout << i1 / i2 << endl;
		}
		catch (runtime_error err){
			cout << err.what()<< "\ntry again? enter y or n" << endl;
			char c;
			cin >> c;
			if (!cin || c == 'n') 
				break;
		}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Is_LiuYiZheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值