1 实验目的
(1)学习如何使用结构体的指针作为函数的参数,通过传指针(本质也是传值)的方式,在被调用函数中修改主调函数中的多个结构体变量的方法。
(2)学习如何把逻辑结构相同的部分抽象为函数,以提高代码的可重用性,达到提高程序可维护性的目的。
2 实验内容
2.1 模拟画图功能
(1)问题描述
模拟计算机的画图功能,能够模拟画圆和长方形的功能。程序主要功能如下:
① 提供一个如下的主菜单。
- Circle (圆)
- Rectangle (长方形)
- Exit (退出)
② 不断接受用户的选择(整数),直至用户选择0为止。如果用户输入了系统尚未支持的选择(比如3),则给出相应的提示信息,并继续选择。
③ 如果用户选择了圆或长方形,则进一步提示用户输入两个点,分别称为起点和终点,如下图所示。坐标仅考虑正整数的情况。要求终点的坐标大于起点的坐标,否则给出相关的提示信息并返回主菜单。
图1. 显示屏的坐标系与起点、终点位置
④ 模拟画出圆和长方形。画圆时,要计算startPoint和endPoint所构成的正方形的内切圆的圆心和半径。若startPoint和endPoint所构成的不是正方形,则给出相关的提示信息并返回主菜单。
(2)问题要求
① 定义一个Point结构体,用来表示显示屏上的点;
② 实现以下函数(图2),使得主程序(图3)输出图4中的结果。
图2. 需要实现的函数雏形
主程序如图3所示。
图3. 主程序
运行结果如图4所示。
图4. 运行结果
注意,上述结果未能列出所有可能的执行情况。请认真思考,相关的提示信息应该分别在由哪些函数中输出?
源代码:
#include<iostream>
using namespace std;
struct Point {
int x;
int y;
};
void displayMenu() {
cout << "***********************************" << endl;
cout << " 1. Circle(圆)" << endl;
cout << " 2. Rectangle(长方形)" << endl;
cout << " 0. Exit(退出)" << endl;
cout << "***********************************" << endl;
cout << "Please select the shape: ";
}
void getTwoPoints(struct Point* startP, struct Point* endP) {
cout << "Please input the coordinate(x,y) of the start point: ";
cin >> startP->x;
cin >> startP->y;
cout << "Please input the coordinate(x,y) of the end point: ";
cin >> endP->x;
cin >> endP->y;
}
void printPoint(struct Point* P) {
cout << "(" << P->x << "," << P->y << ")" ;
}
void drawCircle(struct Point* startP, struct Point* endP) {
struct Point center; // 圆心坐标
int radius; // 半径
if ((endP->x - startP->x) != (endP->y - startP->y))
cout << "Not a circle, Select again\n";
else {
center.x = (startP->x + endP->x)/2; // 计算圆心横坐标
center.y = (startP->y + endP->y)/2; // 计算圆心纵坐标
radius = (endP->x - startP->x)/2; // 计算半径
// 模拟画圆
cout << "Draw a circle at center ";
printPoint(¢er);
cout << " with radius " << radius << endl;
}
}
void drawRectangle(struct Point* startP, struct Point* endP) {
int width, height;
width = endP->x - startP->x; // 长
height = endP->y - startP->y; // 宽
// 模拟画长方形
cout << "Draw a rectangle at topleft ";
printPoint(startP);
cout << ", whose width is " << width << " and height is " << height << endl;
}
int main() {
int choice = 1; // 用户选择
struct Point startP; // 起点
struct Point endP; // 终点
while (choice) {
displayMenu();
cin >> choice;
switch (choice) {
case 1:
getTwoPoints(&startP, &endP);
drawCircle(&startP, &endP);
break;
case 2:
getTwoPoints(&startP, &endP);
drawRectangle(&startP, &endP);
break;
case 0:
cout << "Good Bye!\n";
break;
default:
cout << "Error Input! Please select again!\n";
break;
}
}
}
2.2 计算所得税
(1)问题描述
一个国家计算所得税的规则由如下的不确定多条规则构成:
其中,n是规则的条数,由用户输入。对于任意的 , 表示个人收入中在区间 的部分的税率,它是一个整数,代表百分之几。 为税率起征点, 。
(2)问题要求
① 请定义一个结构体,用来存放一条规则。
② 根据用户输入的规则条数,使用结构体的数组存放所有的规则。
③ 定义一个子函数inputRules(struct Rule rules[], int n),根据用户输入的规则条数,从键盘得到所有规则,存放至数组。
④ 定义一个子函数计算所得税。
// 参数income表示个人收入
double computeTax(struct Rule rules[], int n, int income);
⑤ 在主函数中,一次录入规则后,可以循环计算任意多个人的所得税,直到输入的收入为-1为止。
⑥ 请至少测试以下情况
输入规则后,在录入收入时,直接录入-1;
收入为0;
收入小于 ;
收入等于 的各种情况;
收入大于 ;
收入在 和 之间的情况。
(3)程序运行要求
程序的一次运行结果如下:
①
请输入规则的条数:3
请输入第 1 条规则:800 3
请输入第 2 条规则:2000 4
请输入第 3 条规则:5000 3
②
纳税规则如下:
纳税线 税率
800 3
2000 4
5000 3
③
请输入您的收入:0
您的收入是:0,应缴所得税:0.00元。
④
请输入您的收入:800
您的收入是:800,应缴所得税:0.00元。
⑤
请输入您的收入:801
您的收入是:801,应缴所得税:0.03元。
⑥
请输入您的收入:2000
您的收入是:2000,应缴所得税:36.00元。
(2000 – 800) × 3 / 100
⑦
请输入您的收入:1999
您的收入是:1999,应缴所得税:35.97元。
⑧
请输入您的收入:5000
您的收入是:5000,应缴所得税:156.00元。
[(2000 – 800) × 3 + (5000 – 2000) × 4] / 100
请输入您的收入:10000
您的收入是:10000,应缴所得税:306.00元。
[(2000 – 800) × 3 + (5000 – 2000) × 4 + (10000 – 5000) × 3] / 100
⑨
请输入您的收入:-1
再见
请按任意键继续···
```cpp
#include<iostream>
using namespace std;
struct Rule {
int M;
int R;
};
void inputRules(struct Rule rules[], int n) {
for (int i=0; i < n; i++) {
printf("请输入第%d条规则:", i + 1);
cin >> rules[i].M >> rules[i].R;
}
}
void outputRules(struct Rule rules[], int n) {
cout << "\t纳税线\t\t税率" << endl;
for (int i = 0; i < n; i++) {
cout << "\t" << rules[i].M << "\t\t\t" << rules[i].R << endl;
}
}
double computeTax(struct Rule rules[], int n, int income) {
double sum = 0;
if (income <= rules[0].M)
return sum;
else {
if (income >= rules[n - 1].M) {
for (int i = 0; i < n - 1; i++) {
sum += 0.01 * (double)((rules[i + 1].M - rules[i].M) * rules[i].R);
}
sum += 0.01 * (double)((income - rules[n - 1].M) * rules[n - 1].R);
return sum;
}
for (int i = 0; i < n - 1; i++) {
if (income >= rules[i].M && income < rules[i + 1].M) {
for (int k = 0; k < i; k++) {
sum += 0.01 * (double)((rules[k + 1].M - rules[k].M) * rules[k].R);
}
sum += 0.01 *(double)((income - rules[i].M) * rules[i].R) ;
return sum;
}
}
}
}
int main() {
int count;
int income;
struct Rule rules[20];
cout<<"请输入规则的条数:";
cin >> count;
inputRules(rules, count);
outputRules(rules, count);
cout << "请输入您的收入:";
cin >> income;
while (income != -1) {
cout<<"您的收入是:"<<income<<"应缴所得税:"<< computeTax(rules, count, income)<<endl;
cout << "请输入您的收入:";
cin >> income;
}
}