《C++ Primer Plus》第六章复习题和编程练习

这里写目录标题

一、复习题

1. 请看下面两个计算空格和换行符的数目的代码片段:…。第二个版本比第一个版本好在哪里?

答:读取空格字符时,第一个版本需要判断两次,而第二个版本只需要判断一次。所以,第二个版本效率略高。

2. 在程序清单6.2中,用ch+1 替换++ch将发生什么情况呢?

答:char类型在进行算数运算时会自动转换为int类型,所以表达式ch+1的结果为int类型,cout输出数字而不是字符。

3. 请认真考虑下面的程序:…。假设输入如下:…。则输出将是什么?

答:if语句中误用了赋值运算符,即ch = ‘$’,导致表达式的值始终为true,且ch的值被修改。输出如下:
Hi!
H$i$!$
$S$e$n$d$ $ct1 = 9, ct2 = 9

4. 创建表示下述条件的逻辑表达式:…。

答:
a. weight >= 115 || weight <= 125
b. ch == ‘q’ || ch == ‘Q’
c. x % 2 == 0 && x != 26
d. x % 2 == 0 && x % 26 != 0
e. (donation >= 1000 && donation <= 2000) || guest == 1
f. (ch >= ‘a’ && ch <= ‘z’) || (ch >= ‘A’ && ch <= ‘Z’)

5. 在英语中,"I will not not speak(我不会不说)"的意思与“I willspeak(我要说)”相同。在C++中,!!x是否与x相同。

答:若x为bool类型,则!!x与x为相同的bool值。若x为其他类型,则!!x依然为bool值,则两者的类型不同。

6. 创建一个条件表达式,其值为变量的绝对值。也就是说,如果变量x为正,则表达式的值为x,如果x为负,则表达式的值为-x。

答:x > 0 ? x : -x 或者 x >= 0 ? x : -x

7. 用switch语句改写下面的代码片段:…。

答:

switch (ch)
{
	case 'A' :
		a_grade++;
		break;
	case 'B' :
		b_grade++;
		break;
	case 'C' :
		c_grade++;
		break;
	case 'D' : 
		d_grade++;
		break;
	default:
		f_grade++;
		break;
}

8. 对于程序清单6.10,与使用数字相比,使用字符(如a和c)表示菜单选项和case标签有何有点呢?

答:choice为int类型时,若用户不小心输入字符,则造成非法输入,程序无法正常运行。choice为char类型时,可以读取键盘输入的所有字符,若输入错误,则跳到default语句进行处理,然后重新输入。使用char类型,可以提高程序的容错率。

9. 请看下面的代码片段:…。请重写该代码片段,不要使用break和continue语句。

答:

int line = 0;
char ch;
while (cin.get(ch) && ch != 'Q')
{
	if (ch == '\n)
		line++;
}

二、编程练习

1. 编写一个程序,读取键盘输入,知道遇到@符号为止,并回显输入(数字除外),同时将大写字符转换为小写,将小写字符转换为大写(别忘了cctype函数系列)。

/ 头文件
#include <iostream>
#include <cctype>

// 标准名称空间std
using namespace std;

int main()
{
	char ch;
	cout << "Enter the character: " << endl;
	// 通过循环读取输入字符,直到遇到'@'
	while ((ch = cin.get()) != '@')
	{
		// 不是数字字符
		if (!isdigit(ch))
		{
			// 大写字符变小写
			if (isupper(ch))
				ch = tolower(ch);
			// 小写字符变大写
			if (islower(ch))
				ch = toupper(ch);

			// 显示字符
			cout << ch;
		}
	}

	return 0;
}

2. 编写一个程序,最多将10个donation值读入一个double数组中(也可以使用模板类array)。在程序遇到数字时将结束输入,并报告这些数字的平均值以及数组中有多少数字大于平均值。

double数组

int main()
{
	double input, donations[10];  // 存储输入
	int num = 0;  // 记录输入数字的个数
	double sum = 0;  // 计算输入总和
	while (num < 10)
	{
		cout << "Enter a number: ";
		cin >> input;
		// 如果输入非数字
		if (!cin)
		{
			// 重置输入
			cin.clear();
			// 清空错误输入
			while (cin.get() != '\n')
				continue;
			// 结束输入
			break;
		}
		// 存储输入的数,计算总和,计数器+1
		sum += input;
		donations[num] = input;
		++num;
	}
	// 计算平均值
	double average = sum / num;
	// 统计超过平均值的数的个数
	int num_overAverage = 0;
	for (int i = 0; i < num; i++)
	{
		if (donations[i] > average)
			num_overAverage++;
	}
	// 输出
	cout << "Average: " << average << endl;
	cout << "Over average: " << num_overAverage << endl;

	return 0;
}

array模板

// 头文件
#include <iostream>
#include <array>

// 标准名称空间std
using namespace std;

int main()
{
	// 存储输入
	array<double, 10> donations;
	double input;
	double sum = 0;  // 存储输入数的总和
	double num = 0;  // 存储输入数的个数
	// 输入
	do
	{
		cout << "Please enter a number: ";
		// 如果非法输入
		if (!(cin >> input))
		{
			// 重置输入
			cin.clear();
			// 清空错误输入
			while (cin.get() != '\n')
				continue;
			// 结束输入
			break;
		}
		else
		{
			// 计算总和,存储数据,计数
			sum += input;
			donations[num] = input;
			++num;
		}
	} while (num < 10);
	// 计算平均数
	double average = sum / num;
	// 统计超过平均数的个数
	int num_overAverage = 0;
	for (int i = 0; i < num; ++i)
	{
		if (donations[i] > average)
			++num_overAverage;
	}
	// 输出
	cout << "Average: " << average << endl;
	cout << "Over average: " << num_overAverage << endl;

	return 0;
}

3. 编写一个菜单驱动程序的雏形。该程序显示一个提供4个选项的菜单——每个选项用字母标记。…。

// 头文件
#include <iostream>

// 标准名称空间std
using namespace std;

// 打印菜单
void menu();

int main()
{
	// 显示菜单
	menu();
	// 输入
	char ch;
	ch = cin.get();
	// 无效输入则重新输入
	while (ch != 'c' && ch != 'p' && ch != 't' && ch != 'g')
	{
		// 清除无效输入
		while (cin.get() != '\n')
			continue;
		// 重新输入
		cout << "Please enter a c, p, t, or g: ";
		ch = cin.get();
	}
	// 选择
	switch (ch)
	{
	case 'c':
		break;
	case 'p':
		break;
	case 't':
		cout << "A maple is a tree." << endl;
		break;
	case 'g':
		break;
	}

	return 0;
}

// 打印菜单
void menu()
{
	cout << "Please enter one of the following choices:" << endl;
	cout << "c) carnivore           p) pianist" << endl;
	cout << "t) tree                g) game" << endl;
}

4. 加入Benevolent Order of Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名来了解他(她)。…。

// 符号常量声明
const int strsize = 20;

// bop结构声明
struct bop
{
	char fullname[strsize];  // 真实姓名
	char title[strsize];  // 头衔
	char bopname[strsize];  // 秘密BOP姓名
	int preference;  // 0 = fullname, 1 = title, 2 = bopname
};

// 打印菜单
void menu();
// 打印姓名
void print_by_name(bop arr[]);
// 打印头衔
void print_by_title(bop arr[]);
// 打印秘密BOP姓名
void print_by_bopname(bop arr[]);
// 打印偏好
void print_by_preference(bop arr[]);

int main()
{
	// 显示菜单
	menu();
	// 创建bop结构数组并初始化
	bop bopArr[5] = {
		{"Wimp Macho", "Programmer", "MIPS", 0},
		{"Raki Rhodes", "Junior Programmer", "", 1},
		{"Celia Laiter", "", "MIPS", 2},
		{"Hoppy Hipman", "Analyst Trainee", "", 1},
		{"Pat Hand", "", "LOOPY", 2}
	};
	// 输入
	char ch;
	while ((ch = cin.get()) != 'q')
	{
		switch (ch)
		{
		case 'a':
			print_by_name(bopArr);
			break;
		case 'b':
			print_by_title(bopArr);
			break;
		case 'c':
			print_by_bopname(bopArr);
			break;
		case 'd':
			print_by_preference(bopArr);
			break;
		default:
			cout << "Input error ! Please re-enter." << endl;
		}
		// 清空输入
		while (cin.get() != '\n')
			continue;
		// 下一个输入
		cout << "Next choice:";
	}

	return 0;
}

// 打印菜单
void menu()
{
	cout << "a. display by name        b. display by title" << endl;
	cout << "c. display by bopname     d. display by preference" << endl;
	cout << "q. quit" << endl;
}

// 打印姓名
void print_by_name(bop arr[])
{
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i].fullname << endl;
	}
}
// 打印头衔
void print_by_title(bop arr[])
{
	for (int i = 0; i < 5; ++i)
	{
		cout << arr[i].title << endl;
	}
}
// 打印秘密BOP姓名
void print_by_bopname(bop arr[])
{
	for (int i = 0; i < 5; ++i)
	{
		cout << arr[i].bopname << endl;
	}
}
// 打印偏好
void print_by_preference(bop arr[])
{
	for (int i = 0; i < 5; ++i)
	{
		switch (arr[i].preference)
		{
		case 0:
			cout << arr[i].fullname << endl;
			break;
		case 1:
			cout << arr[i].title << endl;
			break;
		case 2:
			cout << arr[i].bopname << endl;
			break;
		}
	}
}

5. 在Neutronia王国,货币单位是tvarp,收入所得税的计算方式如下。…。

int main()
{
	// 输入工资,计算税收
	double wages = 0;  // 工资
	double tax = 0;  // 税收
	cout << "Please enter your wages: ";
	while (cin >> wages && wages >= 0)
	{
		// 计算税收
		if (wages <= 5000)
			tax = 0;
		else if (wages <= 15000)
			tax = (wages - 5000) * 0.1;
		else if (wages <= 35000)
			tax = (wages - 15000) * 0.15 + 1000;
		else
			tax = (wages - 35000) * 0.2 + 3000 + 1000;
		// 输出
		cout << "Your tax: " << tax << endl;
		// 下一个
		cout << endl;  // 每次输入隔开
		cout << "Please enter your wages: ";
	}

	return 0;
}

6. 编写一个程序,记录捐给“维护合法权利团队”的资金。…。

// Donors结构声明
struct Donor
{
	char name[20];  // 姓名
	double money_donated;  // 捐款金额

};

int main()
{
	// 输入捐款人数
	int num_donated;
	cout << "Please enter the number of donations: ";
	cin >> num_donated;
	cout << endl;
	// 申请对应数量的结构数组
	Donor* pdonors = new Donor[num_donated];
	// 输入
	for (int i = 0; i < num_donated; ++i)
	{
		// 丢弃换行符
		cin.get();

		cout << "Enter the name of donor: ";
		cin.getline(pdonors[i].name, 20);
		cout << "Enter donation amount: ";
		cin >> pdonors[i].money_donated;
		cout << endl;  // 隔开每个人的信息
	}
	// 设置捐款大于15000为重要捐款人
	// 重要捐款人
	int empty = 1;  // 判断是否有捐款者
	cout << "Grand Patrons: " << endl;
	for (int i = 0; i < num_donated; ++i)
	{
		if (pdonors[i].money_donated > 15000)
		{
			cout << pdonors[i].name << ": " << pdonors[i].money_donated << endl;
			empty = 0;
		}
	}

	if (empty)
		cout << "NONE" << endl;

	empty = 1;  // 重置

	// 其他捐款者(捐款金额大于10000)
	cout << "Patrons:" << endl;
	for (int i = 0; i < num_donated; i++)
	{
		if (pdonors[i].money_donated >= 10000 && pdonors[i].money_donated <= 15000)
			cout << pdonors[i].name << ": " << pdonors[i].money_donated << endl;
	}

	// 释放申请空间
	free(pdonors);

	return 0;
}

7. 编写一个程序,它每次读取一个单词,直到用户输入q。然后,该程序指出有多少个单词原音开头,有多少个单词以辅音开头,还有多少个单词不属于这两类。…。

// 头文件
#include <iostream>
#include <cstring>
#include <cctype>

// 标准名称空间std
using namespace std;

int main()
{
	int vowel = 0;  // 元音单词的数量
	int consonant = 0;  // 辅音单词的数量
	int others = 0;  // 其他单词的数量
	// 输入
	char words[20];
	cout << "Enter words (q to quit) :" << endl;
	while (cin >> words && strcmp(words, "q") != 0)
	{
		char ch = words[0];  // 输入单词的第一个字母
		if (isalpha(ch))  // 是单词
		{
			switch (ch)
			{
			case 'a':
			case 'e':
			case 'i':
			case 'o':
			case 'u':
				++vowel;
				break;
			default:
				++consonant;
			}
		}
		else  // 不是单词
		{
			++others;
		}
	}
	// 输出
	cout << vowel << " words beginning with vowels" << endl;
	cout << consonant << "words beginning with consonants" << endl;
	cout << others << " others" << endl;

	return 0;
}

8. 编写一个程序,它打开一个文件,诸葛自负读取该文件,知道打到文件末尾,然后指出该文件中包含多少个字符。

// 头文件
#include <iostream>
#include <fstream>
#include <cstdlib>

// 标准名称空间
using namespace std;

int main()
{
	// 创建ifstream对象
	ifstream fcin;
	// 打开文件
	fcin.open("snow.txt");
	// 检测文件是否成功打开
	if (!fcin.is_open())
	{
		cout << "Open error." << endl;
		exit(EXIT_FAILURE);
	}
	// 输入
	char ch;  // 如果使用ch = cin.get()需要创建为int类型
	int num_char = 0;  // 统计字符个数
	while (fcin.get(ch))  // 检测EOF
	{
		++num_char;
	}
	// 输出
	cout << "The number of the characters: " << num_char << endl;
	// 关闭文件
	fcin.close();


	return 0;
}

9. 重做编程练习6,从文件中读取所需信息…。

// 头文件
#include <iostream>
#include <fstream>
#include <cstdlib>

// 标准名称空间std
using namespace std;

// Donors结构声明
struct Donor
{
	char name[20];  // 姓名
	double money_donated;  // 捐款金额
};

int main()
{
	// 创建ifstream对象
	ifstream fcin;
	// 打开文件
	fcin.open("Donors.txt");
	// 检测打开文件是否成功
	if (!fcin.is_open())
	{
		cout << "Open error." << endl;
		exit(EXIT_FAILURE);
	}
	// 输入捐款人数
	int num_donated;
	cout << "从文件中读取捐款人数:";
	fcin >> num_donated;
	cout << endl;
	// 申请对应数量的结构数组
	Donor* pdonors = new Donor[num_donated];
	// 输入
	cout << "从文件中读取捐款人的信息:" << endl;
	for (int i = 0; i < num_donated; ++i)
	{
		// 丢弃换行符
		fcin.get();

		// 从文件中读取信息
		cout << i + 1 << ":";
		fcin.getline(pdonors[i].name, 20);
		fcin >> pdonors[i].money_donated;
		cout << endl;
	}
	cout << endl;  // 分割
	// 设置捐款大于15000为重要捐款人
	// 重要捐款人
	int empty = 1;  // 判断是否有捐款者
	cout << "Grand Patrons: " << endl;
	for (int i = 0; i < num_donated; ++i)
	{
		if (pdonors[i].money_donated > 15000)
		{
			cout << pdonors[i].name << ": " << pdonors[i].money_donated << endl;
			empty = 0;
		}
	}
	// 判断是否有捐款者
	if (empty)
		cout << "NONE" << endl;

	empty = 1;  // 重置
	cout << endl;  // 隔开两个类型

	// 其他捐款者(捐款金额大于10000)
	cout << "Patrons:" << endl;
	for (int i = 0; i < num_donated; i++)
	{
		if (pdonors[i].money_donated >= 10000 && pdonors[i].money_donated <= 15000)
			cout << pdonors[i].name << ": " << pdonors[i].money_donated << endl;
	}
	// 判断是否有捐款者
	if (empty)
		cout << "NONE" << endl;

	// 释放申请空间
	free(pdonors);
	// 关闭文件
	fcin.close();

	return 0;
}
  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值