捌玖网络工作室's Archiver

zw2004 发表于 2008-1-21 17:17

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
u}3S2j6Q)h },b*bGa4\ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
]4g6V~pQ'v(aj /**************表达式计算器************/ \5ErHy
#include <stdio.h>t{*bQa yHjB(?~T
#include <stdlib.h>.I9[plv#M6e4F
#include <string.h>
B]Ht!xo #include <conio.h>
-bV s4Z8eAQ8Q P #include <malloc.h>/?DJcQea(q

![ BeR zs0mWjNx #define STACK_SIZE 1001j2[ hwr.aZ:z
#define APPEND_SIZE 10IJ#pe:MU&z{

@3["N4ii;IP2?6X U struct SNode{
2V*sv'? |2sGJ     float data; /*存放操作数或者计算结果*/7F/I)t5i.h1Q/Vq+g
    char ch; /*存放运算符*/q"aP#@%}F0Rzn
};
'B+u2oTq"Y*t
#?:J]J]G8P+W6P struct Stack{Fu*G"sy GO
    SNode *top;T0M9|#H0rk:Y$n
    SNode *base;
V q'z aB     int size;(c}K3M;oi D#d8si
};!P C"G*`}~

5} J)G@lIlp /*栈操作函数*/
/\g2O&L$n;pec int InitStack(Stack &S); /*创建栈*/$IZb'}!S*@
int DestroyStack(Stack &S); /*销毁栈*/7J0Tk|&ba
int ClearStack(Stack &S); /*清空栈*/
^P W#C2UH CK int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/u.LZXOh/mw
int Push(Stack &S,SNode e); /*将结点e压入栈*/3a0EzP\$IE
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
CASjg
'W1y;[ I Bu4NQX /*表达式计算器相关函数*/
by'M bf yx char get_precede(char s,char c); /*判断运算符s和c的优先级*/&Fd)oz L F$u/AE
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/:ej4WOp'q?
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5i-t,R |'I h V&\!gw2O float compute(); /*表达式结算器主函数*/3x\h}4~"F4i
char *killzero(float result); /*去掉结果后面的0*/
2\!t:PA#aFQ mcM.p{w EVl
int InitStack(Stack &S)
t&zy#Y g7F3z ` {
_3cd Yj     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3[1T yhd3K;fd2K     if(S.base==NULL)
)pIm U6iz B-AB9R     {
},IT1EO}N         printf("动态分配内存失败!");Fn+yx+P f IX"QB wH$y
        return -1;-G Z)lw-w:}7E'J
    }
h)]9U0\*u     S.top=S.base;W5Z?)~Pw"@p
    S.size=STACK_SIZE;emZH B.Ev b"K
    return 0;2{eY7R+Q L%G;R
}
r {|"k be v
1o%Yz,lC:^hk int DestroyStack(Stack &S)%jU%rK5Y'?C
{%a/\inDX}l
    free(S.base);
+Y:|%BM'd#j     return 0;gv;}}^@Z}U;ta
}^&hvd w%k

$Fy&V#I4o;f}Yp int ClearStack(Stack &S)1Ttih1Uf9U%{
{:] IxYn@o?m Z+Vo
    S.top=S.base;
3c |n(H _6O     return 0;4|)x;~;K%q Mh+s/`&W
}.h]B{.K g
'@:P*Fg-r;I/P0S4^
int GetTop(Stack S,SNode &e)
1f WW9jVy0|&d {
]b9[_1Sz     if(S.top==S.base)m\F6oB0Fz6M!x
    {
2WKS9C^_W*k}         printf("栈以为空!");
'?f |)n#p/E O         return -1; J(^2T}~]Lc
    }$o8F4S4V\T Ur7gh)c
    e=*(S.top-1);
b;b C0y"n,]w"w~x     return 0;
9T"P^LV5g t }
@iYE)f.~ w1Z1[HG U]*qS
int Push(Stack &S,SNode e)
j]eD/s {!?Hgp4iK[
    if(S.top-S.base>=S.size)9|u.SC#e
    {
%]1@!B.l J"RRW3g%c         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
?nC(W T+ICH9{+R1?{         if(S.base==NULL)
Sj0~t&m;^.I         { P.MKV)g0N:U
            printf("动态分配内存失败!");
;tjqv!xa             return -1;G^ DY1^zB
        }&p2t5F k#K:mp Ed
        S.top=S.base+S.size;Xc,]/CZB*E
        S.size+=APPEND_SIZE;(cp s I)[{)Z+[5L
    }
4unJ9n nM     *S.top=e;![A\lqW
    S.top++;X'_$T1F mE"U:pbk!eZr*\?
    return 0;!_(K6f$~L3X
}
$b+V(u2yN$q$B.aQ(_
1t/V}#V F R S int Pop(Stack &S,SNode &e)
F+G~-HK8J \\o {
y.y1jw SX"O%t     if(S.top==S.base)
g(c)eP4c+v]3p}     {6bj(@K@!lW0D
        printf("栈为空!");
;[cXnrP         return -1;
jL v&wO     }
8e#H4gik;XE+G     e=*(S.top-1);B(Oj+A.d6d
    S.top--;
8pbyuh7@-aVR7?x     return 0; Ku.rlr%D6b4?)a"wZv
}
1wUb I.H3T3y?6y
-A|n \;V(? K b9X char get_precede(char s,char c) `)@v A0}
{'C`%X ?@h1}
    switch(s)
C-a~_;T?     {
5]Fv#T@Hw         case '+':                 
!n@/G2Ko7iJq8h3~+Y3j         case '-':
-MH*X!]E+W? l-t              if(c=='+'||c=='-')
![ I0j6VL%g j]                  return '>';
e6q0I1XM*c{q              else if(c=='*'||c=='/')
I,v~*_-FE7Z!q                  return '<';
1@XG]tse)j ["x]              else if(c=='(')
bV N,Kw@F-L                  return '<';
Z5_B U6D              else if(c==')')t3_:uj5NvBx
                 return '>';
-k:Si0MBW*Z              else U*OYu#l1R+g
                 return '>';5c;CRs"Qu$Y
        case '*':k k T v3o3s!]
        case '/':|%N@"Ljl
             if(c=='+'||c=='-')
%UVe gf\O.x1}                  return '>';
k)g8C1tg              else if(c=='*'||c=='/')lo4R ^E*VR]
                 return '>';
+p PPo'x+mxMsYH              else if(c=='(')
{\ },G;lk"\E                  return '<';
;cQp#Qx,fX              else if(c==')')9U.dS S jG(u,t)@o
                 return '>'; D)Ym)M%R$V
             else
Q h0j%@-P&V_D                  return '>';v d/Z3h R7RK
        case '(':
y9eEd`              if(c=='+'||c=='-')
qSH Bn[-~.^T\                  return '<';
`5K#}J1n(Lt1w}~v3}              else if(c=='*'||c=='/')H.qh0x&L3_8N
                 return '<';s0ufjiS X
             else if(c=='(')
*kjatC                  return '<';3i]H O.DM ?
             else if(c==')')
$|u6z;n/Uo                  return '=';z)N r q*B+s'K
             else
]1OY[v#d$r                  return 'E';8B` R9p/wf~
        case ')':
'U&bpP(hI{ D              if(c=='+'||c=='-')
/q@7}2~_$`,Z                  return '>';z l:h F_ e j
             else if(c=='*'||c=='/')
7B~+L/zj'I6V}                  return '>';
}j$hnD}              else if(c=='(')"`.~/HQj1ytc(A
                 return 'E';;_1heH.k6U _
             else if(c==')')V+kM"q#[ P
                 return '>';
_8UP'Opw              elsed~0` Su)V
                 return '>';
7Vw(_a{4JE8X         case '#':
H)F%ja+z5p              if(c=='+'||c=='-')
/s{)_P/Y7\n8\                  return '<';
;n(x&@O.] Zd3lv              else if(c=='*'||c=='/') ~Xg9f*Hj;`
                 return '<';
e3oFL8bv7q#UK              else if(c=='(')
Y$Z1};DU9z%Y                  return '<';
tWD't]$W9p&T              else if(c==')')
2xs~q%f j                  return 'E';
l\?(qN#v-}OO              else8CPZlN O
                 return '=';
#x"_9} Y0B.n.l         default:
F9mMS0ZH              break;d)qa ` d7HlLsx
    }_3w%M-Th#J
    return 0;    ~&sN7Y4aK
}^iur9`4ZL
Qw-]3d"{` B7Z
int isOpr(char c)7V{"]"v+[V%tV s ?
{
k#EuQJQ:JG6J     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')E4\8X}uwX}-w7e
        return 0;
w'D}]Qv5Qq     else
s!A!]%^.S_L         return 1;
(k.q5Zb h)V1]7K%~VXq }
#eNZ%Ls
4{sc7O:f9Vw3G!v float operate(float x, char opr, float y)
0P$b0G,d&y { l;x_Hu%ON Z1Q I%c"b{
    float result;:Yl#iV"@wg'fh C
    switch (opr)
v I)b"\?     {
H9Ag)q t         case '+': $si_O"@1|3f d6[
             result = x + y;
$E*AW^e;] n              break;
4{n!UiE C{         case '-':
} a#Q%?i&\ j9f8B              result = x - y;
4@;ho7?^ uE              break;
vf(G;dy         case '*':
s ]V Wb$H              result = x * y;
I!`8sL4S;G              break;GrBUk|
        case '/': &i-e%BwF*k0M*I
             if (y == 0)
"x(xni Q              {
;o#jKN.q;v                 printf("Divided by zero!\n");~%Z*P PU
                return 0;
B6?G3x OZ[}              }
ue&o)g"lo p y              else
WIY0|lN-Qf              {
CA]w Bc R                  result = x / y;
+U%]Y h0?U:pK                  break;'j9G7@(C.e+t6k8C_8\d
             })H*?Y6};ND.e
       default: I Xw;],w*M
             printf("Bad Input.\n");
1fi1m#m{4h~              return 0;:@ AtHy!k?+Z.@
    } GW2z9hd_i
    return result;!HOO _ZH
}    X J6OA*[ ~ Q.~
2b8n&w-}J7f5\1sz V_
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/c)DW/a Tqw%y
{&Tu;YQDj!f,S_
    Stack optr,opnd;
.`xGd:f*KF#\     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;?e0~2Gp$t^
    char c;0`gw*^w)}o Zy%W(Y
    char buf[16];E+uoqi8f}iZj
    int i=0;1` a8H$?7D o"B8JPu
   
6Rdg3z1T#L{     InitStack(optr); /*用于寄存运算符*/]0\_3LxR8I%KH k
    InitStack(opnd); /*用于寄存操作数和计算结果*/
b\9j-_N:e     memset(buf,0,sizeof(buf));}-`SL:z
    -k,vuV5v3U-f@
    printf("Enter your expression:");&O1K5m{j&oa
        bX-s^:e#@
    opr_in.ch='#';
2Z[j1GO"]x     Push(optr,opr_in); /*'#'入栈*/
G\O~Aa7jZ{     GetTop(optr,opr_top);3p8Yj']_P\l"J-t
    c=getchar();
Km5E:Sr0Q6Y]     while(c!='='||opr_top.ch!='#')`1Ih"y}P-y
    {
0o g7L] OYpER         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+[6zd+[*O3b
        {
ES6scjYBf             buf[i]=c;eq$S$tC*RO:sJ/A
            i++;
9c-dTE.@#T             c=getchar();Et [ sN2T2g7Z8}
        }
5f1\J B9r4^         else /*是运算符*/
6uN0W"F*h:O+_$kt4v         {C7Rejx+s8C}N
            buf[i]='\0';
N"K5VbV$o3g             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
T;\0XU(f WP s             {"Tm ~)||q
                 opn_in.data=(float)atof(buf);
0N)W[QcSG b                  Push(opnd,opn_in);:C8C1P+w]P/T guT
                 printf("opnd入栈:[%f]\n",opn_in.data);9I\"A4?!Z
                 i=0;j@nh(M;n[2I SC~/?z
                 memset(buf,0,sizeof(buf));
Dr:R)C&E+@8yn             }
L+W@U"s~8W             opr_in.ch=c;
;O z'LlP[             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
;Lh;Rys%kn;O             {
(EcAE@/d1Cb                 case '<': /*优先级小于栈顶结点,则运算符入栈*/!?K8s,^+E
                     Push(optr,opr_in);
#m^ ft+[t6j_"ru                      printf("optr入栈:[%c]\n",opr_in.ch);
9xb0vk1]8T,o'qk                      c=getchar();v o;Fx/t j!J
                     break;j ]`8rLC#]N
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/m Y9AT$`9w WP{
                     Pop(optr,e);
1TDYS H                      printf("optr出栈:去掉括号\n");
)f'Eb"rg_cl[                      c=getchar();s J)fs0jn&SOJ
                     break;
[ Ha&p#P"W td                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
:[T2\ly&jz                      Pop(optr,opr_t);
Ymn J Y"x8}(k                      printf("optr出栈:[%c]\n",opr_t.ch);
L;UCRe'qb7Mc                      if(Pop(opnd,b)<0)
/e5E!cxOut                      {3?:w"wny|n
                         printf("Bad Input!\n");
I;xZS)L3uEN%k                          fflush(stdin);;c$aM.IG6u-{w!h
                         return -1; |A*NaM9Fv4I^
                     }
5v ha+Tk8lO4q                      printf("opnd出栈:[%f]\n",b.data);l$^Hs K
                     if(Pop(opnd,a)<0)
)|f/c@#G.G0um                      {
"LW9WDLGE[9Fc,?                          printf("Bad Input!\n");
U p [+xSR                          fflush(stdin);
8\ op5H/vB                          return -1;
7r0eaUq,bR4Q `s4a                      }
#\8N~GaN4q0p#x;j                      printf("opnd出栈:[%f]\n",a.data);~ C,iOw'S+o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
%_P iS8E8?3Xy                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/(V9j7M7h P(y4N,Bi
                     printf("结果入栈:[%f]\n",opn_tmp.data);:P}9l0E|$A \
                     break;
&h"akQ ZSO z             }3` }hdsmW p [n*P
        }1^.}@@ oE2{
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
g&L]D,@T8mG4r/t     }
l'n;M.N2x\6@hL4\     GetTop(opnd,opn_tmp);
A)I*ted] UYH     DestroyStack(optr);~5p:_Qj!csK
    DestroyStack(opnd);7`K,[j5V a
    return opn_tmp.data;
)Bp-Yn"ebi$r9O,V} }#{:m?TfHk q

&dgjH7a:H Npy char *killzero(char *res,float result)
$F0a$M%?k5m;O&D {.PS2w:}l#Q%U
    int i;
.C^(Z$g%wf"iK9y `)t+h7_L/S5g&x#H
    sprintf(res,"%f",result);
G4o;fQl)\(I     i=(int)strlen(res)-1;
h$T&jn3{     while(i&&res[i]=='0')I K Jq+k ~ q3Y ?
    {H+l;];p W,~
        res[i]='\0'; F'P-\CJ(EdW1]
        i--;
%_ w hx&Kwm^g     }-T*o |9r]N7X
    if(res[i]=='.')
6a9RS#Wf(]]         res[i]='\0';
$e&kf:o;o$f,V I6wc     return res;V!Rbq | O8g
}
5LX6z'O yy p&B o8j,E%]GG6ha!k(['Y&@
int main()
8P5AmVCAM.Yg d*S6o { }jkg#]itY
    char ch;
:aa*E3Llp     char res[64];
)x\ekS9B? a     float result;
J FI}&q;W9c1q,~     while(1)
*q O_i2Y1F5Z9?     {
OX*^6~9[+T7hcGS{         result=compute();
g(FoIwi         printf("\nThe result is:%s\n",killzero(res,result));
)T,mB~.~"s`         printf("Do you want to continue(y/n)?:") ;
:h(f2UHdxc.y7v         ch=getch();l4u-i^t[V
        putchar(ch);
+S~QsE         if(ch=='n'||ch=='N')J z$SG(t
            break;/m v}&M4v ~*B
        else
OX:@CJ?ej&@+G;Ke             system("cls");
L!\pT4P?0^DQ     }
gT$h1MM csj     return 0;h-@RT D_} y p
}[/i][/i][/i][/i][/i][/i]
(WqfX{3H -h-N&HX1AH
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.