进制转换展示
因为我们专业这学期有门课要求是每个人都需要上讲台去讲15分钟数学相关的课,然后还会有评分等等,所以没办法,只能准备准备了。我打算讲高一的进制转换,但是我觉得常规的讲可能会没啥意思,所以就思考着能不能利用程序来做点什么,为微课堂比赛添点新意。
说干就干,我打算讲进制的转换,这是属于高一数学书上的内容。都是这么过来的,那时候特别喜欢玩游戏,所以如果把底下的同学当成高一的学生,就必须要拿他们感兴趣的东西来吸引他们注意力,能不能把进制的转换做成一个小游戏呢?
既然是游戏,那肯定就是有分数和做题环节了,我把整体分成了三个部分:1、十进制转二进制 2、二进制转十进制 3、任意进制转换。游戏的前两个部分可以在课前给大家看看,然后引入讲课的主题,同时在结束的时候带大家一起玩一下;第3部分作为教学部分,教学部分可以将进制转换具体描述,如十进制转换成其他进制是怎么转换的?商余法究竟是怎么操作的?如其他进制转换成十进制又是如何做到的?好了,一个大致的框架就打好了,接下来开始操作了。
首先是引入我们可能需要使用到的头文件
#include<stdio.h> #include<time.h> #include<windows.h> #include<string.h>
然后再main函数开始处利用时间函数初始化随机种子,方便后续做题产生随机数。
srand((unsigned)time(NULL));
然后设计一个菜单
void menu() { int select; printf("\n请输入游戏模式:1、给出十进制求二进制 2、给出二进制求十进制 3、演示十进制转换成其他进制"); scanf("%d",&select); run(select); }
run函数自然就是我们整个游戏的框架了。根据玩家的选择,决定最后执行的操作。因为课堂只有15分钟,所以我这里是设定初始分数为10分,12分以上则成功。
void run(int flag) { int score = 10,input,i = 0,num,old,New; char* str = (char*)malloc(sizeof(char)*100); while(score > 0) { if(flag == 1) { num = Rand(5,30); printf("据说分数到达12分以上,就可以顺利通过你现在最希望通过的一门考试哟!!!\n这是一个随机给你的十进制数字 %d,请输入它的二进制表达:",num); scanf("%d",&input); //将input转换成一个字符串保存起来 //if(strcmp(NumToStr(input),NumToStr(TenToOther(num,2))) == 0) if(input == TenToOther(num,2)) { printf("\nRight\n"); score+=2; printf("当前得分为:%d\n",score); if(score>12) { MessageBox(0, TEXT(" 许好愿望后\n 点击确定即会美梦成真!"), TEXT("许愿台"), 0); break; } } else { score--; printf("Error 正确为%d",TenToOther(num,2)); printf("当前得分为:%d\n",score); } } else if(flag == 2) { num = Rand(5,30); printf("据说分数到达12分以上,就可以顺利通过你现在最希望通过的一门考试哟!!!\n这是一个随机给你的二进制数字 %d,请输入它的十进制表达:",TenToOther(num,2)); scanf("%d",&input); if(num == OtherToTen(TenToOther(num,2),2)) { printf("Right\n"); score+=2; printf("当前得分为:%d\n",score); if(score>12) { MessageBox(0, TEXT(" 许好愿望后\n 点击确定即会美梦成真!"), TEXT("许愿台"), 0); break; } } else { score--; printf("Error 正确为%d %d\n",OtherToTen(TenToOther(num,2),2),num); printf("当前得分为:%d\n",score); } } else if(flag == 3) { while(1) { printf("请分别输入一个数字、它的进制以及你想要转换成的进制:"); scanf("%d%d%d",&input,&old,&New); TenToOtherJiaoXue(input,old,New); printf("\n"); system("pause"); } } } system("pause"); if(score <= 0) over(); }
当然,重头戏还是我们的教学讲解部分啦,首先是如何将二进制转换成十进制,因为刚开始是没打算用程序来展现过程的,所以走了蛮多弯路,做了输入一个十进制的数,得到二进制的数的字符串形式。具体怎么转换的我删了,当时的思路好像是除一次就会得到一个余数,然后就保存起来,然后结束后只要倒序输出,就得到了该数字的二进制了
数字转换成字符串我是将数字不断对10除和取余,不断比较除的的结果,如果不为零则不断将这个数字变成字符储存起来
//将数字转换成字符串 char* NumToStr(int num) { int devisor,remain,i = 0; char* str = (char*)malloc(sizeof(char)*100); devisor = num/10; remain = num%10; while(devisor != 0) { str[i++] = remain+48; num = devisor; devisor = num/10; remain = num%10; } str[i++] = remain+48; str[i] = '\0'; str = inverse(str); return str; }
倒序输出我是采用了一种递归的思路,充分利用了局部变量的性质
//将得到的进制数倒序输出,i表示输出下标为i的后面都输出,用0就可以全部输出 void print(char* str,int i) { char c = str[i]; if(c != '\0') print(str,++i); if(c != '\0') printf("%c",c); }
但是做完后我发现我没法将玩家输入的这个和我的结果比较,所以又修改了一下,最后那里不做倒序输出,而是做一个字符串逆转。
字符串逆序:拿到字符串首个元素地址(数组名),设置两个left和right两个下标,一个从0往右走,一个从'\0'符号前一位开始往左走,每次都替换下标为left和right两个字符,直到两者碰到或交叉(即相等或者left>right)
//字符串逆序 char* inverse(char* str) { int left = 0,right; char c; right = strlen(str)-1; for(;left<right;left++,right--) { c = str[left]; str[left] = str[right]; str[right] = c; } return str; }
做完后我输入的地方才用了让玩家输入字符串的形式,但是很快我就发现,这样不利于我做后面的教学,如果这么写,我又得写一个字符串转数字的函数。所以只得从根本上解决问题,我重新改写数据类型,还是采用int的类型来保存计算结果和玩家输入。
因为考虑到通用性,所以我写的不是十进制转换成二进制,二进制转换成十进制,而是加了一个进制参数,可以*选择10以下的进制进行互转
1 //将十进制转换成指定进制 2 int TenToOther(int num,int other) 3 { 4 //一直除,直到结果为零,期间每次都将结果乘以增长因子,增长因子每次操作都会扩大十倍。 5 //char* result = (char*)malloc(sizeof(char)*100); 6 int result = 0,index = 0,devisor,remain,factor = 1; 7 if(num<= other) 8 { 9 //result[index] = '\0'; 10 printf("Error!"); 11 exit(-1); 12 }//有了上面,可以保证至少进入循环一次。 13 devisor = num/other; 14 remain = num%other; 15 while(devisor != 0) 16 { 17 result=result+ remain*factor; 18 factor*=10; 19 num = devisor; 20 devisor = num/other; 21 remain = num%other; 22 } 23 result=result+ remain*factor; 24 return result; 25 }
将指定进制的数转换成十进制。如:OtherToTen(1010,2) 的返回值是10.
int OtherToTen(int num,int other) { char* str = NumToStr(num); int length = strlen(str)-1,index = 0; int result = 0; while(index <= length) { result = result+(str[length-index]-48)*pow(other,index); index++; } return result; }
int pow(int a,int b) 功能是返回a的b次方,这里采用递归的方式进行的
int pow(int a,int b) { int i,result = 1; if(b == 0) return 1; else { for(i=0;i<b;i++) result *= a; } return result; }
因为刚开始设计的时候,没考虑到教学,所以上面的内容是已经够了的,但是后来因为需要展示整个计算过程,所以我将上面两个进制转换的函数又改了一下,补充了两个进制转换教学函数
int OtherToTenJiaoXue(int num,int other) { char* str = NumToStr(num); int length = strlen(str)-1,index = 0; int result = 0; printf("%d进制的%d转换成十进制的过程如下:\n %d(%d)= ",other,num,num,other); while(index <= length) { if(index != 0) printf(" + %c*%d∧%d ",str[length-index],other,index); else printf("%c*%d∧%d ",str[length-index],other,index); result = result+(str[length-index]-48)*pow(other,index); index++; } printf(" = %d(10)\n",result); return result; }
int TenToOtherJiaoXue(int num,int old,int other) { int result = 0,index = 0,devisor,remain,factor = 1,temp; //old to ten if(old != 10) { OtherToTenJiaoXue(num,old); printf("\n"); getchar(); getchar(); //system("pause"); } num = OtherToTen(num,old); temp = num; if(num<= other) { //result[index] = '\0'; printf("Error!"); exit(-1); }//有了上面,可以保证至少进入循环一次。 devisor = num/other; remain = num%other; while(devisor != 0) { printf("%3d│%3d\t\t∧\n",other,num); printf(" └──\t\t∧\n"); printf(" %3d ...%3d\t∧\n\n",devisor,remain); getchar(); result=result+ remain*factor; factor*=10; num = devisor; devisor = num/other; remain = num%other; } printf("%3d│%3d\t\t∧\n",other,num); printf(" └──\t\t∧\n"); printf(" %3d ...%3d\t∧\n",devisor,remain); result=result+ remain*factor; printf("\n\n\t所以%d的%d进制 表达形式为:%d\n",temp,other,result); return result; }
上述代码主要是将计算的过程展现了出来,添加了一下格式进来,效果和原函数差别不大。TenToOtherJiaoXue函数有一个old参数,也是考虑到通用性问题,比如old为10的时候,即为10进制的数转换成二进制。
int TenToOtherJiaoXue(int num,int old,int other)函数解释:num为一个待转换的数,old为num的原来进制,表示num究竟是一个几进制的数,other则为需要转换的进制。如果old是10,则跳过转换成十进制的过程。如果old为非10,则会先将num转换成十进制,再将结果转换成指定的other进制。这也是符合我们数学的计算规则的。
好了,下面贴一张我们的运行结果以及全部程序
1 #include<stdio.h> 2 #include<time.h> 3 #include<windows.h> 4 #include<string.h> 5 int TenToOther(int num,int other); 6 int Rand(int ,int); 7 void print(char* str,int i); 8 void menu(); 9 void run(int flag); 10 char* NumToStr(int num); 11 char* inverse(char* str); 12 int OtherToTen(int num,int other); 13 void over(); 14 int pow(int a,int b); 15 int TenToOtherJiaoXue(int num,int other); 16 int OtherToTenJiaoXue(int num,int other); 17 18 int main(void) 19 { 20 int num; 21 char* result; 22 srand((unsigned)time(NULL)); 23 //num = Rand(2,50); 24 //printf("%d\n",num); 25 //result = TenToOther(num,2); 26 //print(result,0); 27 //TenToOtherJiaoXue(14,10,2); 28 29 menu(); 30 31 system("pause"); 32 return 0; 33 } 34 void menu() 35 { 36 int select; 37 printf("\n请输入游戏模式:1、给出十进制求二进制 2、给出二进制求十进制 3、演示十进制转换成其他进制"); 38 scanf("%d",&select); 39 run(select); 40 } 41 void run(int flag) 42 { 43 int score = 10,input,i = 0,num,old,New; 44 char* str = (char*)malloc(sizeof(char)*100); 45 while(score > 0) 46 { 47 if(flag == 1) 48 { 49 num = Rand(5,30); 50 printf("据说分数到达12分以上,就可以顺利通过你现在最希望通过的一门考试哟!!!\n这是一个随机给你的十进制数字 %d,请输入它的二进制表达:",num); 51 scanf("%d",&input); 52 //将input转换成一个字符串保存起来 53 //if(strcmp(NumToStr(input),NumToStr(TenToOther(num,2))) == 0) 54 if(input == TenToOther(num,2)) 55 { 56 printf("\nRight\n"); 57 score+=2; 58 printf("当前得分为:%d\n",score); 59 if(score>12) 60 { 61 MessageBox(0, TEXT(" 许好愿望后\n 点击确定即会美梦成真!"), TEXT("许愿台"), 0); 62 break; 63 } 64 } 65 else 66 { 67 score--; 68 printf("Error 正确为%d",TenToOther(num,2)); 69 printf("当前得分为:%d\n",score); 70 } 71 } 72 else if(flag == 2) 73 { 74 num = Rand(5,30); 75 printf("据说分数到达12分以上,就可以顺利通过你现在最希望通过的一门考试哟!!!\n这是一个随机给你的二进制数字 %d,请输入它的十进制表达:",TenToOther(num,2)); 76 scanf("%d",&input); 77 if(num == OtherToTen(TenToOther(num,2),2)) 78 { 79 printf("Right\n"); 80 score+=2; 81 printf("当前得分为:%d\n",score); 82 if(score>12) 83 { 84 MessageBox(0, TEXT(" 许好愿望后\n 点击确定即会美梦成真!"), TEXT("许愿台"), 0); 85 break; 86 } 87 } 88 else 89 { 90 score--; 91 printf("Error 正确为%d %d\n",OtherToTen(TenToOther(num,2),2),num); 92 printf("当前得分为:%d\n",score); 93 } 94 } 95 else if(flag == 3) 96 { 97 while(1) 98 { 99 printf("请分别输入一个数字、它的进制以及你想要转换成的进制:"); 100 scanf("%d%d%d",&input,&old,&New); 101 TenToOtherJiaoXue(input,old,New); 102 printf("\n"); 103 system("pause"); 104 } 105 } 106 } 107 108 109 system("pause"); 110 if(score <= 0) 111 over(); 112 } 113 114 void over() 115 { 116 Sleep(1000); 117 system("cls"); 118 printf("游戏结束\n"); 119 } 120 //将数字转换成字符串 121 char* NumToStr(int num) 122 { 123 int devisor,remain,i = 0; 124 char* str = (char*)malloc(sizeof(char)*100); 125 devisor = num/10; 126 remain = num%10; 127 128 while(devisor != 0) 129 { 130 str[i++] = remain+48; 131 num = devisor; 132 devisor = num/10; 133 remain = num%10; 134 } 135 str[i++] = remain+48; 136 str[i] = '\0'; 137 str = inverse(str); 138 return str; 139 } 140 141 //字符串逆序 142 char* inverse(char* str) 143 { 144 int left = 0,right; 145 char c; 146 right = strlen(str)-1; 147 for(;left<right;left++,right--) 148 { 149 c = str[left]; 150 str[left] = str[right]; 151 str[right] = c; 152 } 153 return str; 154 } 155 156 //将得到的进制数倒序输出 157 void print(char* str,int i) 158 { 159 char c = str[i]; 160 if(c != '\0') 161 print(str,++i); 162 if(c != '\0') 163 printf("%c",c); 164 } 165 166 int OtherToTenJiaoXue(int num,int other) 167 { 168 char* str = NumToStr(num); 169 int length = strlen(str)-1,index = 0; 170 171 int result = 0; 172 printf("%d进制的%d转换成十进制的过程如下:\n %d(%d)= ",other,num,num,other); 173 while(index <= length) 174 { 175 if(index != 0) 176 printf(" + %c*%d∧%d ",str[length-index],other,index); 177 else 178 printf("%c*%d∧%d ",str[length-index],other,index); 179 result = result+(str[length-index]-48)*pow(other,index); 180 index++; 181 } 182 printf(" = %d(10)\n",result); 183 return result; 184 } 185 int TenToOtherJiaoXue(int num,int old,int other) 186 { 187 int result = 0,index = 0,devisor,remain,factor = 1,temp; 188 //old to ten 189 if(old != 10) 190 { 191 OtherToTenJiaoXue(num,old); 192 printf("\n"); 193 getchar(); 194 getchar(); 195 //system("pause"); 196 } 197 num = OtherToTen(num,old); 198 temp = num; 199 if(num<= other) 200 { 201 //result[index] = '\0'; 202 printf("Error!"); 203 exit(-1); 204 }//有了上面,可以保证至少进入循环一次。 205 206 207 devisor = num/other; 208 remain = num%other; 209 210 while(devisor != 0) 211 { 212 printf("%3d│%3d\t\t∧\n",other,num); 213 printf(" └──\t\t∧\n"); 214 printf(" %3d ...%3d\t∧\n\n",devisor,remain); 215 getchar(); 216 result=result+ remain*factor; 217 factor*=10; 218 num = devisor; 219 devisor = num/other; 220 remain = num%other; 221 } 222 printf("%3d│%3d\t\t∧\n",other,num); 223 printf(" └──\t\t∧\n"); 224 printf(" %3d ...%3d\t∧\n",devisor,remain); 225 result=result+ remain*factor; 226 printf("\n\n\t所以%d的%d进制 表达形式为:%d\n",temp,other,result); 227 return result; 228 229 } 230 231 //将十进制转换成指定进制 232 int TenToOther(int num,int other) 233 { 234 //一直除,直到结果为零,期间每次都将结果乘以增长因子,增长因子每次操作都会扩大十倍。 235 //char* result = (char*)malloc(sizeof(char)*100); 236 int result = 0,index = 0,devisor,remain,factor = 1; 237 if(num<= other) 238 { 239 //result[index] = '\0'; 240 printf("Error!"); 241 exit(-1); 242 }//有了上面,可以保证至少进入循环一次。 243 devisor = num/other; 244 remain = num%other; 245 while(devisor != 0) 246 { 247 result=result+ remain*factor; 248 factor*=10; 249 num = devisor; 250 devisor = num/other; 251 remain = num%other; 252 } 253 result=result+ remain*factor; 254 return result; 255 } 256 257 int OtherToTen(int num,int other) 258 { 259 char* str = NumToStr(num); 260 int length = strlen(str)-1,index = 0; 261 262 int result = 0; 263 while(index <= length) 264 { 265 result = result+(str[length-index]-48)*pow(other,index); 266 index++; 267 } 268 return result; 269 } 270 int pow(int a,int b) 271 { 272 int i,result = 1; 273 if(b == 0) 274 return 1; 275 else 276 { 277 for(i=0;i<b;i++) 278 result *= a; 279 } 280 return result; 281 } 282 //输出介于最小值和最大值之间的一个数 283 int Rand(int Min,int Max) 284 { 285 return rand()%Max+Min; 286 }
最后,祝我好运吧!