C++ 砺儒云课堂作业 第9章 模块化开发

简答题:

1.用自己的话描述逐步细化的过程。

答:逐步细化就是将一个大问题分成若干个小问题,小问题分解成小小问题,直到一个问题可以用一段小程序实现为止。每个问题的解决过程是一个函数,实现小问题的函数通过调用解决小小问题的函数来实现。解决大问题的函数通过调用解决小问题的函数来实现。在解决一个较大的问题时,只需要知道有哪些可供调用的解决小问题的函数,而不必关心这些解决小问题的函数是如何实现的。这样可以在一个更高的抽象层次上解决大问题。

2.为什么库的实现文件要包含自己的头文件?

答:以便编译器能检查源文件中的函数定义和头文件中的函数原型声明的一致性。

3.为什么头文件要包含#ifndef...#endif这个编译预处理指令?

答:这个预处理命令表示:

如果指定的标识符没有被定义,则执行后面的语句,直到#endif。

如果该标识符已经被定义,则中间的这些语句都不执行,直接跳到#endif。这一对编译预处理命令也被称为头文件保护符。

这样可以防止同一程序的各个模块中重复包含同一个头文件而带来的问题。

程序设计题:

4.哥德巴赫猜想指出:任何一个大于6的偶数都可以表示成两个素数之和。编写一个程序,列出指定范围内的所有偶数的分解。

答:

#include <iostream>  
using namespace std;

int function(int i);

int main()
{
	int left, right;

	cout << "哥德巴赫猜想指出:任何一个大于6的偶数都可以表示成两个素数之和。" << endl;
	cout << "列出指定范围内的所有偶数的分解。" << endl << endl;

number0:
	cout << "请输入左边界:";
	cin >> left;
	if (left <= 6)
	{
		cout << "输入错误!请重新输入" << endl << endl;
		goto number0;
	}
	cout << "请输入右边界:";
	cin >> right;

	if (left % 2 != 0) left = left + 1;
	if (right % 2 != 0) right = right - 1;
	
	cout << endl;
	for (int i = left; i <= right; i = i + 2)
	{
		for (int j = 3; j < right; j = j + 2)
		{
			if (i - j < i / 2) break;
			else
			{
				if ((function(j) == 1)&(function(i - j) == 1)) cout << i << "=" << j << "+" << i - j << endl;
			}
		}
	}
	cout << endl;
	
	system("pause");
	return 0;
}

int function(int i)
{
	//排除掉无法用开平方法的整数  
	if ((i == 3) | (i == 5) | (i == 7)) return 1;

	//试除  
	else
	{
		for (int k = 3; k <= sqrt(i); ++k)
		{
			if (i % k == 0) return 0;
		}

		//什么事也没发生,成功逃离  
		return 1;
	}
}


5.在每本书中,都会有很多图或表。图要有图号,表要有表号。图号和表号都是连续的,如一本书的图号可以编号为:图1、图2、图3、……。设计一个库seq,它可以提供这样的标签系列。该库提供给用户3个函数:void SetLabel(const char *)、void SetInitNumber(int)和char *GetNextLabel()。第一个函数设置标签,如果SetLabel("图"),则生成的标签为图1、图2、图3、……;如果SetLabel("表"),则生成的标签为表1、表2、表3、……;如不调用此函数,则默认的标签为"label"。第二个函数设置起始序号,如SetInitNumber(0),则编号从0开始生成;SetInitNumber(9),则编号从9开始生成。第三个函数是获取标签号。例如,如果一开始设置了SetLabel("图")和SetInitNumber(0),则第一次调用GetNextLabel()返回“图0”,第二次调用GetNextLabel()返回“图1”,依次类推。


答:

seq.h

#ifndef SEQ
#define SEQ

void SetLabel(const char *);	//设置标签
void SetInitNumber(int);	//设置起始序号
char *GetNextLabel();	//获取标签号

#endif

seq.cpp

#include <iostream>
#include <string>	//不知道为什么,to_string函数不在cstring里
#include "seq.h"
using namespace std;

string str1 = "label";	//默认为label
int no;

void SetLabel(const char *s)	//设置标签
{
	if (strlen(s) == 2) str1 = s;	//默认为label,否则改为"图"或"表"
}

void SetInitNumber(int num)	//设置起始序号
{
	no = num;
}

char *GetNextLabel()	//获取标签号
{
	string str2 = to_string(no);
	string str0 = str1 + str2;
	
	no = no + 1;

	char *str = new char[str0.length() + 1];
	strcpy(str, str0.c_str());	//str0.c_str():把str0转换为char*类型

	return str;
}

源.cpp

#include <iostream>
#include "seq.h"
using namespace std;
int main()
{
	int judge, i;
	char *result;
	
	SetLabel("图");	//()里也可以是"表"或""
	SetInitNumber(1);	//()里为起始序号
	
number0:
	result = GetNextLabel();
	
	for (i = 0; result[i] != '\0'; ++i)
	{
		cout << result[i];
	}
	
	cout << endl << endl << "请问是否要继续调用GetNextLabel()函数?" << endl << "若是请按1,若否请按除了1以外的任意键:";
	cin >> judge;
	cout << endl;

	if (judge == 1) goto number0;
	else
	{
		system("pause");
		return 0;
	}
}


6.用结构体表示一个复数,编写实现复数的加法、乘法、输入和输出的函数,并测试这些函数。

加法规则:(a+bi)+(c+di)=(a+c)+(b+d)i。

乘法规则:(a+bi)×(c+di)=(ac-bd)+(bc+ad)i。输入规则:分别输入实部和虚部。

输出规则:如果a是实部,b是虚部,输出格式为a +bi。

试将第8章程序设计题的第1题改写成一个库。

答:

complex.h

#ifndef COMPLEX_NUMBER
#define COMPLEX_NUMBER

struct dataT
{
	double real;
	double imaginary;
};

dataT Cin();	//输入
void Cout(dataT result);	//输出
dataT Addition(dataT data1, dataT data2);	//加法
dataT Multiplication(dataT data1, dataT data2);	//乘法

#endif

complex.cpp

#include <iostream>
#include "complex.h"
using namespace std;

dataT Cin()	//输入
{
	dataT data;

	cout << "请输入一个复数:" << endl << "实部:";
	cin >> data.real;
	cout << "虚部:";
	cin >> data.imaginary;
	cout << endl;

	return data;
}

dataT Addition(dataT data1, dataT data2)	//加法
{
	dataT result;

	result.real = data1.real + data2.real;
	result.imaginary = data1.imaginary + data2.imaginary;

	return result;
}

dataT Multiplication(dataT data1, dataT data2)	//乘法
{
	dataT result;

	result.real = data1.real * data2.real - data1.imaginary * data2.imaginary;
	result.imaginary = data1.imaginary * data2.real + data1.real* data2.imaginary;
	return result;
}

void Cout(dataT result)	//输出
{
	cout << "结果为:" << result.real << "+" << result.imaginary << "i";
}

源.cpp

#include <iostream>
#include "complex.h"
using namespace std;
int main()
{
	struct dataT
	{
		double real;
		double imaginary;
	};
	
	int judge;

	cout << "复数的库" << endl << endl << "功能:" << endl;
	cout << "1.加法" << endl << "2.乘法" << endl << endl;
number0:
	cout << "请输入你需要的功能:";
	cin >> judge;
	cout << endl;

	if (judge == 1) Cout(Addition(Cin(), Cin()));
	else if (judge == 2) Cout(Multiplication(Cin(), Cin()));
	else
	{
		cout << "错误!";
		goto number0;
	}
	
	cout << endl << endl;
	system("pause");
	return 0;
}


7. 设计一个类似于cstring的字符串处理库,该库提供一组常用的字符串的操作,包括字符串复制、字符串拼接、字符串比较、求字符串长度和取字符串的子串。

答:

simulate_string.h

#ifndef simulatestring
#define simulatestring

using namespace std;

void Copy(char *);	//复制
void Connect(char *, char *);	//拼接
void Compare(char *, char *);	//比较
void Length(char *);	//求长度
void Pick(char *);	//取子串

#endif

simulate_string.cpp

#include <iostream>
#include "simulate_string.h"
using namespace std;

void Copy(char *s)	//复制
{
	int len = strlen(s), i;
	char *s_new = new char[len + 1];

	for (i = 0; i <= len; ++i)
	{
		s_new[i] = s[i];
	}

	cout << s << "复制后为:" << s_new;
}

void Connect(char *s1, char *s2)	//拼接
{
	int len1 = strlen(s1), len2 = strlen(s2), i;
	char *s3 = new char[len1 + len2 + 1];

	for (i = 0; i < len1; ++i)
	{
		s3[i] = s1[i];
	}
	for (i = len1; i < len1 + len2 + 1; ++i)
	{
		s3[i] = s2[i - len1];
	}

	cout << s1 << "和" << s2 << "拼接后为:" << s3;
}

void Compare(char *s1, char *s2)	//比较
{
	int len1 = strlen(s1), len2 = strlen(s2);

	if (len1 != len2) cout << s1 << "与" << s2 << "不相等";
	else
	{
		bool judge = true;

		for (int i = 0; i < len1; ++i)
		{
			if (s1[i] != s2[i])
			{
				judge = false;
				break;
			}
		}

		if (judge == true) cout << s1 << "与" << s2 << "相等";
		else cout << s1 << "与" << s2 << "不相等";
	}
}

void Length(char *s)	//求长度
{
	cout << s << "的长度为:" << strlen(s);
}

void Pick(char *s)	//取子串
{
	int start, end, len = strlen(s);
	
	cout << "请输入初始位置:";
	cin >> start;
	cout << "请输入结束位置:";
	cin >> end;

	while ((start < 1) | (start > len))
	{
		cout << "错误!请重新输入初始位置:";
		cin >> start;
	}
	while ((end < start) | (end > len))
	{
		cout << "错误!请重新输入结束位置:";
		cin >> end;
	}

	cout << s << "的子串为:";
	for (int i = start - 1; i < end; ++i)
	{
		cout << s[i];
	}
}

源.cpp

#include <iostream>
#include "simulate_string.h"
using namespace std;

int main()
{
	int choice;
	const int length = 1000;

	cout << "类似于cstring的字符串处理库" << endl << endl;
	cout << "功能:" << endl;
	cout << "1.字符串复制" << endl;
	cout << "2.字符串拼接" << endl;
	cout << "3.字符串比较" << endl;
	cout << "4.求字符串长度" << endl;
	cout << "5.取字符串的子串" << endl;
	cout << "0.退出程序" << endl << endl;

	do
	{
		cout << "请输入你要实现的功能:";
	number0:
		cin >> choice;

		if (choice == 0) cout << "程序退出!";

		else if ((choice < 0)&(choice > 5))
		{
			cout << "错误!请重新输入你要实现的功能:";
			goto number0;
		}

		else
		{
			if ((choice == 1) | (choice == 4) | (choice == 5))
			{
				char s[length];

				cout << "请输入一个字符串:";
				cin >> s;

				if (choice == 1) Copy(s);	//复制
				if (choice == 4) Length(s);	//求长度
				if (choice == 5) Pick(s);	//取子串
			}

			if ((choice == 2) | (choice == 3))
			{
				char s1[length], s2[length];

				cout << "请输入第一个字符串:";
				cin >> s1;
				cout << "请输入第二个字符串:";
				cin >> s2;

				if (choice == 2) Connect(s1, s2);	//拼接
				if (choice == 3) Compare(s1, s2);	//比较
			}
		}
		
		cout << endl << endl;
	} while (choice != 0);

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41013202/article/details/79953069