计算器程序设计报告

计算器程序设计报告

一、设计分析

         编写一个计算器程序,要求:

1、界面类似于windows系统中提供的计算器界面;

2、能实现加、减、乘、除、乘方、开方等功能。

界面类似于windows系统中提供的计算器界面,则数字的输入和功能的执行都通过按键来实现,并且能够在显示区域里及时的显示出数据,所用本程序使用VC++提供的高度可视化的应用程序开发工具MFC来实现。

要实现加、减、乘、除、乘方、开方等功能,则在程序中包含"math.h"库函数文件,通过引用相应的函数来实现乘方、开方等功能。在输入第一个计算参数以后,点击需要执行的计算方式,然后输入第二个计算参数,点击“=”按钮,则会在显示区显示出正确的结果。

本程序从设计上来讲,主要分为两个重点部分,一个是数字的输入,即逐个点击单个数字(包括小数点)之后,这些数据能够在显示区正确的显示。第二个是数据的计算,先输入第一个计算参数,然后选择计算方式,再输入第二个计算参数,最后点击“=”按钮,计算结果。

二、程序结构

按照程序的设计,可以分为数据显示模块、数据输入模块、计算方式选择模块、结果计算模块、菜单模块等五个主要模块,其中,数字输入模块和计算模块是重点和难度,这两个模块的流程图如下所示:

1、数字输入的流程图:

点击一个数字键以后,流程开始:

2、数据计算的流程:

三、各模块的功能及程序说明

按照程序的设计,可以分为数据显示模块、数据输入模块、计算方式选择模块、结果计算模块、菜单模块等五个主要模块,以下逐个说明各模块的功能及程序说明。

1、数据显示模块。数据显示模块显示用户输入的数字和计算器计算的结果,主要由一个数字显示框组成。数字显示框是一个编辑框控件,属性设置为只读模式,不能由用户编辑。在MFC的类向导中,给数字显示框添加一个变量m_num,用来记录数字的变化,当每次操作以后,都会把数字更新到界面上,显示给用户。

2、数据输入模块。数据输入模块用来输入1、2、3、4、5、6、7、8、9、0等十个数字和一个“.”小数点,并且可以进行数据正负的转换。此模块由十个数字按键、一个小数点按键、一个正负转换按键组成。有一个bool型的变量来标识小数点是否已经输入,如果标识为假,则操作的数据为整数,如果标识为真,则操作的数据为小数。在同一个数据的输入中,小数点标识只在第一次点击时有效。每一个按键的操作都由一个函数单独完成,避免相互影响。每一次数据输入,都会更新数据框的显示,达到实时性。

3、计算方式选择模块。计算方式选择用来选择加、减、乘、除、乘方、开方等六个操作,每个计算方式都有一个单独的按钮,每个按钮都有一个单独的函数来执行。用一个int类型的变量m_fuhao来标识计算方式的选择。执行计算方式选择以后,把原先数据框中显示的数据赋值给第一个计算参数m_canshu1,并且对于系统标识变量进行相应的处理。因为对于六个函数来说,这些系统标识变量的相应处理都是相同的,所以把这些系统标识变量整理为一个函数void CJisuanqiDlg::TagFuc(),以利于代码的重复利用。

4、结果计算模块。结果计算模块是点击了“=”按键以后,执行相应的计算,并且输出结果。在其他的模块已经以此执行输入了第一个操作数据、计算方式、第二个操作数据,然后在这里根据这些数据进行计算。如果前面没有完整的执行输入第一个操作数据、计算方式、第二个操作数据,则此模块不做任何处理。在这个模块中,使用switch语句,分别根据计算方式的不同执行相应的操作,其中乘方和开方的操作需要调用"math.h"库函数文件中的pow(m_canshu1,m_canshu2)和sqrt(m_canshu1)函数来实现。执行完计算以后,将结果显示在显示框中,并且对系统标识变量进行一些相应的处理。

5、菜单模块。因为数据显示框中的数据对于用户是只读的,所以当用户在进行使用的时候,不能对数据框中的数据进行复制和粘贴等操作。这样在一定程度上限制了程序使用的方便性。为了解决这个问题,添加了菜单操作模块。菜单由两部分构成,第一个清零、关闭功能,当用户在输入数据的时候,如果不小心输入错误,可以执行清零操作,重新输入。如果用完计算器,可以执行关闭操作,关闭程序的运行。第二部分是编辑功能,包括数据的复制和粘贴功能,这样用户在使用中可以对重要的数据进行复制,先保存起来,然后再需要的时候进行粘贴,方便了用户的操作。

四、源程序

         根据程序模块的划分,除显示模块只有变量不进行任何操作,不需要说明源程序外,下面根据模块依次来对其他模块的源程序进行说明。

1、数据输入模块:

void CJisuanqiDlg::OnButton1() //Button1是字符1的按键

{

    // TODO: Add your control notification handler code here

    if(m_tag==false)//显示框中原来的数据是否继续使用。刚点击过加减乘除乘方开方或者等于按键,则原来的数据不继续使用

    {

        m_num=0;

        m_tag=true;

    }

    if(m_dian==false)//是否已经输入小数点

    {

        m_num=m_num*10+1;  //整数,则把新数据加在原来数据之后

    }

    else

    {  

        float jishu=1;

        for(int i=0;i<m_dianshu;i++)jishu=jishu/10;

        m_num=m_num+jishu;

        m_dianshu=m_dianshu+1;//小数点后的位数再加1

    }

    UpdateData(false);

}

void CJisuanqiDlg::OnButton12()//Button12是小数点的按键

{

    // TODO: Add your control notification handler code here

    if(m_dian==false)

        m_dian=true;

}

void CJisuanqiDlg::OnButton19()//Button19是清零的按键

{

    // TODO: Add your control notification handler code here

    m_num=0;

    m_dian=false;

    m_dianshu=1;

    m_tag=true;

    UpdateData(false);

}

void CJisuanqiDlg::OnButton11()//Button11是正负转换的按键

{

    // TODO: Add your control notification handler code here

    m_num=0-m_num;

    UpdateData(false);

}

2、计算方式选择模块:

void CJisuanqiDlg::OnButton13()//Button13是加法的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=1;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::OnButton14()//Button14是减法的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=2;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::OnButton15()//Button15是乘法的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=3;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::OnButton16()//Button16是除法的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=4;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::OnButton17()//Button17是乘方的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=5;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::OnButton18()//Button18是开方的按键

{

    // TODO: Add your control notification handler code here

    m_fuhao=6;

    m_canshu1=m_num;

    TagFuc();

    m_tag=false;

}

void CJisuanqiDlg::TagFuc()

{

    //m_num=0;

    m_dian=false;

    m_dianshu=1;

    m_tag=true;

    UpdateData(false);

}

3、结果计算模块

void CJisuanqiDlg::OnButton20()

{

    // TODO: Add your control notification handler code here

    if(m_tag==true)//这个判断是为了处理用户点击完“=”,没有点击其他按键再点击“=”,这种情况下,不更新第二个计算参数。

    {

        m_canshu2=m_num;

    }

    //if(m_tag==true)m_canshu1=m_num;

     //   CString sTemp;

    //  sTemp.Format("m_canshu1= %f  ;m_canshu2= %f \n", m_canshu1,m_canshu2);

    //  MessageBox(sTemp);

    switch(m_fuhao)

    {

        case 1:

            m_num=m_canshu1+m_canshu2;

            UpdateData(false);

            break;

        case 2:

            m_num=m_canshu1-m_canshu2;

            UpdateData(false);

            break;

        case 3:

            m_num=m_canshu1*m_canshu2;

            UpdateData(false);

            break;

        case 4:

            m_num=m_canshu1/m_canshu2;

            UpdateData(false);

            break;

        case 5:

            m_num=pow(m_canshu1,m_canshu2);

            UpdateData(false);

            break;

        case 6:

            m_num=sqrt(m_canshu1);//m_canshu1

            UpdateData(false);

            break;

        default:

            break;

    }

    //m_num=0;

    m_canshu1=m_num;

    m_tag=false;

   

}

4、菜单模块:

void CJisuanqiDlg::OnMenuitem32773()//复制

{

    // TODO: Add your command handler code here

    m_baocun=m_num;

}

void CJisuanqiDlg::OnMenuitem32774()//粘贴

{

    // TODO: Add your command handler code here

    if(m_baocun!=0)m_num=m_baocun;

    UpdateData(false);

}

void CJisuanqiDlg::OnMenuitem32771()//清零

{

    // TODO: Add your command handler code here

    OnButton19();

}

void CJisuanqiDlg::OnMenuitem32772()//关闭

{

    // TODO: Add your command handler code here

    CDialog::OnCancel();

}

五、操作方法

1,输入第一个计算参数,比如:2642、246.78、-578、-2.6;

2,点击选择计算方式,比如:加、减、乘、除、乘方、开方;

3,输入第二个计算参数(注:开方计算只需要一个计算参数,不需要输入第二个计算参数。);

4,点击“=”按键,输入计算结果;

5,由于程序做过处理,可以实现连等操作,多次点击“=”按键计算;

6,在操作过程中,可以对操作框进行复制、粘贴等操作。

六、实验结果

1、输入7865.78,结果如下图显示:

2、执行34+98,结果如下图显示:

3、执行65-87,结果如下图显示:

4、执行26*9,结果如下图显示:

5、执行64%98,结果如下图显示:

6、执行4的3次方,结果如下图显示:

7、执行88的开方,结果如下图显示:

七、设计体会

    在这段时间的课程设计中, 与其说是完成设计,我更觉得这是一个学习的过程。在设计过程中,我有很多的知识不懂或者已经淡忘了,但是通过求教于老师和同学,并勤于查阅资料,我又学到了很多的知识。本人真切地感受到此次课程设计带给我的学习动力与兴趣.我相信有了这些,将会对我以后的专业知识学习更加有利.

此次课程设计的顺利完成,还归功于老师殷切的指导和无私的帮助。在此,我向老师们表示衷心地感谢!

 

第二篇:计算器C程序设计报告

计算器C程序设计报告

一. 设计要求

运用C语言所具有的函数,模仿画出计算器的界面,并实现计算器的基本功能:浮点数加、减、乘、除、乘方和求模运算。

(1)收集资料,全面分析课题,分析问题,形成总体编程思路。

(2)深入分析各个小问题,编写各部分程序模块并进行具体介绍。(如初始化函数、主窗口函数、计算器函数等等。)

(3)上机调试,修改出现的错误,确保程序能正确运行。

二. 设计的作用、目的

(1)通过课程设计全面掌握《C语言程序设计》关键知识点,掌握C语言中数组、指针、结构体、各种函数等方面的基本知识。
    (2)通过课程设计了解并掌握C语言程序设计的方法,熟悉C程序设计的开发环境及C程序的调试过程。
    (3)培养学生查阅参考资料、手册的自学能力,通过独立思考深入钻研有关问题,学会自己分析、解决问题的方法。

(4)通过自己动手,培养、提高对编程的兴趣,为将来从事相关工作打好基础。

三.课题分析

要实现计算器功能,先要输出计算器的样式,再是通过按键的方式实现数值的运算,故程序大致可分两部分实现,一部分是显示计算器,另一部分是实现计算功能。

Turbo C提供了PC系统环境下扩充的屏幕和图形支持系统,利用系统提供的字符屏幕处理函数和图形系统的有关信息以及函数的实现,这样就可以显示计算器了。计算功能主要解决的是接收按键信息的处理和进行识别,如果按键是数字符号,要将其转变为操作数,如果是运算操作符,则进行相应的处理。

四.设计的具体实现

1.系统组成模块结构及功能

(1)Main主函数

设置了程序的流程,首先初始化图形系统,然后调用计算器computer()函数进行计算,当从计算器程序返回时,关闭图形系统,程序结束。

(2)Initialize()初始化函数

Turbo C通常的工作方式是字符文本模式,要显示图形,调用图形函数,则必须进入图形工作方式,应首先调用函数initgraph(&GraphDriver,&GraphMode,)初始化图形系统,并装入相应的图形驱动器。

(3)Mwindow()主窗口函数

设置视口大小为当前窗口的一半,再调用drawboder()函数画出边框。我们将可以在屏幕的左上角看到本程序的运行结果视口;

(4)Drawboder()画边框函数

通过getviewsettings(&vp) 函数把当前视口的信息装入由vp所指向的结构中。vp是struct viewporttype类型,其结构定义如下:

struct viewporttype

{

int left,top,right,bottom;

int clip;

void far rectangle(int left,int top,int right,int bottom);

void far setlinestyle(int linestype,unsigned upattern);

}

域left、top、right、bottom中存放视口左上角和右下角的坐标。当clip为0时,不进行对超出视口边界输出的剪裁,否则,执行剪裁以防止超出边界。

字符屏幕操作和图形函数的核心是窗口,它是屏幕的活动部分,在这个活动窗口中将显示输出。为保持两个系统的独立性,Turbo C在字符屏幕和图形系统之间用了两个不同的术语。

字符屏幕的函数提供了窗口,而图形系统提供了视口,但是当屏幕用字符模式时,左上角坐标为(1,1),而在图形状态下,左上角坐标为(0,0)。

根据视口坐标,利用rectangle()函数画出矩形边框线。我们将可以在屏幕的左上角看到程序运行的窗口;

(5)Computer()计算器函数

计算器函数是本程序的主要函数部分,其流程是先调用mwindow()主窗口函数显示一黄色边框的窗口,再在窗口中显示计算器,最后接收按键进行计算。为了合理布局、方便操作,根据窗口的大小设计按钮的大小和位置。读取当前窗口的大小后,设置了两个单位变量width和height,图形显示以这两个单位变量为计算单位,布局如下图所示:

                                        注:w表示width ;h表示height

图中的符号按钮利用函数setfillstyle()设置用绿色实体进行填充,然后用bar()函数画一个二维矩形条,setcolor()函数设置边框颜色,retangle()函数画一个矩形边框线,利用outtextxy()函数将预先存储在strl中的字符串中的字符输出,因为outtextxy()输出的是字符串,所以先要用sprintf()函数将输出的字符写入字符数组str2,转变为字符串,再输出。

界面设置完成后,首先在第一个按钮位置显示光标,此时可以移动和按下光标,当按下Alt+X键时可以结束程序,否则执行循环判断移动的是哪一个光标键,变量m和n分别记录光标的坐标(x,y)位置,光标移动到某个位置按回车键后,则程序判断所按的是哪个字符,并进行相应的处理:

①当所选为数字或小数点,则先判断是否为负数,如果是负数则将符号连接到字符串中,否则只连接所选的数字或小数点,并显示数据;

    ②当所选为“-”时,先判断有无操作数,如果没有操作则表示负数,组负数标记,否则是做减法,做减法标志,并将当前的操作数保存;

③当所选为“+”、“*”、“/”、“^”、“%”时,处理方式与(b)步骤一样,均是先保存第一个操作数,做为运算标志。准备接收第二个操作数;

④当所选为“=”时,根据运算符号标志act进行相应的运算,并结果显示;

⑤当所选为“c”时,表示归零,所以将第一和第二操作数均置0;

⑥当所选为“Q”时,则结束运算,桌面切换到原程序桌面状态;

(6)Arrow()设计图形鼠标函数

由于在图形函数方式下,光标是不可见的,所以为了能正确地选择按钮,自己设计一个光标图形。方法是用fillpoly(8,raw)画一个由raw所指向的数组定义的8个(x,y)坐标点所围成的封闭图形,用当前填充颜色对该形状进行填充后形状像鼠标的光标,利用函数imagesize()测试图像和函数putimage(x,y,rar,XOR_PUT)操作实现光标图像的显示和隐藏;

(7)Specialkey()读取特殊键函数

利用函数bioskey()读取所按键的信息,int bioskey(int cmd)函数原型在bios.h中功能是完成直接键盘操作。

如果cmd是0,bioskey()返回下一个在键盘输入的值(它将等待到下一个按键)。它返回严格16位的二进制数,包括两种不同的值。当按下“普通键”时,它的低8位数存放在该字符的ASCII码;对于“特殊键”,低8位为0。特殊键包括箭头键、功能键等。高8位字节存放该键的扫描码,所以程序中用到了语句key=bioskey(0),表示返回下一个在键盘上按下的键,并保存在变量key中,key=key&0xff:key>>8,对所按的键进行判断,如果key&0xff为真,即低8位不为0,则说明按下的是“普通键”,因为0xff16进制数代表的二进制码高8位为0,低8位为1,和0相遇,结果为0,和1相遇,结果保持原数,这样就将低8位(也就是该字符的ASCII码值)赋给key。如果key&0xff为假,即低8位为0,署名按下的是“特殊键”,将key右移8位后,也就是将其高8位值赋给key。

Cmd如果是1,bioskey()查询是否按下一个键时返回非0值,否则返回0值,所以用while(bioskey(1)==0)语句等待按键。

2.系统程序结构及流程图

计算器C程序设计报告

3.重要函数介绍

   (1)int main()

{

initialize();

          computer();   

          closegraph();  

return(0);

}

●主函数,内有数个分函数。它规划了该程序的设计思路。首先初始化图形系统,然后调用计算器computer()函数进行计算,当从计算器程序返回时,关闭图形系统,程序结束。

   (2)void initialize(void)

         {

        getpalette( &palette );          

            MaxColors = getmaxcolor() + 1;   

            MaxX = getmaxx();  

            MaxY = getmaxy(); 

            getaspectratio( &xasp, &yasp );  

        AspectRatio = (double)xasp/(double)yasp;

         }

●进入图形模式,并设置模块大小,颜色等信息初始化图形。

    (3)while((v=specialkey())!=45)

         {

           while((v=specialkey())!=ENTER)         {

             putimage(x,y,rar,XOR_PUT);

             if(v==RIGHT) 

                if(x>=x0+6*width)

                {

                   x=x0;

                   m=0;

                 }

                 else

                 {

                   x=x+width+width/2;

                   m++;

                  }

if(v=LEFT){……}

if(v=UP){……}

if(v=DOWN){……}

putimage(x,y,rar,XOR_PUT);

      }

●显示光标并设置光标的上、下、左、右移动规则。

(4)if(c=='+')

         {

            num1=atof(str2);  /*将第一个操作数转换为浮点数*/

            strcpy(str2,""); /*将str2清空*/

            act=1;  /*做计算加法标志值*/

            setfillstyle(SOLID_FILL,color+3);

            bar(2*width+width/2,height/2,15*width/2,3*height/2);

            outtextxy(5*width,height,"0."); /*显示字符串*/

          }

          if(c=='-'){……}

if(c=='*'){……}

if(c=='/'){……}

if(c=='^'){……}

if(c=='%'){……}

if(c=='='){……}

if(c=='c'){……}

if(c=='Q'){……}

●设置加、减、乘、除、归零和退出的功能

(5)int arrow()

     {  int size;

        int raw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4};

        setfillstyle(SOLID_FILL,2);

        fillpoly(8,raw); 

        size=imagesize(4,4,16,16);

        rar=malloc(size); 

        getimage(4,4,16,16,rar);

        putimage(4,4,rar,XOR_PUT);

        return 0;

}

●设置鼠标图形

(6)int specialkey(void)

{  int key;

        while(bioskey(1)==0);

        key=bioskey(0); 

        key=key&0xff? key&0xff:key>>8;

        return(key); 

}

●设置键盘的输入

4.程序代码编写及注释

#include    /*DOS接口函数*/

#include    /*数学函数的定义*/

#include   /*屏幕操作函数*/

#include   /*I/O函数*/

#include   /*库函数*/

#include   /*变量长度参数表*/

#include   /*图形函数*/

#include   /*字符串函数*/

#include   /*字符操作函数*/

#define UP 0x48    /*光标上移键*/

#define DOWN 0x50  /*光标下移键*/

#define LEFT 0x4b  /*光标左移键*/

#define RIGHT 0x4d  /*光标右移键*/

#define ENTER 0x0d  /*回车键*/

void *rar;       /*全局变量,保存光标图象*/

struct palettetype palette; /*使用调色板信息*/

int  GraphDriver;      /* 图形设备驱动*/

int  GraphMode; /* 图形模式值*/

int  ErrorCode;        /* 错误代码*/

int  MaxColors;        /* 可用颜色的最大数值*/

int  MaxX, MaxY;       /* 屏幕的最大分辨率*/

double  AspectRatio;   /* 屏幕的像素比*/

void drawboder(void); /*画边框函数*/

void initialize(void);  /*初始化函数*/

void computer(void);  /*计算器计算函数*/

void changetextstyle(int font, int direction, int charsize);  /*改变文本样式函数*/

void mwindow(char *header);  /*窗口函数*/

int specialkey(void) ;   /*获取特殊键函数*/

int arrow();     /*设置箭头光标函数*/

/*主函数*/

int main()

{

   initialize();/*设置系统进入图形模式*/

   computer(); /*运行计算器*/

   closegraph();/*系统关闭图形模式返回文本模式*/

   return(0);   /*结束程序*/

}

/*设置系统进入图形模式*/

void initialize(void)

{

   int xasp, yasp;     /*用于读x和y方向纵横比*/

   GraphDriver = DETECT; /*自动检测显示器*/

   initgraph( &GraphDriver, &GraphMode, "" );

/*初始化图形系统*/

   ErrorCode = graphresult();         /*读初始化结果*/

   if( ErrorCode != grOk )  /*如果初始化时出现错误*/

   {

      printf("Graphics System Error: %s\n",

      grapherrormsg( ErrorCode ) ); /*显示错误代码*/

      exit( 1 );  /*退出*/

    }

    getpalette( &palette );           /* 读面板信息*/

    MaxColors = getmaxcolor() + 1;    /* 读取颜色的最大值*/

    MaxX = getmaxx();    /* 读屏幕尺寸 */

    MaxY = getmaxy();  /* 读屏幕尺寸 */

    getaspectratio( &xasp, &yasp );   /* 拷贝纵横比到变量中*/

    AspectRatio = (double)xasp/(double)yasp;/* 计算纵横比值*/

}

/*计算器函数*/

void computer(void)

{

    struct viewporttype vp;  /*定义视口类型变量*/

    int color, height, width;

    int x, y,x0,y0, i, j,v,m,n,act,flag=1;

    float num1=0,num2=0,result;  /*操作数和计算结果变量*/

    char cnum[5],str2[20]={""},c,temp[20]={""};

    char str1[]="1230.456+-789*/Qc=^%";/* 定义字符串在按钮图形上显示的符号 */

    mwindow( "Calculator" );  /* 显示主窗口 */

    color = 7;     /*设置灰颜色值*/

    getviewsettings( &vp );       /* 读取当前窗口的大小*/

    width=(vp.right+1)/10;        /* 设置按钮宽度  */

    height=(vp.bottom-10)/10 ;  /*设置按钮高度  */

    x = width /2;   /*设置x的坐标值*/

    y = height/2;      /*设置y的坐标值*/

    setfillstyle(SOLID_FILL, color+3);

    bar( x+width*2, y, x+7*width, y+height );

    /*画一个二维矩形条显示运算数和结果*/

    setcolor( color+3 );  /*设置淡绿颜色边框线*/

    rectangle( x+width*2, y, x+7*width, y+height );

     /*画一个矩形边框线*/

    setcolor(RED);  /*设置颜色为红色*/

    outtextxy(x+3*width,y+height/2,"0."); /*输出字符串"0."*/

    x =2*width-width/2;   /*设置x的坐标值*/

    y =2*height+height/2;  /*设置y的坐标值*/

    for( j=0 ; j<4 ; ++j ) /*画按钮*/

    {

       for( i=0 ; i<5 ; ++i )

       {

           setfillstyle(SOLID_FILL, color);

           setcolor(RED);

           bar( x, y, x+width, y+height ); /*画一个矩形条*/

           rectangle( x, y, x+width, y+height );

           sprintf(str2,"%c",str1[j*5+i]);

             /*将字符保存到str2中*/

           outtextxy( x+(width/2), y+height/2, str2);

           x =x+width+ (width / 2) ;  /*移动列坐标*/

       }

       y +=(height/2)*3;       /* 移动行坐标*/

       x =2*width-width/2;  /*复位列坐标*/

    }

    x0=2*width;

    y0=3*height;

    x=x0;

    y=y0;

    gotoxy(x,y); /*移动光标到x,y位置*/

    arrow();  /*显示光标*/

    putimage(x,y,rar,XOR_PUT);

    m=0;

    n=0;

    strcpy(str2,"");  /*设置str2为空串*/

    while((v=specialkey())!=45)  /*当压下Alt+x键结束程序,否则执行下面的循环*/

    {

       while((v=specialkey())!=ENTER)  /*当压下键不是回车时*/

       {

          putimage(x,y,rar,XOR_PUT); /*显示光标图象*/

          if(v==RIGHT)   /*右移箭头时新位置计算*/

             if(x>=x0+6*width)

                 /*如果右移,移到尾,则移动到最左边字符位置*/

             {

                x=x0;

                m=0;

              }

             else

             {

                x=x+width+width/2;

                m++;

              } /*否则,右移到下一个字符位置*/

          if(v==LEFT) /*左移箭头时新位置计算*/

             if(x<=x0)

             {

                x=x0+6*width;

                m=4;

             } /*如果移到头,再左移,则移动到最右边字符位置*/

             else

             {

               x=x-width-width/2;

               m--;

             } /*否则,左移到前一个字符位置*/

          if(v==UP) /*上移箭头时新位置计算*/

             if(y<=y0)

             {

               y=y0+4*height+height/2;

               n=3;

             } /*如果移到头,再上移,则移动到最下边字符位置*/

             else

             {

                y=y-height-height/2;

                n--;

             } /*否则,移到上边一个字符位置*/

          if(v==DOWN) /*下移箭头时新位置计算*/

             if(y>=7*height)

             {

               y=y0;

                n=0;

             } /*如果移到尾,再下移,则移动到最上边字符位置*/

             else

             {

               y=y+height+height/2;

               n++;

             } /*否则,移到下边一个字符位置*/

          putimage(x,y,rar,XOR_PUT);  /*在新的位置显示光标箭头*/

      }

      c=str1[n*5+m];  /*将字符保存到变量c中*/

      if(isdigit(c)||c=='.')  /*判断是否是数字或小数点*/

      {

          if(flag==-1)  /*如果标志为-1,表明为负数*/

          {

             strcpy(str2,"-"); /*将负号连接到字符串中*/

             flag=1;

          } /*将标志值恢复为1*/

      sprintf(temp,"%c",c); /*将字符保存到字符串变量temp中*/

      strcat(str2,temp); /*将temp中的字符串连接到str2中*/

      setfillstyle(SOLID_FILL,color+3);

      bar(2*width+width/2,height/2,15*width/2,3*height/2);

      outtextxy(5*width,height,str2);  /*显示字符串*/

   }

   if(c=='+')

   {

      num1=atof(str2);  /*将第一个操作数转换为浮点数*/

      strcpy(str2,""); /*将str2清空*/

      act=1;  /*做计算加法标志值*/

      setfillstyle(SOLID_FILL,color+3);

      bar(2*width+width/2,height/2,15*width/2,3*height/2);

      outtextxy(5*width,height,"0."); /*显示字符串*/

   }

   if(c=='-')

   {

      if(strcmp(str2,"")==0) /*如果str2为空,说明是负号,而不是减号*/

          flag=-1;  /*设置负数标志*/

      else

      {

          num1=atof(str2);  /*将第二个操作数转换为浮点数*/

          strcpy(str2,""); /*将str2清空*/

          act=2; /*做计算减法标志值*/

          setfillstyle(SOLID_FILL,color+3);

          bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/

          outtextxy(5*width,height,"0."); /*显示字符串*/

      }

   }

   if(c=='*')

   {

      num1=atof(str2); /*将第二个操作数转换为浮点数*/

      strcpy(str2,""); /*将str2清空*/

      act=3; /*做计算乘法标志值*/

      setfillstyle(SOLID_FILL,color+3);      bar(2*width+width/2,height/2,15*width/2,3*height/2);

      outtextxy(5*width,height,"0."); /*显示字符串*/

    }

   if(c=='/')

   {

      num1=atof(str2); /*将第二个操作数转换为浮点数*/

      strcpy(str2,""); /*将str2清空*/

      act=4; /*做计算除法标志值*/

      setfillstyle(SOLID_FILL,color+3);

      bar(2*width+width/2,height/2,15*width/2,3*height/2);

      outtextxy(5*width,height,"0."); /*显示字符串*/

   }

   if(c=='^')

   {

      num1=atof(str2); /*将第二个操作数转换为浮点数*/

      strcpy(str2,""); /*将str2清空*/

      act=5; /*做计算乘方标志值*/

      setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/

      bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/

      outtextxy(5*width,height,"0."); /*显示字符串*/

   }

   if(c=='%')

   {

      num1=atof(str2); /*将第二个操作数转换为浮点数*/

      strcpy(str2,"");  /*将str2清空*/

      act=6; /*做计算模运算乘方标志值*/

      setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/

      bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/

      outtextxy(5*width,height,"0."); /*显示字符串*/

   }

   if(c=='=')

   {

      num2=atof(str2); /*将第二个操作数转换为浮点数*/

      switch(act)  /*根据运算符号计算*/

      {

          case 1:result=num1+num2;break; /*做加法*/

          case 2:result=num1-num2;break; /*做减法*/

          case 3:result=num1*num2;break; /*做乘法*/

          case 4:result=num1/num2;break; /*做除法*/

          case 5:result=pow(num1,num2);break; /*做x的y次方*/

          case 6:result=fmod(num1,num2);break; /*做模运算*/

      }

      setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/

      bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/

      sprintf(temp,"%f",result); /*将结果保存到temp中*/

      outtextxy(5*width,height,temp); /*显示结果*/

   }

   if(c=='c')

   {

      num1=0; /*将两个操作数复位0,符号标志为1*/

      num2=0;

      flag=1;

      strcpy(str2,""); /*将str2清空*/

      setfillstyle(SOLID_FILL,color+3);  /*设置用淡绿色实体填充*/

      bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/

      outtextxy(5*width,height,"0."); /*显示字符串*/

   }

   if(c=='Q')exit(0);  /*如果选择了q回车,结束计算程序*/

   }

   putimage(x,y,rar,XOR_PUT); /*在退出之前消去光标箭头*/

   return;  /*返回*/

}

/*窗口函数*/

void mwindow( char *header )

{

   int height;

   cleardevice();                     /* 清除图形屏幕 */

   setcolor( MaxColors - 1 );         /* 设置当前颜色为白色*/

   setviewport( 20, 20, MaxX/2, MaxY/2, 1 );  /* 设置视口大小 */

   height = textheight( "H" );           /* 读取基本文本大小  */

   settextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );/*设置文本样式*/

   settextjustify( CENTER_TEXT, TOP_TEXT );/*设置字符排列方式*/

   outtextxy( MaxX/4, 2, header );  /*输出标题*/

   setviewport( 20,20+height+4, MaxX/2+4, MaxY/2+20, 1 );  /*设置视口大小*/

   drawboder(); /*画边框*/

}

void drawboder(void)  /*画边框*/

{

   struct viewporttype vp;  /*定义视口类型变量*/

   setcolor( MaxColors - 1 );         /*设置当前颜色为白色   */

   setlinestyle( SOLID_LINE, 0, NORM_WIDTH );/*设置画线方式*/

   getviewsettings( &vp );/*将当前视口信息装入vp所指的结构中*/

   rectangle( 0, 0, vp.right-vp.left, vp.bottom-vp.top ); /*画矩形边框*/

}

/*设计鼠标图形函数*/

int arrow()

{

   int size;

   int raw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4}; /*定义多边形坐标*/

   setfillstyle(SOLID_FILL,2); /*设置填充模式*/

   fillpoly(8,raw);    /*画出一光标箭头*/

   size=imagesize(4,4,16,16);  /*测试图象大小*/

   rar=malloc(size);  /*分配内存区域*/

   getimage(4,4,16,16,rar); /*存放光标箭头图象*/

   putimage(4,4,rar,XOR_PUT); /*消去光标箭头图象*/

   return 0;

}

/*按键函数*/

int specialkey(void)

{

   int key;

   while(bioskey(1)==0);  /*等待键盘输入*/

   key=bioskey(0);   /*键盘输入*/

   key=key&0xff? key&0xff:key>>8;  /*只取特殊键的扫描值,其余为0*/

   return(key);    /*返回键值*/

 }

5.软件调试问题分析及解决方法

◆第一次找到计算器的程序后匆忙运行,出现8个错误,而且都看不懂,经查找,才发现是因为编程语言不对,选用了java。

◆第二次又由于疏忽,在最后少加了一个大括号

6.软件运行结果

▲在TC上编写计算器程序

     

        ▲检查程序没有错误

      

             ▲计算器程序运行界面

    

▲输入1+2

▲运行结果

四.心得体会及建议

通过此次C语言程序设计实践,本人实在是获益不浅!C语言是上个学期开的课程,所以这个学期并没怎么看过,当要开始设计的时候,还真不知从哪下手!结果,第一次上机,我坐了一个下午,只找到个源程序,而且也看不懂,什么也没干!回去以后,我想,这样不行,这样下去还得了!我就重新学了一遍我们上个学期的教材,发觉自已有许多都遗忘了!经过温习,和资料的查找,再去看源程序终于觉得有些头绪了。

     通过这次课程设计,理解了一些编译程序的一般原理和基本实现方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。使我对C语言的使用得到了的提高。我觉得对程序的深层理解,清楚程序中每一步的功能,在程序的运行中是十分重要的。一个好的结构在运行中能够充分的发挥程序的功能。结构设计的合理性决定了这个程序的价值。在今后的学习中我要注意这方面,使得我的编程能力能有进一步的提高。     

这次课程设计,不仅对我的学习提供了帮助,而且在意志力方面也得到了锻炼。没有足够的耐力和信心就很难坚持对课程设计每一步的顺利进行。我觉得编写类似的程序其中最重要的一个方面就是要认真,认真编写代码可以大大减少错误的出现;其次是要有耐心,勇于克服困难,不断解决问题,面对困难要永不退缩,迎难而上;再次是要有清晰的思维,能够理清各个函数之间的关系,明确各个函数的职能;最后还要和同学多交流合作,多参考书籍。

五.参考文献

(1)郭翠英  《C语言课程设计案例精编》  中国水利水电出版社  2004.3

(2)谭浩强  《C程序设计》(第二版)      清华大学出版社      2005.8

(3)www.ut365.com

相关推荐