捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
PU$o;[g5b+\ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=-Eq2Ha D1Bw} N
/**************表达式计算器************/
S9VX*F'I*] #include <stdio.h>
h9|xs!L #include <stdlib.h>
4w/a4^{h,Ed #include <string.h>
v!]}~$IPC/k #include <conio.h>qA,mS'[V9~UE4G
#include <malloc.h>
k/hZ+fAKO j ~&Bx!_"O-uC4Jx
#define STACK_SIZE 100zg'v4dNk`
#define APPEND_SIZE 10??&R{a$y%^
yY#R2D'WXm[
struct SNode{
h%T2q ub v^     float data; /*存放操作数或者计算结果*/0wf!wW[S
    char ch; /*存放运算符*/
9}`N/HGxZ.U };1V[P|6B
6q4qq%I-]#K[
struct Stack{
IY N |(S(z     SNode *top;
*`]4ZmD:isIy     SNode *base;
'h;C-c$OI8VB     int size;
IfS_ o$S] };
8ER{9\]J @ D){dp!St Gc
/*栈操作函数*/
?z5Rh,|)f#W N7nZ int InitStack(Stack &S); /*创建栈*/
(YX4Bf1G"Z int DestroyStack(Stack &S); /*销毁栈*/
^(H9fc3r+Z_#v int ClearStack(Stack &S); /*清空栈*/
V.E;w0qA7Mm'_ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
\.wD8h0r!Ir&M int Push(Stack &S,SNode e); /*将结点e压入栈*/
S%p`f _Ks/{ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ef3[,sA-R2j

%z4p&I:e1w3r&R5n QW /*表达式计算器相关函数*/
h _#Q X9LLv;? char get_precede(char s,char c); /*判断运算符s和c的优先级*/
co%qk;t+r int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/g,Z6kf4m FX)o"O
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/g%a?C3Q&M9K qf)L
float compute(); /*表达式结算器主函数*/ @&l9_;^&g+D
char *killzero(float result); /*去掉结果后面的0*/ i8u9?:~URx]a v
%yu-~ G5}i-[Rx
int InitStack(Stack &S)
8sv3J`Jhpn {
a[Mx%s^%j     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));c NS| u
    if(S.base==NULL)
Q(|#W+k#@.fw     {
g*F4X"r6QY:r6f         printf("动态分配内存失败!");
j[WBUI         return -1;4L`,{ ^pz_eY
    }
/jFc/Y t$|     S.top=S.base;
S#x[_YyT(w     S.size=STACK_SIZE;3v-Y:c@#C GU@
    return 0;
]+E'v-['z)h ?@k[C }[] u1Q-f

G2CDb4z,d~o)C|"Y int DestroyStack(Stack &S)
S3A-H*h}c$n {l:e-jO+C2Vj^8E1jq
    free(S.base);L/K%b\6B9F
    return 0;
H[up/|3w }
4i)q XY@rK?
~*hU#PA$S:i1? ~p(n int ClearStack(Stack &S)
V%m{QDpx+BP {~*~_!SiD;@
    S.top=S.base;^6zh;XX&r
    return 0;:~3qc{%HD1p
}
3G2PJB3ve%T8`
H#F3C dn\ int GetTop(Stack S,SNode &e)
CD/Y wlfz ~ {LS{W^R
    if(S.top==S.base) fG+QI#E l+v@
    {
\{*xq}M}i;b*I3tF         printf("栈以为空!");
#d(s}"etU,c!m8h\         return -1;
\5YK H\     }
7S6[X*AQ     e=*(S.top-1);h,| a {awh
    return 0;;P1x/G8lz9d6y.R g6C
};xw*}b|

+ROm8rc^ int Push(Stack &S,SNode e)
&`:Q l \ [3M~N7e {
%z"cl3p U6[6|j7Q8w     if(S.top-S.base>=S.size)
1y] H0i%zD+m5a)_     {
G7g7g(T.d         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2[}Y%d?
        if(S.base==NULL)M }1k*XX(p&w h
        {
p#Go+V*FE[ p~ k             printf("动态分配内存失败!");(e }Z/J^ `k
            return -1; ko.Dv;L{
        }
kx0h+Ah8];\k         S.top=S.base+S.size;&f#wqp4|m
        S.size+=APPEND_SIZE;
h6H+qC4Fz     },mhHB]4i6[%i U
    *S.top=e; R7t*~7A2T+N
    S.top++;d2jkMZ
    return 0;
mk:~+T?8`p+\2@` }"N:~'H8J1|i

L{&nbb'c int Pop(Stack &S,SNode &e)
TKTJ4I(o { bA _+V0u6w9G
    if(S.top==S.base) d|pJ^@9V.F
    {)J[ }~|S o Wy
        printf("栈为空!");
z"\7d3g#y;L         return -1;T3C5JjY`y aaP
    } ckv~;Lo]
    e=*(S.top-1);
WU1N"K$kz*}d     S.top--;
nd7jrXT m     return 0;oP%C[$H!gD r~ V9n.u
}
q/I,nnu9t:xUd{
(ICQ4f;psVL1^ char get_precede(char s,char c)
WG"?"S@1n };S {
{2U,hHD     switch(s)
&u2an.Z,Jf/ZT     {"O#k C-S4Y hu/B
        case '+':                 
dl8df&nDPB)V         case '-': rVdC `:p P
             if(c=='+'||c=='-')5bv*L+d^6s1z*a
                 return '>';
fb.P+zK+e              else if(c=='*'||c=='/')4^$`&zdbRf Z
                 return '<';/TxX WX f ] X
             else if(c=='(')
Q*vp-Z6fe                  return '<';4Qzj-SMvLws
             else if(c==')')q0U D{ddnh
                 return '>';,SO;O(I-V
             else K&u(B ~1b%nc
                 return '>';G/D?OXY1x5d:t;e!X
        case '*':
'n }0v&{Rq         case '/':)L.K%N9p+MX/`xdC
             if(c=='+'||c=='-')'m1M1hV[[6ab
                 return '>';
/G&Vhkb@?&~              else if(c=='*'||c=='/')
waUb^0u*\_a                  return '>';
Yi#b lG2z~              else if(c=='(')
^.d4ng:w]'v u                  return '<';'SrM4}9W
             else if(c==')')T @n,B9E&XP
                 return '>';9[x/xw%@}l
             else
y*Duupn                  return '>';(pO~*v!zlA;j!p5U
        case '(':
GR0nk#h4S,Z"@              if(c=='+'||c=='-')o&IHsL9vt
                 return '<';
d@1G$n1M]-@              else if(c=='*'||c=='/')
Zt3o|,z#G I                  return '<';^(n4L#ju l|
             else if(c=='(')
V:FGI#?.n1UEH                  return '<';
*n8h:`/QUR ev;[5c+B[              else if(c==')')1j c"nw'i(n,pj
                 return '=';d v-I*F0] [a
             else A1Q(i"gy2]u}J i
                 return 'E';1V D P;@{ pRx`
        case ')':
1|g0S:k d nEY              if(c=='+'||c=='-')
jHB,S1V9JM                  return '>';
Kl0`\o;C"Hq              else if(c=='*'||c=='/')y2h#A7U*i3Q2r5B
                 return '>';"y2^1?d!S$Jt
             else if(c=='(')@$y:` RHb:c"U_ ^
                 return 'E';+S#QdyFw%V)H2O
             else if(c==')')0y$Z(l$L^;o
                 return '>';w e ?s{)U` Jc
             else8H5F0j R Y
                 return '>';
N"}5ME`AhSE         case '#':\ Kpu'~-MW!D+?0zK
             if(c=='+'||c=='-')i h`3EV{
                 return '<';
~k*Du1v?&E:tvf              else if(c=='*'||c=='/')!G&vn8K C_
                 return '<'; K*G:s|U
             else if(c=='(')Ws K(ZXq-@)Fk&G
                 return '<';Ez+]qj5o"jl~B
             else if(c==')')
B.j-G6Y9e{X5F3mi                  return 'E';
6y&JS*l C,xzR              else
QV7J~E,@v-c                  return '=';
l\8y4Z&NV'W H+T         default:IwV%xVr F
             break;Wx.j|ac'cuB
    }
3q)}#X ~ w~d     return 0;   
$r&y,H.H5V }i c1c"\o xD"G A'b t
W1X!d&b ]@7g6K{S3o
int isOpr(char c)
2W+Jhv2p"Jhmy {'p(b/B VP\
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') @/su2y/PFH%t
        return 0;1k6e%Z |P2}'I'YK
    else
%S4gA4}6|'n|         return 1;
,ZV{:w3\xs~ }4UQ3Aub!Y9h
~)V7xN:B.H
float operate(float x, char opr, float y)?9j5S7RwIU
{7wm uh%C!F
    float result;
Z|d%KbwP     switch (opr)*M:v6GKhsg^
    {z(eNP-g)d4]0gy]
        case '+': v"y k5CZ G'Yhp
             result = x + y;a$} t!sC:q
             break;(d.w7]'GY L.iw
        case '-': #P!Wb;F6n2] xjY$s
             result = x - y;yd@ZLHrh
             break;Z7Cc2}5WQ5h6u
        case '*':
3xb9T_q              result = x * y;
.W c+vP0t)J.c7U              break;
uZ'Jx uS.SD[-d^I         case '/':
kh"}Li              if (y == 0)
Y+m X3vv e              {_,X'[ ]-j%E
                printf("Divided by zero!\n");HIcUnep b|
                return 0;a w/Xr(E!iH]9{
             }
v"K di&{2h              else
-OE3E s4^r$j              {@l9dH/],B+Nl@
                 result = x / y;
|3si5ZXC0s4zs w                  break;DNn:`-BMRx(E:m
             }a gBA|gH
       default:
M8XNVbf/A;~              printf("Bad Input.\n"); z$glq1}ZKs
             return 0;
@&~8@;B!F Sbu     }
b.XT6xc,u[     return result;
+l.C/K`)a}E }   
~ X r7LcZh
n\+OT'xrf/o8[ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/)n1{9n#~+o
{"evIj I.zI j(?O
    Stack optr,opnd;4Z4c} H^Wsy
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;5WrtQ3C1eGe_
    char c;
'BKL4J7BN9X]#j     char buf[16];!p0\2tw)|bV
    int i=0;l(Q(L8r b.p7| L-n
    5O/] WdE%C4a]{/Q#l
    InitStack(optr); /*用于寄存运算符*/3Sh)TrFtb*C2~#M}
    InitStack(opnd); /*用于寄存操作数和计算结果*/#c1hT2Acj*V
    memset(buf,0,sizeof(buf));,PFXT#nld\U
    K)tFz[
    printf("Enter your expression:");Js1gi^gAj}
        -LA9bxB
    opr_in.ch='#';7go"BjkU
    Push(optr,opr_in); /*'#'入栈*/Q+vUi$CM
    GetTop(optr,opr_top);8{9i.WnQ&Y6y
    c=getchar();
'lU$yj+kQ!s,h     while(c!='='||opr_top.ch!='#') I7B~fk(N
    {*j(kb5u!DR5H7n;]4h
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7cE(b'Xvcm
        {
v/PnonS{             buf[i]=c;
b;v6\ HZ[xHs             i++;
2gv.ob4fn^ u             c=getchar();Th/S;QSc
        }`;F] ? rL'Y3oz
        else /*是运算符*/
vh&hdU~O~         {
Xo$S q5n1r,QI;u             buf[i]='\0';M"b0](b%q7m^
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/`/N3fX yDr,NX
            {
'\;F~5r"WgX c6D                  opn_in.data=(float)atof(buf);
A2WK#Oo(s                  Push(opnd,opn_in); [%cvM f*e~
                 printf("opnd入栈:[%f]\n",opn_in.data);+i^7P)G$ihUGy
                 i=0;ydF$bzM A*Sb
                 memset(buf,0,sizeof(buf));8GPUJ7uj!J&}7x
            }
,Eq'd TO Y'J             opr_in.ch=c;6g?Z;k iP
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
#w.pj s!|Df7d             {
`I{(c2b:B|6p-E                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
'B,q6~~:WR5A y                      Push(optr,opr_in);8bN c,k1O
                     printf("optr入栈:[%c]\n",opr_in.ch);
a~ exFb6i.w_ \                      c=getchar();
']/QZ\OA%}                      break;
!dHZ6r!C/mP\                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
wqXrl3D                      Pop(optr,e);]b4k3Kp7B!Z
                     printf("optr出栈:去掉括号\n");
'If$mu V"s8S @                      c=getchar();6@(Zw2SQg3`"vNW
                     break;
?%hv2~+U                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/No5cS+L2c H
                     Pop(optr,opr_t);fC#t4H.OJ%n,f.Q
                     printf("optr出栈:[%c]\n",opr_t.ch);k$xR[)v.s
                     if(Pop(opnd,b)<0)
e9JI'~IE                      {\p A)qzZ v.oz8x!R
                         printf("Bad Input!\n");
3IIA-`Vs6\                          fflush(stdin);I[(R-O"kZN;rF
                         return -1; D7Al8Q d(o-g
                     } yL_uq1Y L
                     printf("opnd出栈:[%f]\n",b.data);
~3Lj2o#qB:J K                      if(Pop(opnd,a)<0)
(O)Q2_$\ Nc                      {DzW:lln(q)P/N
                         printf("Bad Input!\n");
'K3F7SGM+Zke5^&Z                          fflush(stdin);
7v!yE+aF                          return -1;
g$HIHA5Dsi#k3o                      }8YX |_7O'@
                     printf("opnd出栈:[%f]\n",a.data);
$tX#m7Aka                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/OXP~L8}]
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$B;Ms1Mo Kv5a#s
                     printf("结果入栈:[%f]\n",opn_tmp.data);
]L c0d0QOb                      break;
5?!l}$kE v#v a             }L/Or{"OWS
        }
K }2ra c+XT         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
Cc7`F8m     }
K,O HL[N     GetTop(opnd,opn_tmp);
9|^d2w}'A     DestroyStack(optr);
R:up]Li     DestroyStack(opnd);
#pVJB+Q     return opn_tmp.data;
9?T:us/fzb6C3E }
[Bk#k)t
9?;K2e`_"mJ char *killzero(char *res,float result)
abX.o%l:{ {
w$z.SU)tb*w     int i;
y%AEP{0ma2fuC
4f,D_&W$Z*s B#}:e     sprintf(res,"%f",result);
OL0m;R9Jy     i=(int)strlen(res)-1; dYP j/tC7[p5s"w4_
    while(i&&res[i]=='0')
9P!OB5a ?"H C/I'g5v     {+V&q7S4K8NN%L
        res[i]='\0';%h3u7kr+t;q8t,LN#Z
        i--;
8WO K8K%`!P@     }
vy1n)|V3FO     if(res[i]=='.')
;T,\oS'`n X V         res[i]='\0';
G @7N K,J0L]8G`     return res;
A-u(c2m*T"{mE"I };P;q f5X'o{

o;B.wm(|j int main()2u1C@llC
{cS1[I'n
    char ch;
'D;K a l%j@ u     char res[64];1l |(At[IMg\"`q
    float result;8b~h2k0L#N^
    while(1)
+}0L3[4McX(j2AZ     {9UHQ(J Qx Ak
        result=compute();
5[2W L5D yLo*g?ji,O         printf("\nThe result is:%s\n",killzero(res,result));
H%\}J;W LSE2Y         printf("Do you want to continue(y/n)?:") ;M T(hO6X w
        ch=getch();0F_Fl5q
        putchar(ch);eko)BQg S]
        if(ch=='n'||ch=='N')
2},M;kHPA             break;
"|8frPh.p         else
E9St e^7T M{(x!E             system("cls");
6D0Dw9TvV%jHK     }(k#nD%W`f+@,s2W
    return 0;
%U'y(S,@ t s)@ }[/i][/i][/i][/i][/i][/i]
}:OA(O.I0k5Y(E
+PD2j:m~1l+\O [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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