捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/lWTe3X,a,z.q 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=[JlJ@q
/**************表达式计算器************/#S b2Fwu6~x
#include <stdio.h>
i}'@b'pK!R"g T #include <stdlib.h>
w"m~ vk #include <string.h>jlFi7m#O&b#k
#include <conio.h>y(jl9a$ykv
#include <malloc.h>
k$TtG+m] i ?
:Z7X.BM%gs X #define STACK_SIZE 100
o:dL.i9xxEao #define APPEND_SIZE 10
!?5_5s-Q'IT&L s$K:Q!bo;F
struct SNode{Ei|A#l![U
    float data; /*存放操作数或者计算结果*/'Q1e%gE/t;O
    char ch; /*存放运算符*/d+E ]6Q;a8S\;J
};*i;UT"_*]-M!FIZ
!O xw A sKU:|
struct Stack{/RR H"Q@q2I!Y
    SNode *top;
r*P0A2v1C7^h8u     SNode *base;
,[*`-KO,F$e-OR{k     int size;
&MtZq G9IK7H$}f%O8g,|R };
G|'`-F0|]C
*mIh!mo,F })^%Z0E /*栈操作函数*/
`*z*?7?2^V:H Yf5I3[ int InitStack(Stack &S); /*创建栈*/B"p9pA P4^?
int DestroyStack(Stack &S); /*销毁栈*/$lLY[2P8Y/TP%`
int ClearStack(Stack &S); /*清空栈*/cNJ2f|s Fy
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9udQK"L6Y3x-q u+n2v
int Push(Stack &S,SNode e); /*将结点e压入栈*/|sc$sWB+s
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$[C7H.t(E6H

#wc:sm"M ?*ja e /*表达式计算器相关函数*/7MsC9qF&Db"n
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7xe3k}7EVi6mo$^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
$XN.{!E5g I?p;~ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/udY9D`%S,u%O
float compute(); /*表达式结算器主函数*/
4c1e _HY8d char *killzero(float result); /*去掉结果后面的0*/
v9KH_6T6XX ANq 0tdC3ap$s
int InitStack(Stack &S)0j#@ yC1g6p7g:p
{
-L,M&kvZ     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));$}L:kl+Hs)t
    if(S.base==NULL)
qKE5GYB9k3j     {irc3vr
        printf("动态分配内存失败!");(_4kIH1is*LE,n
        return -1; _ ^~E:IFh s
    }{&YE"u Q l4@
    S.top=S.base;3h!A,Wtg
    S.size=STACK_SIZE;
-M @*Jx T,|     return 0;
/L"y6O ?\;W }
k0Y/wRD(lX
*~k W mb5y int DestroyStack(Stack &S)'z(Vq^j d Y
{ E1?:Fs ^'h+U8r1VV
    free(S.base);B+o~fH4u
    return 0;R]n W3M.K b"B
}
u1QWTq/Z :QMN i5{:p H8V
int ClearStack(Stack &S)
6g$|/LLD"q`0B {
U.m\ \6ME-f     S.top=S.base;5b_X#~)_
    return 0;
m8lpC clnu[,B }7]+M1`u8u9V,a+Ik.A
.`[9j:oh){PL
int GetTop(Stack S,SNode &e)#y6Udh.?w
{2sn|$Hs
    if(S.top==S.base)
yf8k)t#uRg}:fl     {
aq.i%A!YM         printf("栈以为空!"); L9z.r"oM-h9U/Q
        return -1;
3euF5f0S k Q8R[     }g/|f4h1j
    e=*(S.top-1);^$u4e _N FD
    return 0; C*M q7T-O|
}d!J-Z1|{7@2j,Q e
g f!B-D,g&j m
int Push(Stack &S,SNode e) F av^`v.aTAb i6o
{-U h"Vea4Do
    if(S.top-S.base>=S.size)
8O M7m$w'D0};DT     { Y@\,L;lx#V
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));(Bl:r'I;D%_!x
        if(S.base==NULL) V,PbAv D%A?
        { x~+_-u&pc5s
            printf("动态分配内存失败!");/}#UG0gfG
            return -1;K%n5Eh%Z:gn
        }v0q(Q(iz`G
        S.top=S.base+S.size;
:dK{UT9@         S.size+=APPEND_SIZE;N8X,P ?{` s.E*W#G
    }[p|wy1g
    *S.top=e;"P0yu C;O:{
    S.top++;
}_ gR0{\     return 0;5o*`:j Im-iK
}
k-J y%r^| u+jsZ0fc
int Pop(Stack &S,SNode &e) ev'k0j\h7jgo
{+h~{ j3L'uD5B
    if(S.top==S.base)G?!g*Zc O.yO X S;HB
    {6L:P6v+r&RE~ [
        printf("栈为空!");
!jP6E7t `{0Y         return -1;V)O'a*URp` l,W7|^2S
    }8bd};?X$i"qD
    e=*(S.top-1);d2c$KF7I H
    S.top--;Qw!yAk?fa`mX
    return 0;
!M$\#?wxS2p }vJs6er*b&o

Q)kr+K i char get_precede(char s,char c)(p QQ d X|L*T
{
(jtq&fiGh     switch(s)%yn N:S_(gj&wRK
    {
N'j/W;z:l         case '+':                 
)u5VK#NJj L,wHv         case '-':
0y)P,W!X |              if(c=='+'||c=='-')
J]6Sx(i^0f)K+J                  return '>';
({5M{R&a X!t q              else if(c=='*'||c=='/')/KO&^m!y@?R(a
                 return '<';Yf#y8G5e
             else if(c=='(')
.byn9_lpvr5j L                  return '<';8]zr5O8}y
             else if(c==')')"~/M7t4V#zs.G2^
                 return '>';Y.?FLTk@9NV3y}
             else
d5S5F \Jb                  return '>';$za$Mp"@h&j"urQ*C
        case '*':(y\of.J
        case '/':
.~ FF3D0p!g.]"o              if(c=='+'||c=='-')
$\KMAn\                  return '>';Kon0S5IIQk
             else if(c=='*'||c=='/')
(vER eb                  return '>';
+r1Q{7|6S              else if(c=='(')
3U!M$t!w6MEQ                  return '<';P|Qm9a
             else if(c==')')
~@XQ_$O*^M                  return '>';
`x(ulDv5Ey              elsec7}H}m4[n&sr?
                 return '>';+P!}(I5O7d
        case '(':5J1h+d,eN/LV'nc
             if(c=='+'||c=='-')
7~}7b[bJ ysw{n                  return '<';
5iKA5[ H}6@ N              else if(c=='*'||c=='/')8Gt*w2MYn
                 return '<';
[5CU;Nl P              else if(c=='(')
7XA rQxN$n                  return '<';5G5XU9S;B/g(GJ
             else if(c==')')
"~7b9xTH| PYv]f u                  return '=';
R%^Y!z}8i{)v              else
sU:p+]Lb(P]                  return 'E';
X'o`1o;mA1ds         case ')':
p Ct8b[              if(c=='+'||c=='-')n k+d2kkS sN)vT\
                 return '>';rB|$s[
             else if(c=='*'||c=='/')
.| Nm$oz'k2fAd G*T                  return '>'; w_6J5L$e*G ZYxV
             else if(c=='(')5F'j_$RlDd
                 return 'E';"C5Z%i\Bm
             else if(c==')')
4C~*lv"s-B*Y                  return '>';"{hV7{Mkg
             elselF T4q4R MC
                 return '>';,d'?ZwH
        case '#':"`Hz4c j;g7Zg
             if(c=='+'||c=='-')
q+T'q/O7yPr                  return '<';
xh#_7zqYZ              else if(c=='*'||c=='/')i9p Ap6Gy
                 return '<';%tC rR'wJ
             else if(c=='('))W2m7sSP K
                 return '<';}?H,c!e)y/aY i{
             else if(c==')')!r*pj x$}B3cmm6_2j
                 return 'E';9l$i!O*L|6XWB$j3\
             else])W6MH {-P V
                 return '=';/~'YJ@ot-u$n
        default:+t v:Zrz+U WO
             break;+].h$PKCe*AFl
    }
d%T c$D#W&l&_     return 0;    @`P+PS I R
}
gC3iz m"L
E#tU HO3Z8T int isOpr(char c)
ir_.s&id {
`.S#Q7L A     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
@${'|5z L5l|         return 0;
DKzI g;a     else
BIE5z\wdG         return 1;
TJ*N|`3tW%gl,{ }.H7n ? l6cg0m

[%u~x E&{ float operate(float x, char opr, float y)
"xE2N4o_1gC:Xy&k {
X#p;m!h A%~5zE     float result;
-Qc)A4YGa     switch (opr)(x!YG$b/]r,{
    {
3\ W^gZS         case '+':
t9H:Nza;U6K.ZM              result = x + y;x*C6|x;C2`
             break;
Zs0J0Uxt}5wOb         case '-': &B2Xblu9eIT+[
             result = x - y;.D&ac s+E*E$f
             break; yd6}&_ f
        case '*': F?7JQ@#I*`5G s
             result = x * y;"dU7R^~Y.`.EP {
             break;"w.dGO+I F
        case '/': Y{J%kHD'k
             if (y == 0)
w.B,N8Q(k Wz7\H              {
%D(b wH4eD1qX                 printf("Divided by zero!\n");
a,a'e8l/jN)Sb Ne+ll                 return 0;
&xR.bK.Qx              }
9])kd)@4B VLwL              else
2q4Z9?M;V.R9w$n_              {
@XK%Oj,ON3V                  result = x / y;
/h A$?i0k7U                  break;
:U@w%g ?Ul              }0U,G1K FG6X l-g}
       default:
jD3G.sD%N@              printf("Bad Input.\n"); :t_d K$mpL _/r
             return 0;
`G@3~j(C)F2|     }
PA N{C'I;H     return result;
wjfm kV!}$P`8k }   
K/[rP,o/N9k
A"gO3sx:G8| float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/-z$u'N J(bx)pR+p c
{
] o Ks%Y3o3X*P`     Stack optr,opnd;
e!SW(~!m7e3b     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
%q,ukK$nJ.FE(V`     char c; sN1Z,s.P/O5Y
    char buf[16]; `4Eu~'`"@
    int i=0;
P k8iXX~SW n+~    
3Q+v{E Sy     InitStack(optr); /*用于寄存运算符*/.`*\v&i4T cC#^
    InitStack(opnd); /*用于寄存操作数和计算结果*/
!`l1R'\kle2_     memset(buf,0,sizeof(buf));.K/}VT/A c
    Ey:N:{H1N!a8M _
    printf("Enter your expression:");a6c(E"KGIjR T
        f|v2\,N X-qMR
    opr_in.ch='#';9tdi@9h[4P
    Push(optr,opr_in); /*'#'入栈*/'U| EzL\h Y
    GetTop(optr,opr_top);qsz:v)A-D[
    c=getchar();^r/Y W^?4w
    while(c!='='||opr_top.ch!='#')(O5WF4vP'fR
    {
Z o0dH.@zwv         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
C |N)Q\.qz         {XC&E Oxm^
            buf[i]=c;XlX fbJ
            i++;U7mm(P0\^ Z$eF
            c=getchar();
hGZ8CdV2?2[         }u@b8u"X0g.xz
        else /*是运算符*/,v7|H)tpZ\
        {+Y4?0hHap
            buf[i]='\0';Y6D8n,X~5zX rP
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/_ ]5\zX Pq,W
            {
(ylqt9g!cN*{                  opn_in.data=(float)atof(buf);
'v H[P,y Aj.KF                  Push(opnd,opn_in);Cc(@3E.hU2qi
                 printf("opnd入栈:[%f]\n",opn_in.data);
,}O7c:w(Fl zX h                  i=0;No*N+]@8vh*|xN
                 memset(buf,0,sizeof(buf));rVjj*`?+[%E
            }&Ta9[K;tT)~3D
            opr_in.ch=c;+zc [-a7F#k;i
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/u6DFfx%`#n7u
            {
h$TL-G"V&@6N                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Zz$O*z-S1W                      Push(optr,opr_in);e2j e zn(tf]6x
                     printf("optr入栈:[%c]\n",opr_in.ch);
BEij)z                      c=getchar();i7] z_"]ls
                     break;
|?HN&k&fX]                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
iq'\5t4fo0p                      Pop(optr,e);
{0W-`b6F                      printf("optr出栈:去掉括号\n");)u1l;wL a*jyK
                     c=getchar();@DIp f;H'V'O
                     break;
/i&H%k3^Ib7M                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
_|6v[B                      Pop(optr,opr_t);
C N1Iy.k"T w[6tN-s ^2R                      printf("optr出栈:[%c]\n",opr_t.ch);
DK${$s"x/nkTR'^                      if(Pop(opnd,b)<0)
M.CYb#B7c8H                      {PUrL6^7^ D
                         printf("Bad Input!\n");(zK-c&AM
                         fflush(stdin);
.q1zC|;|4A                          return -1;/na4Q]|(p`
                     }Q1_@.W-JBX
                     printf("opnd出栈:[%f]\n",b.data);
4{"M\5@-]C9h$]Q                      if(Pop(opnd,a)<0),]\iuqH0T$p
                     {A Ff*h0e nTw
                         printf("Bad Input!\n");
ru l-p#k.Of(x                          fflush(stdin);`G!d$[TEU5V
                         return -1;,p8L n,Om)P
                     }
1I`'}7C4A7q?u(p                      printf("opnd出栈:[%f]\n",a.data);
}3j/ox4A2g s                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/m/?3ql1y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
N'OT B'Jo!cw^                      printf("结果入栈:[%f]\n",opn_tmp.data);A"rr"v#P$T
                     break;.OB,u6O4|l W?z
            }q H6G fa2qa}
        }!}Y2f"HRo8|
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                4[l X-w,M g8d
    }9L f1X!^ n9\1U3Y
    GetTop(opnd,opn_tmp);F|R amI%As;x"q
    DestroyStack(optr);
l6@eEqf7TD;RgH     DestroyStack(opnd);/s gN2f:AI@
    return opn_tmp.data;1`jL3rM&N!}
}KT%m?:oTp5FEC
ODt3g$m/` ez
char *killzero(char *res,float result)
1gL6kT\ i SRZ/v {$XJ*[k"u
    int i;7UGzsbHc3?

pS/t7Wf [     sprintf(res,"%f",result);U:e G"K:j'^|Y
    i=(int)strlen(res)-1;
.~o4p0d-J%u7D^5y     while(i&&res[i]=='0'))i O2u5CVA'Tv}
    {
7[0em(_TBaktb8}H         res[i]='\0';
N"|(TW3TQ!N         i--;k[Xu'j5e3j}
    }0b thA L @#ceD3{
    if(res[i]=='.')+H!B c6k;g r(c7z
        res[i]='\0';
7vw"C%z%wE     return res;omK%aK5{~)Z3|{
}?,R-Z]'b&[J\ M

+Jj9f!VfuNqDV int main() aL%r RZ
{
bO'{vNe"@uD~     char ch;&S*iV!o)H\4C
    char res[64];
!_Tw,e JL3S     float result;
(ZP;{-q jm!p o     while(1)-Ks'L]!e9EzC9w
    {
z&Pu*Ad6@R I         result=compute(); go4mY7]+O
        printf("\nThe result is:%s\n",killzero(res,result));(omh6mH6je o
        printf("Do you want to continue(y/n)?:") ;`yO(w*F1p8]u!~c#Y
        ch=getch();
/{ Ht+G\xO O         putchar(ch);
)GVa6q-z3p9G'o         if(ch=='n'||ch=='N')
h%g:A{7@Rqp;c             break;
h2F'D;kS#ST         else
FH(O tu             system("cls");
m};\"c GKO)K9F.N#E     }
gRV1D`{     return 0;
,I.oLZ*h0C\ \7f0[ }[/i][/i][/i][/i][/i][/i]
4WB/_6Wy6z(c4k~
y1C{ b6z`5C [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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