进制转换展示
因为我们专业这学期有门课要求是每个人都需要上讲台去讲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以下的进制进行互转
//将十进制转换成指定进制
int TenToOther(int num,int other)
{
//一直除,直到结果为零,期间每次都将结果乘以增长因子,增长因子每次操作都会扩大十倍。
//char* result = (char*)malloc(sizeof(char)*100);
int result = 0,index = 0,devisor,remain,factor = 1;
if(num<= other)
{
//result[index] = '\0';
printf("Error!");
exit(-1);
}//有了上面,可以保证至少进入循环一次。
devisor = num/other;
remain = num%other;
while(devisor != 0)
{
result=result+ remain*factor;
factor*=10;
num = devisor;
devisor = num/other;
remain = num%other;
}
result=result+ remain*factor;
return result;
}
将指定进制的数转换成十进制。如: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进制。这也是符合我们数学的计算规则的。
好了,下面贴一张我们的运行结果以及全部程序
#include<stdio.h>
#include<time.h>
#include<windows.h>
#include<string.h>
int TenToOther(int num,int other);
int Rand(int ,int);
void print(char* str,int i);
void menu();
void run(int flag);
char* NumToStr(int num);
char* inverse(char* str);
int OtherToTen(int num,int other);
void over();
int pow(int a,int b);
int TenToOtherJiaoXue(int num,int other);
int OtherToTenJiaoXue(int num,int other);
int main(void)
{
int num;
char* result;
srand((unsigned)time(NULL));
//num = Rand(2,50);
//printf("%d\n",num);
//result = TenToOther(num,2);
//print(result,0);
//TenToOtherJiaoXue(14,10,2);
menu();
system("pause");
return 0;
}
void menu()
{
int select;
printf("\n请输入游戏模式:1、给出十进制求二进制 2、给出二进制求十进制 3、演示十进制转换成其他进制");
scanf("%d",&select);
run(select);
}
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();
}
void over()
{
Sleep(1000);
system("cls");
printf("游戏结束\n");
}
//将数字转换成字符串
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;
}
//字符串逆序
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;
}
//将得到的进制数倒序输出
void print(char* str,int i)
{
char c = str[i];
if(c != '\0')
print(str,++i);
if(c != '\0')
printf("%c",c);
}
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;
}
//将十进制转换成指定进制
int TenToOther(int num,int other)
{
//一直除,直到结果为零,期间每次都将结果乘以增长因子,增长因子每次操作都会扩大十倍。
//char* result = (char*)malloc(sizeof(char)*100);
int result = 0,index = 0,devisor,remain,factor = 1;
if(num<= other)
{
//result[index] = '\0';
printf("Error!");
exit(-1);
}//有了上面,可以保证至少进入循环一次。
devisor = num/other;
remain = num%other;
while(devisor != 0)
{
result=result+ remain*factor;
factor*=10;
num = devisor;
devisor = num/other;
remain = num%other;
}
result=result+ remain*factor;
return result;
}
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)
{
int i,result = 1;
if(b == 0)
return 1;
else
{
for(i=0;i<b;i++)
result *= a;
}
return result;
}
//输出介于最小值和最大值之间的一个数
int Rand(int Min,int Max)
{
return rand()%Max+Min;
}
最后,祝我好运吧!
上一篇: 苹果Macbook笔记本闪屏怎么办? Macbook闪屏的五种解决办法
下一篇: EasyUI 入门