欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

进制转换展示

程序员文章站 2024-02-05 12:52:52
...

因为我们专业这学期有门课要求是每个人都需要上讲台去讲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;
}

  最后,祝我好运吧!

相关标签: 进制