捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.x"x5eoR$U Lpz
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
&? ].v8Jbm$x /**************表达式计算器************/
DF:mh!H[ #include <stdio.h>
V Fafv T7z #include <stdlib.h>SNfrQl%OQ
#include <string.h>
R PUW1| #include <conio.h>8pB0?"d1g NqAj
#include <malloc.h>\|.X1wNq Ky

WH-W3Z(F+F PW #define STACK_SIZE 100
[r@*g:? u7K7]cH #define APPEND_SIZE 10
$Bp}"Z?$Z0K "Ic3k i-y+jgy!ms
struct SNode{
*p*CA K,p     float data; /*存放操作数或者计算结果*/l};X+_S
    char ch; /*存放运算符*/
1F C;`1R+f8bP2\ };"}G'p&c8p

] L2g#Y+t(H r;k struct Stack{9` u+|YL6y1Z Y c
    SNode *top;a4ticXn!P
    SNode *base;
;t6o!kxg.o2\!~r V|_     int size;-U1E0f,})wY&p/`
};
CQ6u xF\s{
]$L*l2\Ht V5_ /*栈操作函数*/p G A(M/v#Xy
int InitStack(Stack &S); /*创建栈*/HQrDb
int DestroyStack(Stack &S); /*销毁栈*/
Mjq&zd%|9p0l int ClearStack(Stack &S); /*清空栈*/
8UOE*|2ug int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
)~` w0`[+|$o)y int Push(Stack &S,SNode e); /*将结点e压入栈*/
pGdC6l6G int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
:xgKJ:k.Ubh{R
Foe*D!O /*表达式计算器相关函数*/2k~wP8]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
o*Nyx)\/k4v}N]9R!P int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
aZ:a `P\ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/m+C9sW6?G`;J
float compute(); /*表达式结算器主函数*/qe;P`8r
char *killzero(float result); /*去掉结果后面的0*/ |%Syh ?8s
:EE9j%\1_
int InitStack(Stack &S)
:K$L2b ]!s:QR8s {
6j1b Z/H3c     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));3T D.W+Wv-d
    if(S.base==NULL)
8^5Ur7x-v8R     {
y([i$q^&vI         printf("动态分配内存失败!");#@/MbrY.UZ9}.m
        return -1;
;N `)buBM'`G     }
1PIX7Q/]0~     S.top=S.base;.r@$n%o;i
    S.size=STACK_SIZE;
oX3_7q3K     return 0;
3S'k@"jT'}_+` }
1klUn2a,wE4n.lh i?+O)Kl}
int DestroyStack(Stack &S)
+Qm0t aT O#[ {:A:p!n'qg#HK9f)R
    free(S.base);|"A]%yR MC|/B
    return 0;~.|s(c Au
}u'tj#? PG

"C/r8Qgz!GsQ int ClearStack(Stack &S)Z-EW,`%OaR a!lGFo
{
7G ~n[ g     S.top=S.base;rgB Bd0B5|8dUK
    return 0;4r#i{7AS*L {
}
w`x%O:G&V iP
!Oc9T!i-Aj}{Se int GetTop(Stack S,SNode &e)
(e(F'M uE#J` {T1O/W?)D
    if(S.top==S.base)
1^#uN1Xd!B0[     {
1| u~,tUH;dSg3Tg)|         printf("栈以为空!");G2fl5I5Et y#a
        return -1;O(r%[(UNzw
    }4tT W1[^6WI
    e=*(S.top-1);
#n.F iRx J     return 0;,AB C,}4b-Mm(VmH
}3j"`-nW+r,mCp{(t y'@
b#HST`
int Push(Stack &S,SNode e) x7Ice1F*q`t
{ eZJ9\5n T)y6|1Y
    if(S.top-S.base>=S.size)GP.]jT5x
    {$B4|8TpW
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
j I7Q3T,T iM`5@O(d         if(S.base==NULL)zz$A:g+_Wb4@
        {
:b8`v+Z5ip;Y             printf("动态分配内存失败!");
?} jm j^             return -1;kj2G%t|9m
        }
.xai ]\         S.top=S.base+S.size;
N-]1[&dc         S.size+=APPEND_SIZE;:ce%`LQo/CZN
    }IG"iI Q;l
    *S.top=e;t6}*e:t%]9\4{w-q
    S.top++;dAEO-ECbY r.s"x E
    return 0; \ w;q%rj e#~!^
}
AX h"}ON 7nrJC^}0m/RJ
int Pop(Stack &S,SNode &e)t3m _PXmP
{1EteH[D/~_SL^
    if(S.top==S.base),m/}x,a&J sw
    {
xi;X%Q`~7q6q-F         printf("栈为空!");M8`"Ud(a1Yq'FE
        return -1;-]0I$yZ-_B@V({
    }
f$}Dj:[g&V     e=*(S.top-1);
]#rKt bN     S.top--; };D/JK%B?9p
    return 0;R(t^)F fR;W
}
i:D'ah8^dh!Z (t.h9\_5Ch)V
char get_precede(char s,char c)
/Q }S s#\#AG't {{%F ^G/a
    switch(s)
3U(hAxil     {
.G%P S_)b4^5u         case '+':                 /K k7t |6S {,x^@
        case '-':
kr;E1{'vW              if(c=='+'||c=='-')
Ce+`+^"Uu                  return '>';
0d`W-DIgr&|              else if(c=='*'||c=='/')|$qq \)L*z#Yz
                 return '<';
:Y.Xo9z7cb-_7W?!Uv|              else if(c=='(')
3m"G"yP5V2qr                  return '<';
m7o'M:S2U#^Xv1Ba              else if(c==')')p]Q#x0q7l
                 return '>';Y5b(O%Z4@+JF"S s
             else Q] `2G/}]
                 return '>';y @}:?e%E
        case '*'::~~ Xh({|2I/s{
        case '/':
nZ"v4s$A)k              if(c=='+'||c=='-')
#}u.qa8U^U _v1I                  return '>';
6y f8za;N Q.d|              else if(c=='*'||c=='/')r2OH-yh0Jk
                 return '>';I+D8a0_)mYU-J
             else if(c=='(')
F6d S{1~J ^5[                  return '<';;NUGIR Q tI}
             else if(c==')')
9V0D:E(JZ                  return '>';
+G5N ]vnIW              else
az$j\[k:OdX                  return '>';W:DH5o9R0B.m
        case '(':
n'H2t4kQ j A#f~              if(c=='+'||c=='-')b[\3q _%Y%v*EY
                 return '<'; ~0ebd#aS
             else if(c=='*'||c=='/') O@xn?/A;i1V
                 return '<';
a[d-u1m.}V3x9e)s              else if(c=='(') t'n b8] \4S6oyY7r
                 return '<';
g ]A}3j]2f              else if(c==')')cM?0t`]ai
                 return '=';/BG g }Uy"a
             else
uqR8_3w                  return 'E';
m5V^4xS         case ')':
4cR4ZsR f              if(c=='+'||c=='-')hp [b+zVPh
                 return '>';
UX{/U0X Q4J              else if(c=='*'||c=='/')2| sq GJ)qo
                 return '>';
0v"W,b]n)D,a7mv              else if(c=='(')&Oq2W&z jVN8M2a2_
                 return 'E';ty4\:`O{w
             else if(c==')')
fd!i'a v(Z fU                  return '>';
c9hiIv4GuX#B              else:`9Bn)O?6@#YF
                 return '>';_3` y.qB ] O
        case '#':,K*e8B/X~ ^'l
             if(c=='+'||c=='-')
xAf*{:w                  return '<';
-PIK gHH ns              else if(c=='*'||c=='/')
tW#d ]lbB {.V                  return '<';1~ S LT&SB?
             else if(c=='(')
0E/Ja]RD ^                  return '<';IT}4By.\-H
             else if(c==')')VRykdC
                 return 'E';
1Q1I a^S yq              elsej"Q5O1G1f)Q
                 return '=';
{*s Q1h.A w         default:"jt.Y2W?&G9?
             break;
)U Zn+p Qf$zF4~     }
:C] b I Gbv,Dg_     return 0;    ;a"x9b7~$f't6i7NX
}~ Eh3\,p6L7yk

&jd!_8Ni fT;Z int isOpr(char c)?*n$T0Y-|vu
{
,K0_8Q_,M;z])ab     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')CT"?^$}Ew
        return 0;
;pt:k9l;?Q4i ?     else
nL&sBW?         return 1;o8oQ2E2m.F?zE
}
fZ4^0Wk.F K5I
e8|u~&AXH float operate(float x, char opr, float y)|,uqG6[;D
{
a?im6T}6?     float result;5{M!l h#M)]
    switch (opr)
:z:RyAXVb     {
m.AXT6TR8b|y*L         case '+':
9T3ky1MW?8F'F              result = x + y;
0Hf+AF~eZ              break;
?E!U+h&e(O         case '-': H+p)z6z$m%Ms7e*}7o [ P
             result = x - y;I._g1b!E]J%c
             break;
w})u}.t PQ         case '*': #M"lavZ.|"u9R
             result = x * y;T!w%NJ"SOP
             break;)n B'?pvRDr m9W
        case '/': z |C b1m&@f\
             if (y == 0)
/zIa"NV)P;?L              {
m\,M5aJe3H+E                 printf("Divided by zero!\n");
X'w#oh4z+i                 return 0;o h6ka.a7K7a?i
             }8XZ!A8}\v`
             else
f^|`_+M              {'P.~Eo&i3D ]8w7`Qg
                 result = x / y;
7Y~"Q2Fz:a8v qYa?                  break;z3}(i;_I0SF
             }k#[2m/\;N
       default:
0O6Y(f]$bS5r1c%h              printf("Bad Input.\n"); [P]w$~4Nc:Z
             return 0;
5Rj o,l3xs![i     }
X_/gL!\6w;W _7]@ Y!~     return result;"u5Mw3E9~Z
}   
)c6mF"q C
:hK:crx float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
g,P&v"kZR Y {
)W L"d sM!WL     Stack optr,opnd; H$jG5`Jf|
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;^#B,h,G3?9I PW,t0}3d
    char c;
.g ~ |3v:m9I     char buf[16];
*H8VxI I,h%r0g     int i=0;
f7f7IfsE+E8IkY     %oG;[w/{x_7EF
    InitStack(optr); /*用于寄存运算符*/8Fz AvV5x5c A1@
    InitStack(opnd); /*用于寄存操作数和计算结果*/
6B;p3k Hu     memset(buf,0,sizeof(buf));
S|c.K${ x+d    
+Uem/{&YVi:p&Gc     printf("Enter your expression:");L*A?"gU{Y I3Y
        7ya%~#hY^j"Zr
    opr_in.ch='#';#e'X,i(B$d ~
    Push(optr,opr_in); /*'#'入栈*/k0{b4v`M
    GetTop(optr,opr_top);
)M-i N {m8g8s     c=getchar();
qJ6@q#Y;z9B.X g:^R     while(c!='='||opr_top.ch!='#')
2F7_+ADn4h)~`     {
6I2`6lRv+y1KHJ         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ L7X$N"Cu1Zx.c2C
        {
S~X@]             buf[i]=c;
/x$ec:^e?4A             i++;8e4fjt9U JP/ms$b]
            c=getchar();
T3\B5u$Q.o         }
_Dd \?*V;K8L([x         else /*是运算符*/
2UqV;g H         {
"z})||| c N2Q             buf[i]='\0';
^%qiAo             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
p8S X)]&OgFCD             {
5[U]L}&B                  opn_in.data=(float)atof(buf); EFe(gm b]Y
                 Push(opnd,opn_in);sQSM Y&G
                 printf("opnd入栈:[%f]\n",opn_in.data);
Lfh`1hnx                  i=0;
J[ F Er8ma!C                  memset(buf,0,sizeof(buf)); Zr&r:QDE!X+~(W
            } R(D$l*v&z5K,F z9F[
            opr_in.ch=c; } ]-P0RTM CrH*I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/~o qU n4i{F
            {Q#N-K7?tP4XCS
                case '<': /*优先级小于栈顶结点,则运算符入栈*/;n S,_5}8y ` g)C
                     Push(optr,opr_in);-h#]]uf)BpL
                     printf("optr入栈:[%c]\n",opr_in.ch);W@\!COru:b y
                     c=getchar();
M%@~zi$o                      break;
*\ ^;aV:_                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3u%\ _NTQ(D:I4rRD3d
                     Pop(optr,e);M6^o#](_8O,g9J;L
                     printf("optr出栈:去掉括号\n");
Q? y(w D*rf                      c=getchar();tA$KwQJ1t'Rj~}
                     break;
eT n S2[                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/j)xiB!f#S$c|l[ x
                     Pop(optr,opr_t);e1tD9i@Pd
                     printf("optr出栈:[%c]\n",opr_t.ch);
2rxZ!UDi`,UAT                      if(Pop(opnd,b)<0)b#Y:|`avGF
                     {
.b vwvqS                          printf("Bad Input!\n");
IP m7tz                          fflush(stdin);
~{|d3Q'rb                          return -1;
@qQ}h0WXA'\ @                      }
%`M,c3e,Q$st{                      printf("opnd出栈:[%f]\n",b.data);
n |,MSh2wr&H B'd                      if(Pop(opnd,a)<0)
5D c9I1E Qqvp                      {GV9b#x4l,Q%B$v4v
                         printf("Bad Input!\n");,I/H gdk~|
                         fflush(stdin);s;\!p:g7?;H
                         return -1;U:^uUg C
                     }
4P7KJ^:C                      printf("opnd出栈:[%f]\n",a.data);
@X[[s&r N                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
r"N8G5AL1r                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
Ct Yv aeW%R                      printf("结果入栈:[%f]\n",opn_tmp.data);F%e?5o#@j \6q z
                     break;`Z7?-KIU,|
            }
6x;u e9HaZ5V;] _IQD         }I:KW8[~ N],R&B
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
F aC.\ ~;p%t0\     }
MP _{?     GetTop(opnd,opn_tmp);
oI M3}1b;O     DestroyStack(optr);
8nzJ5l-q.s2e^#U     DestroyStack(opnd);9YHW c3LWp&kI
    return opn_tmp.data;
2b W%Gk,w4c MA0~? }
1ll!M(r!EK| #@ ?j~a*X
char *killzero(char *res,float result)
-vz's.d y:M { PB%t2SS~$n G
    int i;\f8b1[XI{

!GM6~!b RQ     sprintf(res,"%f",result);
%lss3{$y(u-]&I     i=(int)strlen(res)-1;
3aoHk'W$o!n     while(i&&res[i]=='0')
XBrE&Pd     {
hi+X$@\}\9g         res[i]='\0';)K:G,bQ0@h R#t_kzC'@[
        i--;|Ep_&~TK@+a
    }d;}:h7WK]~o/dy
    if(res[i]=='.') z _,@^3u s+E
        res[i]='\0';2M%~`fx%A}n!SD
    return res;{#@"}0Z mx)M/U
}:nN t7]4AM)?
"e0q5sGv#Qo
int main()
YO$e(W%]4Q8G9Ol {c0W$|HO2u
    char ch;
1mO Mx7da s%D?     char res[64];
bz'jN;g,a5N;c0[q     float result;
mcB~'} P-Zs1C     while(1)
+S&sz.R5HZ5R     {(]*{ `;X]'S'F/|,]
        result=compute();,FW*k z d*I8X
        printf("\nThe result is:%s\n",killzero(res,result));kUp$d-\
        printf("Do you want to continue(y/n)?:") ;)lqC J@K#nlu
        ch=getch();
A]#j:{}T*K`C`         putchar(ch);U ]:mn_ r
        if(ch=='n'||ch=='N')$n m.xzce
            break;
/] d j"E3PL:zf f         else
1z#g;H4a \ M.T             system("cls");m[ ?5v0~,p'|.D~
    }J%\-of b*L
    return 0;8L6fU#AV'Q~7@C{
}[/i][/i][/i][/i][/i][/i]
Z9i ^ l$T"U:R e?'O sLW
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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