进制转换器
一、程序运行截图
1、二进制-->八进制+不继续
2、八进制-->十六进制+不继续
3、十进制-->十六进制+不继续
4、十六进制-->二进制+继续(十六进制-->八进制)
(接上图)
5、类型选择错误
6、输入不在进制范围
二、函数介绍
1、所有函数声明
void putmenu(void); //输入*选择菜单 void getmenu(void); //输出*选择菜单 void hint(int intype); //进一步提示菜单 int mypow(int m, int n); //自制pow函数 int judge(char number[], int intype); //判断所有进制数的输入是否在进制范围内 int convertdec(char number[], int intype); //全部进制都转为十进制 void converdinary(int newnum); //十进制转为二进制 void output(int newnum, int outtype); //最终输出结果
2、中间提示+输入输出菜单
void putmenu(void) { puts("^-^欢迎进入进制转换器初始界面!!!\n"); puts("请选择您要输入的进制类型为:(输入前置代号即可)"); puts("[1]——二进制数!"); puts("[2]——八进制数!"); puts("[3]——十进制数!"); printf("[4]——十六进制数!\n您的选择是: "); } void getmenu(void) { puts("\n^-^请选择您要输出的进制类型!!!(输入前置代号即可)"); puts("[1]——二进制数!"); puts("[2]——八进制数!"); puts("[3]——十进制数!"); printf("[4]——十六进制数!\n您的选择是: "); } void hint(int intype) { switch (intype) { case 1:printf("\n请输入您的二进制数:"); break; case 2:printf("\n请输入您的八进制数:"); break; case 3:printf("\n请输入您的十进制数:"); break; case 4:printf("\n请输入您的十六进制数:"); break; default:puts("选择无法识别!!!请重新输入!\n"); break; } }
注:此三个函数只是为了程序运行时的必要文字输出,无具体功能
3、自制pow函数
int mypow(int m, int n) { int sum = 1; for (int i = 0; i < n; i++) { sum *= m; } return sum; }
注:自制pow指数运算函数为提升一部分程序的运行效率
4、核心函数1
int convertdec(char number[], int intype) { int len; for (len = -1; number[len] != '\0'; len++) {} int newnum = 0; if (intype == 1) { for (int i = len - 1, t = 0; i >= 0; t++, i--) { newnum += ((number[i] - 48) * mypow(2, t)); } } else if (intype == 2) { for (int i = len-1,t=0; i >=0;t++, i--) { newnum += ((number[i] - 48) * mypow(8, t)); } } else if (intype == 3) { for (int i = len-1,t=0; i >=0;t++, i--) { newnum += ((number[i] - 48) * mypow(10,t )); } } else if (intype == 4) { for (int i = len-1,t=0; i >=0;t++, i--) { if (number[i] >= 48 && number[i] <= 57) { newnum += ((number[i] - 48) * mypow(16, t)); } else if (number[i] >= 65 && number[i] <= 70) { newnum += ((number[i] - 55) * mypow(16, t)); } } } return newnum; }
注:此函数为整个程序功能实现的核心函数,目的是将所有类型的进制数都转换为十进制数存于变量“newnum”中
5、核心函数2
void converdinary(int newnum) { if (newnum / 2) converdinary(newnum / 2); printf("%d", newnum % 2); }
注:此函数利用递归,实现十进制数转为二进制数输出
6、裁判函数
int judge(char number[], int intype) { if (intype == 1) { for (int i = 0; number[i] != '\0'; i++) { if (number[i] != 48 && number[i] != 49) { return 0; } } return 1; } else if (intype == 2) { for (int i = 0; number[i] != '\0'; i++) { if (number[i] < 48 || number[i]>56) { return 0; } } return 1; } else if (intype == 3) { for (int i = 0; number[i] != '\0'; i++) { if (number[i] < 48 || number[i]>57) { return 0; } } return 1; } else if (intype == 4) { for (int i = 0; number[i] != '\0'; i++) { if (number[i] < 48 || (number[i] > 57 && number[i] < 65) || number[i]>70) { return 0; } } return 1; } }
注:此函数目的为判断传入数字是否在该进制类型范围内
7、结果输出
void output(int newnum,int outtype) { if (outtype == 1) { puts("\n最终结果为:(转至二进制)"); converdinary(newnum); puts("\n\n(^-^)欢迎使用,谢谢!!!"); } else if (outtype == 2) { puts("\n最终结果为:(转至八进制)"); printf("%#o\n\n(^-^)欢迎使用,谢谢!!!", newnum); } else if (outtype == 3) { puts("\n最终结果为:(转至十进制)"); printf("%d\n\n(^-^)欢迎使用,谢谢!!!", newnum); } else if (outtype == 4) { puts("\n最终结果为:(转至十六进制)"); printf("%#X\n\n(^-^)欢迎使用,谢谢!!!", newnum); } }
注:此函数目的为输出最终结果
三、main函数展示
int main(void) { int contorlnumber; //用于控制程序是否再一次进行 do { putmenu(); int intype, outtype, newnum, time = 0; char number[N]; //定义字符数组,存放所有类型的进制数 do { scanf("%d", &intype); hint(intype); } while (intype < 1 || intype>4); //确保输入选择范围 do { time++; if (time != 1) puts("错误!请重新输入!"); scanf("%s", number); } while (judge(number, intype) != 1); //确保输入范围 newnum = convertdec(number, intype); //将转成的十进制数放在newnum getmenu(); scanf("%d", &outtype); while (outtype > 4 || outtype < 1) { //确保输出选择范围 puts("选择无法识别!!!请重新输入!\n"); scanf("%d", &outtype); } output(newnum, outtype); //最终转换输出 puts("\n输入“1”继续,输入“0”退出程序!"); scanf("%d", &contorlnumber); } while (contorlnumber); return 0; }
四、思维导图
五、问题及解决
问题1:在程序编写的过程中二进制数如果按照一个int类型数来输入的话,一是int类型的大小上限可能不够,二是后续的判断、转换的按位取出的实现会很复杂
解决1:我先开始其他进制的编写,写到十六进制的输入时,用到字符串存放输入的数字,因此我想到了二进制数以及所有的进制数都可以用字符数组来存放,这样可以就可以省略判断和转换时按位取出每一位数的麻烦,因为数组的每一个单元都存放了一位数字,精简了代码并解决了问题。
问题2:如果每个进制到另一个进制的转换都写一个函数来实现的话,代码编写工程量会很大。
解决2:我想到了高中进制转换时,老师说可以先将一个进制数转换到我们熟悉的十进制再转换到其他进制。由此,我写出此程序的一个至关重要的功能函数,此函数将所有类型的进制数都转换到十进制,这样就可以用例如:%o,%x,直接输出想要的进制类型数。
六、代码互评
1、
//黄力强 void menu() //菜单 { printf(" \\ 我是菜单 / \n"); printf(" (。ì _ í。) \n"); printf(" ——————十进制转换二进制 [1]—————— \n"); printf(" \\ 十进制转换八进制 [2] / \n"); printf(" \\ 十进制转换十六进制[3] / \n"); printf(" \\ 二进制转换十进制 [4]/ \n"); printf(" /八进制转换十进制 [5]\\ \n"); printf(" 十六进制转换十进制[6] \n"); printf(" 退 出 [0] \n"); printf(" | | \n"); printf(" | | \n"); printf(" _| |_ \n"); printf("\n"); printf("\n"); }
评:将菜单玩出花样是我没有想到了。
2、
//林洁颖 int binaryconversion(int number){ if(number/2==0){ return number%2; } else{ return number%2+binaryconversion(number/2)*10; } }
评:这位同学是将转换成的二进制数当作一个int类型的数来返回,万一超出int类型的上限范围就会出错,我本来也是类似这样写的,后来发现有错就改成了一位一输出,但是这位同学的递归很值得我学习。
七、总结
通过这次的大作业让我意识到写程序时新颖的思路很重要,有时候一个小小的思路的改变就可以让我们的代码精简很多,所以在以后的代码编写中,我要多多思考。同时也让我懂得了写程序不仅仅是供自己使用就行,在以后,程序绝大部分情况是要给其他人使用,因此在代码编写中有一些必要的文字说明非常重要。
在我的理解中,函数就是为了实现某一特定的功能从而编写产生的,可以提升程序代码的可读性,可以供多个地方使用,可以让代码更容易去理解,所有的函数就类似于一块块积木,而程序的主体就相当于一块块积木搭建拼凑而成的。