面向对象程序设计寒假作业2
实践题
新建一个github仓库,使用git,或者github desktop把接下去的编程题的代码及测试脚本传到这个仓库。
在网页中创建一个仓库并命名
下载github desktop,在指定的目录中添加文件,如图:
请使用.gitignore文件忽略不要上传的文件。用法自行百度。
创建.gitignore文件先下载Git,然后在本地仓库所在的目录中右键Git Bash Here
输入touch .gitignore创建.gitignore文件
找到空白的.gitignore文件,对.gitignore文件进行编辑,并且设置过滤规则
过滤规则如下:
1、跳过单个文件:
比如我需要跳过 project.config.json 这个文件,可以这样写:
project.config.json
2、跳过某个格式的文件:
比如 .zip 、 .config 、 .sln 格式的文件,代码如下:
*.zip*.config*.sln
3、跳过某个文件夹:
比如跳过 Debug 文件夹,代码如下:
Debug/
4、过滤某个文件夹中的某个文件或者某个格式:
Debug/test.exeDebug/*.zip
5、指定添加某个文件、文件夹或者格式:(前面加感叹号"!")
!/mtk/one.txt!/mtk/!*.zip
开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。
6、[] 过滤多个文件或者类型
# cat .gitignore *.[oa] *~
第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。
一般这类对象文件和存档文件都是编译过程中出现的,我们用不着跟踪它们的版本。
第二行告诉 Git 忽略所有以波浪符(~)结尾的文件
一起上传.gitignore文件即完成操作
编程题优化
(1)继续完成作业一的编程题。
(2)优化架构,一般要求每个函数长度不超过15行。
(3)优化规范,尤其是命名规范。
(4)制作一个编译脚本,运行该脚本可以编译你的代码,可选的脚本语言,python(2.7),windows批处理,powershell,shell。
示例脚本:
gcc 1.cpp -o lang.exe
进行单元测试,即测试每一个函数,并制作一个测试脚本,运行该脚本可以进行测试,并显示测试结果。
示例脚本:
gcc 1.cpp test.cpp -o test.exetest
在作业一编程题的基础上添加以下功能:
o通过命令行读取一个文件,然后运行这个文件。如我的程序叫lang,lang 1.txt代表我要运行1.txt这个文本中的代码。
o假设我的1.txt内容如下:
整数 钱包 等于 零
钱包 增加 四
钱包 减少 三
看看 钱包
o输入lang 1.txt后,命令行输出一。
编程题要求:
1.读题,提取出题目的要求。
2.分解需求,把需求分解为几个你觉得不太相关的模块。
3.思考每个模块怎么写,可以从简单的模块开始写。
4.对于不会的问题进行查阅资料。
5.对于每一个模块设计测试用例。
6.详细记录下以上每一步,并写在博客中。
7.不要求完全做出来,但要求记录详细。
8.建议博客长度不少于1000字(不包含代码)。
1.题目要求:
白话文编程要满足变量的定义,能够根据输入的白话文进行加减运算,且能输出正确结果
2.分解需求:
(1)编写transform函数,将白话文形式的零到十转换为数字
(2)以transform函数为辅编写函数change,使计算范围扩大为100以内
(3)加减运算合并为一个calculate函数
(4)编写主函数(遇到“看看 xxx”时就输出结果的判断在主函数中体现)
3.思考过程:
针对前一次的作业,我提出了第一个函数——转换函数除了通过个个枚举的方式能否用其他方式的疑问,虽然原代码长度就不超过15行,我通过参考同学的博客发现可以改变先前用个个枚举的方法,先将汉字的数按顺序排列为二维的字符数组,输入白话####文的数字后遍历比较字符串,找到后返回对应的数字形式。这样的方式可以有效地使转换函数的代码量减少。
原转换函数如下:
int transform(char str[]){
if(strcmp("零",str)==0)return 0;
if(strcmp("一",str)==0)return 1;
if(strcmp("二",str)==0)return 2;
if(strcmp("三",str)==0)return 3;
if(strcmp("四",str)==0)return 4;
if(strcmp("五",str)==0)return 5;
if(strcmp("六",str)==0)return 6;
if(strcmp("七",str)==0)return 7;
if(strcmp("八",str)==0)return 8;
if(strcmp("九",str)==0)return 9;
if(strcmp("十",str)==0)return 10;
//个个枚举
}
通过参考优化后的转换函数如下:
char num[15][5]={"零","一","二","三","四","五","六","七","八","九","十"};
//改变作业一中通过个个比较字符串的做法,先将汉字按顺序排成列表
int transform(char z[]){
int i;
for(i=0;i<11;i++){
if(strcmp(z,num[i])==0) return i;//比较字符串,返回汉字的数字形式
}
}
由以上使用二维字符数组列表来转换白话文和数字的方式可以联想到原代码中数字转白话文的result函数可以删除,直接在主函数中体现
原代码的加减函数的运算仅限制于十以内的加减运算,若要将运算量扩大为100以内编写一下change函数.
char str1[20],str2[20];
int change(char d[]){//d数组为读入用于计算的量,一个汉字的字符串长度为2
if(strlen(d)==2) return transform(d);//不超过十的数直接用transform函数进行转换
if(strlen(d)==4){//长度为4,对应两个汉字
str1[0]=d[2];str1[1]=d[3];str1[2]='\0'; //一种情况对应十开头的数 ,将第二个汉字赋给str1数组
if(transform(str1)!=10) return transform(str1)+10;
else{
str1[0]=d[0];str1[1]=d[1];str1[2]='\0';//另一种情况为十结尾的数字,将第一个汉字赋给str1数组
return 10*transform(str1);
}}
if(strlen(d)==6){
str1[0]=d[0];str1[1]=d[1];str1[2]='\0';str2[0]=d[4];str2[1]=d[5];str2[2]='\0';//几十几的类型,分别将第一个汉字和末尾汉字赋个str1和str2
return transform(str1)*10+transform(str2);
}}
优化加减运算函数:原来的加减运算函数只能计算十以内的数,编写以上change函数后可以进行更大的运算,比较字符串判断是加运算还是减运算后再进行计算,可将原来的两个进行加减运算的函数合并为一个calculate函数:
int calculate(int sum,char c[],char d[]){//将原来的加减运算合并为一个calculate函数
if(strcmp(c,"增加")==0) return sum+change(d);
if(strcmp(c,"减少")==0) return sum-change(d);
}
明显相对于原来的个个枚举的情况代码量减少了且运算范围增大了
对主函数进行修改,将局限于原来十以内的运算扩大为100以内
int main(){
char a[100],b[100],c[100],d[100];
scanf("%s %s %s %s",a,b,c,d);
char m[100],n[100],s[100],t[100];
sum=change(d);getchar();
for(;;){
scanf("%s",m);
if(strcmp("看看",m)==0) break;
scanf("%s",n);
scanf("%s",s);
if(strcmp("增加",n)==0) sum+=change(s);
if(strcmp("减少",n)==0) sum-=change(s);
}
scanf("%s",t);
if(sum<=10) printf("%s",num[sum]);
if(sum>10){
int a;
a=sum/10;
if(a==1) printf("十");
else{
printf("%s",num[a]);
printf("十");
}
int b;
b=sum%10;
if(b!=0) printf("%s",num[b]);
}
return 0;
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
int sum;
char num[15][5]={"零","一","二","三","四","五","六","七","八","九","十"};
//改变作业一中通过个个比较字符串的做法,先将汉字按顺序排成列表
int transform(char z[]){
int i;
for(i=0;i<11;i++){
if(strcmp(z,num[i])==0) return i;//比较字符串,返回汉字的数字形式,transform函数用于辅助下面的change函数
}
}
char str1[20],str2[20];
int change(char d[]){//d数组为读入用于计算的量,一个汉字的字符串长度为2
if(strlen(d)==2) return transform(d);//不超过十的数直接用transform函数进行转换
if(strlen(d)==4){//长度为4,对应两个汉字
str1[0]=d[2];str1[1]=d[3];str1[2]='\0'; //一种情况对应十开头的数 ,将第二个汉字赋给str1数组
if(transform(str1)!=10) return transform(str1)+10;
else{
str1[0]=d[0];str1[1]=d[1];str1[2]='\0';//另一种情况为十结尾的数字,将第一个汉字赋给str1数组
return 10*transform(str1);
}}
if(strlen(d)==6){
str1[0]=d[0];str1[1]=d[1];str1[2]='\0';str2[0]=d[4];str2[1]=d[5];str2[2]='\0';//几十几的类型,分别将第一个汉字和末尾汉字赋个str1和str2
return transform(str1)*10+transform(str2);
}}
int calculate(int sum,char c[],char d[]){//将原来的加减运算合并为一个calculate函数
if(strcmp(c,"增加")==0) return sum+change(d);
if(strcmp(c,"减少")==0) return sum-change(d);
}
int main(){
char a[100],b[100],c[100],d[100];
scanf("%s %s %s %s",a,b,c,d);
char m[100],n[100],s[100],t[100];
sum=change(d);getchar();
for(;;){
scanf("%s",m);
if(strcmp("看看",m)==0) break;
scanf("%s",n);
scanf("%s",s);
if(strcmp("增加",n)==0) sum+=change(s);
if(strcmp("减少",n)==0) sum-=change(s);
}
scanf("%s",t);
if(sum<=10) printf("%s",num[sum]);
if(sum>10){
int a;
a=sum/10;
if(a==1) printf("十");
else{
printf("%s",num[a]);
printf("十");
}
int b;
b=sum%10;
if(b!=0) printf("%s",num[b]);
}
return 0;
}
4.编译脚本
编辑完后重命名
但文件类型仍然显示文本文档,通过查阅资料可知,文件的扩展名被自动隐藏了
打开我的电脑在查看中勾选文件扩展名
勾选后再次重命名
编译后如图
再次编辑如图:
疑问:要生成如下的.exe文件,路径问题到底应该怎么解决?
5.单元测试:
参考同学的博客,模仿写得以下内容:
重命名后得: