第二次博客作业
1.进制转换器运行效果:
初始界面:
二进制转8,10,16进制效果图:
八进制转2,10,16进制效果图:
十进制转2,8,16进制效果图:
十六进制转2,8,10进制效果图:
各进制数输入操作错误提示效果:
2.额外扩展功能:“程序评价系统”、“智能防沉迷系统”以及退出系统语句
(1)智能防沉迷系统:每当使用者使用次数达到5的倍数时,系统会自动发出警告。
效果图:
(2)评价系统:当用户结束转换时,窗口会输出评价选择,以供用户做出对此程序的评价,不同的评价会有不同的反馈,具有操作错误提示功能。
效果图:
(3)退出反馈:
3.函数介绍:
2进制转8、10、16进制函数:
//2>>>8//
int twoto8(int n)//2进制转10进制,10进制转8进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
if(flag==1){
for(i=1;i<=count-1;i++)
flag=flag*2;
}
sum=sum+flag;
n=n/10;
}while(n!=0);
printf("转换结果为: ");
printf("%o",sum);
}
//2>>>10//
int twoto10(int n)//2进制转10进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
if(flag==1){
for(i=1;i<=count-1;i++)
flag=flag*2;
}
sum=sum+flag;
n=n/10;
}while(n!=0);
printf("转换结果为: ");
printf("%d",sum);
}
//2>>>16//
int twoto16(int n)//2进制转10进制,10进制转16进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
if(flag==1){
for(i=1;i<=count-1;i++)
flag=flag*2;
}
sum=sum+flag;
n=n/10;
}while(n!=0);
printf("转换结果为: ");
printf("%X",sum);
}
8进制转2、10、16进制函数:
//8>>>2//
int eightto2(int n)//8进制转10进制,10进制转2进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
for(i=1;i<=count-1;i++)
flag=flag*8;
sum=sum+flag;
n=n/10;
}while(n!=0);
tento2(sum) ;
return 0;
}
//8>>>10//
int eightto10(int n)//8进制转10进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
for(i=1;i<=count-1;i++)
flag=flag*8;
sum=sum+flag;
n=n/10;
}while(n!=0);
printf("%d",sum);
return 0;
}
//8>>>16//
eightto16(int n)//8进制转16进制
{
int flag,sum,count,i;
sum=0;
count=0;
do{
flag=n%10;
count++;
for(i=1;i<=count-1;i++)
flag=flag*8;
sum=sum+flag;
n=n/10;
}while(n!=0);
printf("%X",sum);
return 0;
}
10进制转2、8、16进制函数:
//10>>>2//
int tento2(int n)//10进制转2进制
{
int i,count,flag;
int a[999]={0};
count=0;
flag=0;
for(i=1;;i++)
{
flag=n%2;
a[i]=flag;
n=n/2;
count++;
if(n==0)break;
if(n==1){
a[i+1]=1;
count++;
break;
}
}
printf("转换结果为: ");
for(i=count;i>=1;i--)
printf("%d",a[i]);
}
//10>>>8//
int tento8(int n)//10进制转8进制
{
printf("转换结果为: ");
printf("%o",n);
}
//10>>>16//
int tento16(int n)//10进制转16进制
{
printf("转换结果为: ");
printf("%X",n);
}
16进制转2、8、10进制函数:
//16>>>2//
int sixteento2(int n)//16进制转10进制,再转2进制
{
int i,count,flag;
int a[999]={0};
count=0;
flag=0;
for(i=1;;i++)
{
flag=n%2;
a[i]=flag;
n=n/2;
count++;
if(n==0)break;
if(n==1){
a[i+1]=1;
count++;
break;
}
}
printf("转换结果为: ");
for(i=count;i>=1;i--)
printf("%d",a[i]);
}
//16>>>8//
int sixteento8(int n)//16进制转8进制
{
printf("转换结果为: ");
printf("%o",n);
}
//16>>>10//
int sixteento10(int n)//16进制转10进制
{
printf("转换结果为: ");
printf("%d",n);
}
将十六进制数化为十进制数的函数以及判断输入的十六进制数是否有误的判断函数:
//16>>>>>10
int sixteentoten(char a[])//以字符串形式输入16进制数
{
int l, i, num;
int m=0;
l=strlen(a);
for (i = 0; i < l; i++)
{
if (a[i] >= '0' && a[i] <= '9')
{
num = a[i] - '0';
}
else if (a[i] >= 'A' && a[i] <= 'F')
{
num = a[i] - 'A' + 10;
}
m = m * 16+ num;
}
return m;//返回对应的10进制数
}
int panduansixteen(char a[])//判断16进制数是否正确
{
int l, i;
l=strlen(a);
for (i = 0; i < l; i++)
if (a[i] < '0' || a[i]>'9' &&a[i] < 'A' || a[i]>'F'&&a[i] < 'a' || a[i]>'f')return 1;
return 0;
}
4.main函数展示:
int main (void)
{
int n,m,i,flag,num,sum,item,z,k,j,p,q;
char ch1,ch2,a[99];
item=1;
printf(" **进制转换器v1.0beta**\n\n");
printf(" 支持的转换类型:\n\n");
printf("(1) 2 进制-->8 进制 (2) 2 进制-->10进制 (3) 2 进制-->16进制\n");
printf("(4) 8 进制-->2 进制 (5) 8 进制-->10进制 (6) 8 进制-->16进制\n");
printf("(7) 10进制-->2 进制 (8) 10进制-->8 进制 (9) 10进制-->16进制\n");
printf("(10) 16进制-->2 进制 (11) 16进制-->8 进制 (12) 16进制-->10进制\n");
for(j=1;j<=20;j++){
printf("\n");
printf("请输入您的转换类型: ");
scanf("%d",&n);
if(n>12||n<1){
printf("无效的选项");
continue;
}
else{
printf("请输入您想要转换的数字: ");
if(n>=1&&n<=9){
scanf("%d",&m);
k=m;
if(n==1||n==2||n==3){
do{
num=k%10;
k=k/10;
if(num!=0&&num!=1)item=0;
}while(k!=0);
}else if(n==4||n==5||n==6){
do{
num=k%10;
k=k/10;
if(num<0||num>=8)item=0;
}while(k!=0);
}else item=1;
if(item==0){
printf("您输入的数不正确\n");
continue;
}
if(n==1)twoto8(m);
else if(n==2)twoto10(m);
else if(n==3)twoto16(m);
else if(n==4)eightto2(m);
else if(n==5)eightto10(m);
else if(n==6)eightto16(m);
else if(n==7)tento2(m);
else if(n==8)tento8(m);
else if(n==9)tento16(m);
}
else{
scanf("%s",&a);
if(panduansixteen(a)){
printf("您输入的数不正确\n");
continue;
}
if(n==10)sixteento2(sixteentoten(a));
else if(n==11)sixteento8(sixteentoten(a));
else if(n==12)sixteento10(sixteentoten(a));
}
}
if(j%5==0){ //**智能防沉迷系统**//
printf("\n");
printf("您已使用进制转换器%d次,请注意适度独立自主的计算哦~\n",j);
printf("(1)继续使用 (0)自主尝试\n");
}else{
printf("\n");
printf("继续转换请按1,结束转换请按0 \n");
}
scanf("%d",&p);
if(p==1)continue;
else break;
}
printf("感谢您的使用!请对我们的程序作出评价:\n");//**星级评价系统**//
printf(" (1)* * * * * \n");
printf(" (2)* * * * \n");
printf(" (3)* * * \n");
printf(" (4)* * \n");
printf(" (5)* \n");
for(j=0;;j++)
{
scanf("%d",&z);
if(z>5||z<1){
printf("无效的选项\n");
continue;
}else break;
}
switch(z){
case 1:printf("感谢您的肯定与支持!\n");break;case 2:case 3:case 4:printf("感谢您的评价!\n");break;
case 5:printf("感谢您的批评,我们会继续优化程序!\n");break;
}
printf("******************************\n感谢您的使用,祝您生活愉快!\n");
return 0;
}
5.函数关系的思维导图:
6.遇到的问题及其解决方法:
(1)首先,遇到了函数过多的问题,这次作业是我第一次写一个函数超过十个的程序,行数一多起来就扰乱了思路。最后,我选择模块化地处理问题,把每个函数分开写,调试通过后再放到程序中,这样就省去了大量的时间,且能防止代码看串行而写错程序。
(2)程序的界面设计问题,当真正让我去设计这种小程序的界面后我才知道,一个程序的界面看似简单,实则用代码实现的过程十分复杂且枯燥,就算只漏了一个打印回车在程序运行界面上的变化都是十分明显的。关于这一问题,我解决的办法是在写程序之前就先试着做一做界面和文字提示,这样等到我真正去写代码的时候就会轻松很多。
(3)程序的选择命令设计问题,在我的程序中,有很多选择的操作,包括防沉迷提醒的选择,是否继续转换的选择,转换类型的选择,以及给程序评分打星的选择,这些选择看似简单,实则是最让人容易把程序写错的点,因为要考虑到选择不同结果后程序的反应,这些选择中既有你让用户选的,但也有你不想让用户选的,在这种情况下我又要给每个选择系统做一个查错机制,很是琐碎。在这一点上我的解决方法是先把程序的主要构架写出来,当主要程序运行良好后,再考虑“锦上添花”的事情。
(4)数据正确性的判断,在编写2、8、10进制的判断程序时都很顺利,唯独到了16进制的时候花了好一阵子的功夫,最终通过单独的一个函数来专门判断输入的16进制数的正确性。
(5)关于16进制输入的二三事。在整个程序中,我耗时最长的地方以及让我最抓狂的地方就是16进制的输入问题,由于我的其他进制数都是直接由实数输入的,以至于在遇到16进制这种位数中含有字符的数据时,我一度不知道该怎么做,还因为惯性思维绕了不知道多少个大圈,到最后简直有一种想哭的感觉。最终我还是静下心来,尝试利用字符串输入,再通过函数将其化为10进制函数再做计算,最终终于成功,兴奋至极。
7.代码互评:
网络1913 杨涛 的代码 :
void Numchange(int m, int b)//将10进制数转化为任意进制数
{
int n = m;
int count = 0;
if (m == 0) printf("0");
while (n != 0)
{
n = n / b;
count++;
}
int number;
for (int i = count; i >= 1; i--)
{
number = m / (int)pow(b, i - 1);
if (number < 10) {
printf("%d", number);
}
else {
printf("%c", number + 55);
}
m = m % (int)pow(b, i - 1);
}
}
互评:在看到杨涛同学使用的这个函数之后我十分震惊与佩服,因为他能够将我用三个函数才能完成的任务集中到了一个函数上--void Numchange(int m, int b),而相对应的,我用了tento2(),tento8(),tento16()这三个函数才完成上述任务,杨涛的这个函数无论是在运行效率上还是设计观念上,都能瞬间把我“秒杀”,也真的让我大开眼界--函数还可以这么玩,除了佩服还是佩服!
8.总结:
收获:本次作业的收获颇多,具体为学会了如何应对较多函数的这一类程序,积累了程序界面设计的经验,暴漏了自己对于字符串知识的薄弱,但同时也使自己的这一弱项得到了锻炼,学会了运用函数的一些技巧,了解了运用函数的一些情景,认识到了查错程序的一些套路,学会了怎样去输入一些特殊的进制数,16进制数更是完美地锻炼了我的抗压能力和受挫能力,这些经验与教训都是我在以后的路上走得稳当的重要保障。
个人对于函数的理解:经过本次大作业的洗礼后,我开始认识到函数存在的必要性,它不仅仅只是让我们的程序看起来井井有条那么简单,更是程序走向模块化的必经道路,而程序的模块化带给程序本身的是其简洁的外观、易于维护的结构、易于解读代码的模块化布局,而且在程序中运用函数,可以使某些难题迎刃而解,可谓克敌制胜的法宝之一,对于现阶段的我自己来说,函数也能美化程序,让程序不再那么臃肿。