这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/2020OOP |
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/2020OOP/homework/10224 |
这个作业的目标 | 思考C语言的缺陷,了解C语言/C++的编译过程,运用命令行编译C语言,完成一道编程 |
作业正文 | 1.问答题 2.实践题 3.编程题 |
参考文献 | https://www.cnblogs.com/zzdbullet/p/9911226.html https://blog.csdn.net/heihei2017/article/details/95048581
https://www.cnblogs.com/BooneZan/p/7924248.html
https://jingyan.baidu.com/article/5553fa828d836765a23934e7.html
https://blog.csdn.net/jjz2016/article/details/79376622
|
一、问答题
1.如果你不了解C++请回答以下问题:你认为C语言有什么缺陷(你觉得哪里用的不顺手)。
如果你已经了解C++请回答以下问题:你觉得C++和C语言比有什么优点。
我对于C++还不怎么了解,在学习C语言的过程中发现了一点问题。
(1)C语言对于数组的下标越界没有做检查,同时自己也不容易发现,因此常常出错。
(2)在指针当中表示二维数组的同一个地址的方式很多,表示不同地址的方式也很相似,有时会混淆。
(3)存在一些不够安全的函数,例如gets()函数,不会判断上限,只是以回车结束,容易发生溢出。
同时,通过查阅资料了解到:C语言不够安全,原因是C语言使用时间较长、编写的代码数量多、集中程度高,容易出现开源漏洞。
2. 查阅相关资料,简述一下C语言/C++的编译过程。
过程:预处理—编译—汇编—链接
(1)预处理:处理#include、#define和条件编译语句,把include文件中的内容复制到源文件,根据define的定义进行替换,并且删除不符合编译条件的语句,只剩下符合的语句。
(2)编译:通过词法分析、语法分析和语义分析,检查有没有语法错误,并将高级语言转换为汇编语言。
(3)汇编:将汇编语言再转换为机器语言,生成二进制文件也就是目标文件。
(4)链接:汇编之后的文件还不能直接运行,还要通过链接,将生成的文件组合为可执行文件,使每个源文件能够调用到其他源文件的函数,并且把所需的库函数的代码也组合到文件中去。
参考资料:
https://www.cnblogs.com/zzdbullet/p/9911226.html
https://blog.csdn.net/heihei2017/article/details/95048581
二、实践题
1.查看自己的C++编译器版本。
通过百度,了解到可以用gcc-v查看版本信息。
但是我在visual studio的工具—命令行—开发者命令提示 中输入gcc-v之后,显示不对。
于是我再查找资料,得知要查看是否安装GNU和是否配置环境变量,但是我查了资料,看不太懂怎么配置,找不到路径,尝试了很久也不会。之后我问了同学,不用输gcc-v,输入cl.exe就可以了,于是我改成输入cl.exe,结果如下
参考资料:
https://www.cnblogs.com/BooneZan/p/7924248.html
https://jingyan.baidu.com/article/5553fa828d836765a23934e7.html
2.使用命令行编译一份C语言/C++代码。
通过查阅资料,得知命令行的运行方法:
(1)编写代码
(2)点击开始--运行--输入--CMD 回车(或按windows键和R键弹出运行框—输入CMD回车)
(3)输入指令
参考资料:
https://blog.csdn.net/jjz2016/article/details/79376622
三、编程题
1.读题
题目要求将中文转化为数字,并且用中文输入,同时在其中进行运算,最后仍是以中文输出数字。
2.分解
我认为题目可以分成这几个方块:起始输入及中文数字转换、中间输入及中文数字转换并运算、数字中文转换并输出。其中数字中文转换的我觉得可以用函数来写,可以稍微简洁一些。
3.分模块解决
首先,我觉得应该是要用字符数组来做。然后考虑到中文一个字占2个字符,因此我觉得不能用字符数组的单个元素判断是否 “ 等于 ”,所以只能用strcmp函数来代替 “ 等于 ”。
首先是中文转换为数字的函数
int tran(char s[20]) { int num=0; flag=0; if(strcmp(s,"零")==0) num=0; else if(strcmp(s,"一")==0) num=1; else if(strcmp(s,"二")==0) num=2; else if(strcmp(s,"三")==0) num=3; else if(strcmp(s,"四")==0) num=4; else if(strcmp(s,"五")==0) num=5; else if(strcmp(s,"六")==0) num=6; else if(strcmp(s,"七")==0) num=7; else if(strcmp(s,"八")==0) num=8; else if(strcmp(s,"九")==0) num=9; else if(strcmp(s,"十")==0) num=10; else { flag=1; printf("数字输入有误,请重新输入\n"); } return num; }
(1)起始输入及中文数字转换:
利用字符串完成输入,并运用strcmp函数,就可以判断输入是否符合语法、输入的数字是多少,以及完成数字与中文的转换。其中循环用来在输入不符合语法时重新输入,并且在不符合语法时会提示重新输入。函数用来将中文转换为数字,从而得到sum的初始值。里面用了很多个嵌套if,但是不知道怎么简化。
for(i=0;;i++)
{
printf("请输入“整数 钱包 等于 初始数值”\n");
scanf("%s",a);
if(strcmp(a,"整数"))
{
printf("输入有误,请重新输入\n");
continue;
}
else
{
scanf("%s",b);
if(strcmp(b,"钱包"))
{
printf("输入有误,请重新输入\n");
continue;
}
else
{
scanf("%s",c);
if(strcmp(c,"等于"))
{
printf("输入有误,请重新输入\n");
continue;
}
else
{
scanf("%s",d);
sum=tran(d);
if(flag==1) continue;
else break;
}
}
}
}
运行如下:(含输入不符合语法的情况,并输出了钱包的初始值来看看有没有错)。
(2)完成中间过程的输入:
与起始值输入类似,也是运用strcmp函数判断语法是否正确,并且在不符合语法时会提示重新输入。然后也是用了一个函数,将中文转换为数字,这样运算就不会很难了。其中有两个循环。一个与起始输入一样是为了输入符合语法,还有一个循环来进行多次的运算,最后再用 if 语句来判断是否结束外层的循环。也是用了很多嵌套if语句。
printf("请输入“钱包 运算 数字”或“看看 钱包”\n"); for(j=1;flag2;j++) { for(i=1;;i++) { scanf("%s",e); if(strcmp(e,"钱包")&&strcmp(e,"看看")) { printf("输入有误,请重新输入\n"); continue; } else { if(strcmp(e,"钱包")==0) { scanf("%s",f); if(strcmp(f,"增加")&&strcmp(f,"减少")) { printf("输入有误,请重新输入\n"); continue; } else { scanf("%s",g); k=tran(g); if(strcmp(f,"增加")==0) sum+=k; else { if(sum"运算后会使钱包变为负数,请重新输入\n"); else sum-=k; } } } else { scanf("%s",f); if(strcmp(f,"钱包")) { printf("输入有误,请重新输入\n"); continue; } else { flag2=0; break; } } } } } printf("%d",sum);
运行如下:(包含输入不符合语法的情况,并输出了sum的数值来看看有没有错)
(3)转换并输出:
写了两个函数将中文转化为数字,要考虑到个位数、十位数、百位数的情况(千位数太大了没办法测试)。一个函数用于把数字拆成每个位数上的数,另一个函数用于将单个中文转换为数字。其中特殊情况有:十几、几百零几、整十位及整百位。
void pt(int w)
{
void tran2(int m);
int p,q;
p=w/100;
q=w%10;
if(w<=10) tran2(w);
else if(w>10&&w<20)
{
printf("十");
tran2(w%10);
}
else if(w>=20&&w<100)
{
tran2(w/10);
printf("十");
if(w/10!=0) tran2(w%10);
}
else if(w>=100)
{
tran2(w/100);
printf("百");
if((w-p*100)>=10)
{
tran2((w-p*100)/10);
printf("十");
if(w%10!=0) tran2(w%10);
}
else if((w-p*100)>0&&(w-p*100)<10)
{
printf("零");
tran2(w%10);
}
}
}
void tran2(int m)
{
switch (m)
{
case 0: printf("零");break;
case 1:printf("一");break;
case 2:printf("二");break;
case 3:printf("三");break;
case 4:printf("四");break;
case 5:printf("五");break;
case 6:printf("六");break;
case 7:printf("七");break;
case 8:printf("八");break;
case 9:printf("九");break;
case 10:printf("十");
}
}
整百整十的情况:
整百的情况
十几的情况
几百零几的情况
总结:
在做的过程中有一些碰到一些问题:
1.)变量比较多容易乱
2)刚开始设置变量时没有设成全局变量,导致用指针来做,感觉很麻烦,而且一直出错,因为指针的知识感觉比较多有点乱了,于是换成了全局变量。
3)在群里好像有看到变量不一定是 “ 钱包 ” ,于是直接把原来的 “ 钱包 ” 换成了字符串,但是不确定可不可以这样。
4)还有一些问题,但是尝试了很久也不知道怎么修改,例如有时候输入不符合语法时,会多次输出“请重新输入”,我觉得可能是在输入的判断上有问题或者continue用错了,但是改来改去都不对,最后还是不知道怎么修改。
(参考资料主要是课本)
最后总代码如下:
#include#include<string.h> char a[20],b[20],c[20],d[20],e[20],f[20],g[20],h[20]; int sum=0,flag=1,flag2=1; int main() { int tran(char s[20]); void pt(int w); void tran2(int m); int i,j,k; printf("请输入“整数 物品 等于 初始数值”\n"); for(i=0;;i++) { scanf("%s",a); if(strcmp(a,"整数")) { printf("输入有误,请重新输入\n"); continue; } else { scanf("%s%s",b,c); if(strcmp(c,"等于")) { printf("输入有误,请重新输入\n"); continue; } else { scanf("%s",d); sum=tran(d); if(flag==1) continue; else break; } } } printf("请输入“%s 运算 数字”或“看看 %s”\n",b,b); for(j=1;flag2;j++) { for(i=1;;i++) { scanf("%s%s",e,f); if(strcmp(e,b)&&strcmp(e,"看看")) { printf("输入有误,请重新输入\n"); continue; } else { if(strcmp(e,b)==0) { if(strcmp(f,"增加")&&strcmp(f,"减少")) { printf("输入有误,请重新输入\n"); continue; } else { scanf("%s",g); k=tran(g); if(strcmp(f,"增加")==0) sum+=k; else { if(sum "运算后会使%s变为负数,请重新输入\n",b); else sum-=k; } } } else { if(strcmp(f,b)) { printf("输入有误,请重新输入\n"); continue; } else { flag2=0; break; } } } } } pt(sum); return 0; } int tran(char s[20]) { int num=0; flag=0; if(strcmp(s,"零")==0) num=0; else if(strcmp(s,"一")==0) num=1; else if(strcmp(s,"二")==0) num=2; else if(strcmp(s,"三")==0) num=3; else if(strcmp(s,"四")==0) num=4; else if(strcmp(s,"五")==0) num=5; else if(strcmp(s,"六")==0) num=6; else if(strcmp(s,"七")==0) num=7; else if(strcmp(s,"八")==0) num=8; else if(strcmp(s,"九")==0) num=9; else if(strcmp(s,"十")==0) num=10; else { flag=1; printf("数字输入有误,请重新输入\n"); } return num; } void pt(int w) { void tran2(int m); int p,q; p=w/100; q=w%10; if(w<=10) tran2(w); else if(w>10&&w<20) { printf("十"); tran2(w%10); } else if(w>=20&&w<100) { tran2(w/10); printf("十"); if(w/10!=0) tran2(w%10); } else if(w>=100) { tran2(w/100); printf("百"); if((w-p*100)>=10) { tran2((w-p*100)/10); printf("十"); if(w%10!=0) tran2(w%10); } else if((w-p*100)>0&&(w-p*100)<10) { printf("零"); tran2(w%10); } } } void tran2(int m) { switch (m) { case 0: printf("零");break; case 1:printf("一");break; case 2:printf("二");break; case 3:printf("三");break; case 4:printf("四");break; case 5:printf("五");break; case 6:printf("六");break; case 7:printf("七");break; case 8:printf("八");break; case 9:printf("九");break; case 10:printf("十"); } }
测试如下: