用c语言编写的可以计算+-*/的计算器

写了一个计算器程序,想分享给大家;同时写到最后感觉有点凌乱,希望各位帮忙给优化下,共同提高。这个计算器可以计算输入的字符串,字符串中可以含括号,可以是小数,也可以包含负数。此程序被拆分在5个文件中,我按文件一一罗列吧:

编写环境:VC++6.0。

第一个main函数所在文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include
#include
#include
int  main()
{
     char  *s1;
     int  i;
     double  c;
     double  calc( char  *s);
     int  brk( char  *st);
     while (1)
     {
         s1=( char  *) malloc (50);    //为s1分配地址和空间。
         scanf ( "%s" ,s1);           //输入并得到s1字符串。
         i=brk(s1);                //执行所有"()"中的计算式。
         c=calc(s1);               //计算最后的不带"()"的s1。
         printf ( "%g\n" ,c);         //输出最后结果。
         printf ( "--------Press Up/Down Arorw or Begain Next Input:\n" );    
         //提示执行下一次运算。
         free (s1);     //释放s1内存空间。
     }
}


第二个函数文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include
#include
#include
double  calc( char  *s)    //把s拆解成double型数组和保存操作符的字符型数组,
{                       //并利用两个数组计算结果。
     int  i=0,j=0,k=0,num=1,end=0,sub=0;     //num、end、sub为开关标识。
     double  *sn;
     char  *sc,*sp;
     void  mathc( double  *a, char  *s);
     sn=( double  *) malloc (51);               //用于存放s中所有的数字串。
     sc=( char  *) malloc (50);                 //用于存放s中所有的操作符。
     sp=( char  *) malloc (10);                 //遍历s中的各个数字串,并保存其中。
     //while(!isdigit(*s))
     //    s++;
     //c=*s;
     //if(c=='-')
     //{
     //    *sp=c;
     //    i=1;
     //    s++;
     //}
     for (;*s!= '\0' ;s++)                     //遍历s所有字符。
     {
         if (! isdigit (*s) && *s!= '+'  && *s!= '-'  && *s!= '*'  && *s!= '/'  &&
(接上一行) *s!= '.' )     //如果字符不是数字且不是操作符及小数点则输出错误。
         {
             printf ( "Error 6: illegal input!\n" );
             return  0;
         }
         if ( isdigit (*s)||*s== '.' )         //如果字符是个数字或者小数点。
         {
             //if(c=='-')
             *(sp + i++)=*s;
             //i++;
             num=0;                       //把这3个开关置为0。
             end=0;
             sub=0;
             continue ;
         }
         if (sub==1)           //sub用于标识s中负数,比如"-5",
                             //但是如果有两个"--"则是错误,
                             // 除了类似"4--5"【等价于4-(-5)】的情况。
             {                //"--"前没有数字的情况是不允许的。
                 printf ( "Error 7: too many operator!\n" );
                 return  0;
             }
         if (num==1)           //num==1说明是字符串刚开始(即第一个字符)
         {                    //或者上一次执行的是“+-*/”。
             if (*s!= '-' )      //开始不是"-"或"+*/"后面不是"-"。
             {                //(注意在这个时候肯定也不是数字,
                             //因为数字已经被判断过了。)
                 printf ( "Error 8: too many operator!\n" );
                 return  0;
             }
             else
             {
                 *(sp + i++)=*s;      //开始是个"-"或者前一个字符是"+*/"。
                 sub=1;               //把sub置为1,即下一个字符不能再是"-",
                                     //注意这是在num==1的情况下。
                 end=0;               //执行的是数字字符部分,此程序把
                                     //这种情况下的负号做为了数字的一部分。
                 continue ;            //执行下一次循环。
             }
         }
         if (*s== '+' ||*s== '-' ||*s== '*' ||*s== '/' )   //如果执行的字符是操作符。
         {
             *(sp+i)= '\0' ;                      //是sp结束,即结束数字字符部分。
             i=0;                               //使下一次sp从0开始计数。
             end=1;                             //标识数字字符部分执行结束。
             *(sn + j++)= atof (sp);              //把sp转换为double型数组。
             if (*(s+1)== '\0' )                   //如果下一个元素为s的的结束,
                                               //则不往下执行,即不保存这个操作符。
                 break ;
             *(sc + k++)=*s;                    //既然s的下一个元素不是结束,
                                               //那么把这个字符串保存到sc中。
             num=1;                             //因为刚保存的是个操作符,
                                               //下一个不能再是操作符,除了"-"。
             continue ;
         }
     }
     if (*s== '\0' &&end==0)             //s的最后一个字符是数字字符,执行这一部分语句。
     {
         *(sp+i)= '\0' ;                //使sp结束。
         //i=0;
         if (*(sp+i-1)== '-' )           //如果上一个字符只是一个"-"号,则输出错误。
         {
             printf ( "Error 9: illegal input!\n" );
             return  0;
         }
         *(sn + j++)= atof (sp);         //把sp转换成double数组保存到sn中。
     }
     *(sn+j)= '\0' ;                     //是sn和sc结束。
     *(sc+k)= '\0' ;
     mathc(sn,sc);                     //把sn和sc传给mathc函数计算s的结果。
     return  *sn;                       //mathc的计算结果是保存在sn中的,
}                                     //把sn返回即可。


第三个函数文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include
void  mathc( double  *a,  char  *s)                             //执行计算。
{
     int  i;
     double  sum;
     void  offsetd( double  *s, int  n1,  int  n2);
     void  offsetc( char  *s, int  n1, int  n2);
     for (i=0;*(s+i)!= '\0' ;i++)                             //先计算“/”。
         if (*(s+i)== '/' )
         {
             if (*(a+i+1)==0)                                 //不能除以0。
             {
                 printf ( "Error 5: illegal input 0!\n" );
                 break ;
             }
             sum = *(a+i) / *(a+i+1);
             *(a+i)=sum;
             offsetd(a,i+1,1);
             offsetc(s,i,1);
             i=-1;
         }
     for (i=0;*(s+i)!= '\0' ;i++)                             //计算"*"。
         if (*(s+i)== '*' )
         {
             sum = *(a+i) * *(a+i+1);
             *(a+i)=sum;
             offsetd(a,i+1,1);
             offsetc(s,i,1);
             i=-1;
         }
     for (i=0;*(s+i)!= '\0' ;i++)                             //计算"-"。
         if (*(s+i)== '-' )
         {
             sum = *(a+i) - *(a+i+1);
             *(a+i)=sum;
             offsetd(a,i+1,1);
             offsetc(s,i,1);
             i=-1;
         }
     for (i=0;*(s+i)!= '\0' ;i++)                             //计算"+"。
         if (*(s+i)== '+' )
         {
             sum = *(a+i) + *(a+i+1);
             *(a+i)=sum;
             offsetd(a,i+1,1);
             offsetc(s,i,1);
             i=-1;
         }
}


第四个函数文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include
#include
void  offsetd( double  *s, int  n1,  int  n2)  //使double数组的n1+n2处的元素往前移动n2。
{
     for (;*(s+n1)!= '\0' ;n1++)
         *(s+n1) = *(s+n1+n2);
}
void  offsetc( char  *s, int  n1,  int  n2)    //与offsetd功能相同,只是s数组元素是字符型。
{
     for (;*(s+n1)!= '\0' ;n1++)
         *(s+n1) = *(s+n1+n2);
}
void  repl( char  *c1, char  *c2, int  i, int  j)  //使用c2替换c1中第i-j之间的元素。
{
     unsigned  int  n=0;
     int  a;
     n= strlen (c2);
     for (a=n;*(c1+j)!= '\0' ;)              //先把c1中第j元素以后的数字复制到c2后面。
         *(c2 + a++) = *(c1 + j++);
     *(c2+a)= '\0' ;
     for (;*c2 !=  '\0' ;)                  //用c2替换c1中第i元素往后的所有元素。
         *(c1 + i++) = *(c2++);
     *(c1+i)= '\0' ;
}


第五个函数文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include
#include
#include
int  brk( char  *st)     //计算括号内的算式的值。
{
     int  m,n,d,b;      //m左括号位置,n遍历整个st数组,d右括号位置,b用于上s2数组。
     char  *s2;
     double  i;
     void  repl( char  *c1, char  *c2, int  i, int  j);   //调用repl函数使用s2计算结果
                                                //替换st中相应位置的字符。
     //void mathc(double *a,char *s);
     double  calc( char  *s);                       //计算字符串s的值。
     s2=( char  *) malloc (50);             //为s2分配内存空间,并返回空间地址。
     for (n=0;*(st+n)!= '\0' ;n++)         //遍历st数组。
         if (*(st+n)== ')' )               //首先查找")"。重要!在多重括号
                                       //中查找")"才能有效的找到每组括号。
         {    d=n;                      //把"("的位置保存在d中。
             if (*(st+d+1)!= '\0' && isdigit (*(st+d+1)))  //st的下一位是个数字则
                                                     //输出错误并返回。
             {
                 printf ( "Error 1: ();\n" );
                 return  0;
             }
             while (n>0&&*(st + --n)!= '(' )       //从")"的位置n往回查找"("。
                 ;
             if (*(st+n)!= '(' )            //while语句执行完成,此时n==0;
                                        //但是*(st+n)不是"(",则意味着没有匹配的
                                        //"(",输出错误。
             {
                 printf ( "Error 2: ();\n" );
                 return  0;
             }
             m=n;                         //找到"("的话,把n的值保存到m中。
             if (m>0 &&  isdigit (*(st+m-1)))   //m位置的上一位不能是数字。
             {
                 printf ( "Error 3: ();\n" );
                 return  0;
             }
             if ((d-m)==1)                    //如果"()"为空,输出错误。
             {
                 printf ( "Error 4: ();\n" );
                 return  0;
             }
             for (b=0;*(st + ++n)!= ')' ;b++)   //把括号中的内容复制到s2中。
                 *(s2+b) = *(st + n);
             *(s2+b)= '\0' ;
             i=calc(s2);                     //计算s2的值,并返回double i。
             sprintf (s2, "%g" ,i);             //把i转换成字符串保存至s2中。
             //printf("s2 %s\n",s2);
             repl(st,s2,m,n+1);              //使用s2替换st中的括号。
             printf ( "step %s\n" ,st);         //输出替换后的st。
             n=-1;                           //执行下一次循环。
             continue ;
         }
}


可执行程序下载地址:http://pan.baidu.com/s/1jGiUaYM 。

写的不好,大神勿喷,欢迎指正。

欢迎转载,但是版权所有。

你可能感兴趣的:(c语言,计算器)