捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
g+XC[4M7]Q)t 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
W:h;Y,c%g\4D!n /**************表达式计算器************/*u j*RhHBs
#include <stdio.h>{a;up7j
#include <stdlib.h>
({ ls)o5PweJx/o+I #include <string.h>
g%u2Dsp}d0@,c #include <conio.h>
6W/F\|wA)L #include <malloc.h>
@(X+KK3c5c9g Bn_8]Os)K
#define STACK_SIZE 100
B#} upc:ur,n #define APPEND_SIZE 10
%u%fR!{%UN1F zM
jK,cre#o5B struct SNode{J\4{@.LD&^r
    float data; /*存放操作数或者计算结果*/.D$q$tG3s _)l%sG@t(\ t
    char ch; /*存放运算符*/
~?O,W#N)a[ };"SO5E%gAwj0@;}
faP)Q3c+FVwv
struct Stack{(x4S/IHL8}
    SNode *top;
\6gx4@p)Jh!G     SNode *base;3L3HMhU$Y;bN
    int size;Y*t:F)z E OW%[-nu
};
VFh7cJ;n:i .vg` Y [vY
/*栈操作函数*/1unFXii1Ek
int InitStack(Stack &S); /*创建栈*/
+sG9Wt3X,Q/[ P1k int DestroyStack(Stack &S); /*销毁栈*/
8T3X/N(SEm&CL4I2M int ClearStack(Stack &S); /*清空栈*/:W/e2T Tb1O(Ove
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
]sCQ:mQ\6LP int Push(Stack &S,SNode e); /*将结点e压入栈*/
0?+{cR ~&b$V int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
_3]8N&O8io[7B _ w v;DKj1n
/*表达式计算器相关函数*/
/sb.Q~YY char get_precede(char s,char c); /*判断运算符s和c的优先级*/
k p(~!P |9O6Is int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8KO,\~T_.T float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6V-t,C(j#Y*l'n$m:\7O
float compute(); /*表达式结算器主函数*/
epl,OR y9}/BB char *killzero(float result); /*去掉结果后面的0*/
%h c'y}v/R4Y
IOu1xY.n)m int InitStack(Stack &S)xx,GTF4rn1pZ
{
U6[ l6i$L|^|     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
N&er-D |TfW}     if(S.base==NULL)WaJ]IlIQ
    {
?7qy$wf5lx y!u         printf("动态分配内存失败!");Nu)v,NA;N
        return -1;{7KT0ged9~T9c
    }(|I"a-j'P6ESDq
    S.top=S.base; RI;nU k0x&_l
    S.size=STACK_SIZE;
4EE/K'h0T7qw9`     return 0;
5vvRv!ly:oB },[3Ld!U?#L"GH(i
R@r0d0z&l
int DestroyStack(Stack &S)
b vWI3Ep.E | k {
zH!q)Z B$L'k)t     free(S.base);Q?4f7a p8j
    return 0;
jXt,f N3| }
&Wx Y qdoUo O D[9J3Pr^joY"Z'C]
int ClearStack(Stack &S)v;O$sW;tZ/w$b
{
rYp0K maq8~:y%\     S.top=S.base;,` d!D4Y-yX
    return 0;*GgAh6a'O;`
}
\$mN(`A\h:S~x'D d(AnWe-_ l K u
int GetTop(Stack S,SNode &e)cfb}-h
{
!cMf0M3}HX"VH     if(S.top==S.base)3_4w]O:b0H'p.U-NuE
    {b(P"~4uS `
        printf("栈以为空!");
8D(['x@RV         return -1;
,I e(Y%EI)w     }
GMf,V/`hG0b     e=*(S.top-1);
8L?tG&E     return 0;
"TK c A0g3Ao }bBzGw#t"kn

9mlD-M&CG*} int Push(Stack &S,SNode e)%@D)ui3h+Mp
{A"I M)q2J5[8S@CA.Me
    if(S.top-S.base>=S.size)
`6HM(b5C'f6s$u3\K     {
5_t |;|-~ v         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
$EIuT-vv         if(S.base==NULL)8^]QS`b5C H
        {
r7oE3C6S)K`sh             printf("动态分配内存失败!");Xza%k f I"q
            return -1;8s9h4Z!rGjdy*lC
        }
w_'g+^v         S.top=S.base+S.size;x-Gx5l2Z1kTq y _
        S.size+=APPEND_SIZE;"`d P1C,U8`]P C
    }
%yf8k H8cX1X;dI/S`c-e     *S.top=e;
GIm7?%W.c#{4G     S.top++;
_VeN!e     return 0;%bNnDR7@b(R
}
}.a#s G/Vw vW)S.du.h1V*J r
int Pop(Stack &S,SNode &e)
/`vh1Xpu9S/H6N {^yjA*I
    if(S.top==S.base)
c&r3g~J \U(s)I     { {6p n,l9x
        printf("栈为空!");0P*~'W7I_R&^ Dz
        return -1;
c tCo ]2t     } @!C!^PY#I4K
    e=*(S.top-1);
u,UY&rNyO     S.top--;
3_-WPX6o'P)J9p     return 0;
f?+y0J$\2Kb }
1R!@!T%~5et a)pU
'm\/[%U { L{"VV char get_precede(char s,char c) B(d9~h2Z n
{
2}8Z;q"q^gb [,|`     switch(s)ykydGB
    {/d9U^6v3S8k-I2}^)_ y
        case '+':                 
1zH,PL4~'L         case '-':^T$K1Z6Q E1wb
             if(c=='+'||c=='-')"r'_.F9h9X/[aM
                 return '>';
+E%G I$s`v?              else if(c=='*'||c=='/')3n6u IV#D8o+c*_s
                 return '<';!d-N)@'GE;K
             else if(c=='(')
6M }c5QF9V                  return '<';N3]o+YZ*?*p6w2d
             else if(c==')')4l{};B t
                 return '>';
F"n_ \hk P              else
C_"y.Kkp(p0Z exs                  return '>';
s5WL0XJ a1\o         case '*':
,n(a6k;|1M)b         case '/': VFRig
             if(c=='+'||c=='-')
9j U|7N`0Z_                  return '>';
*D.g~ zQS}_^$hKu              else if(c=='*'||c=='/')
l:lyt/~#AV                  return '>';
0[3l`2e ]9x              else if(c=='(')
fW"d*Q yV"}                  return '<';2I ]@`Om ^|
             else if(c==')')
S)I+v5y&vq1i                  return '>';t*{3Q Y eE5c1Jw B
             else
+{];u fF                  return '>';q&^YW.\hG
        case '(':
*r9Z:P-T4p{)] a              if(c=='+'||c=='-')#|Q`(E|2NM(Ww
                 return '<';
#c+T\E;M"x*H              else if(c=='*'||c=='/') i4zmYQ2POm
                 return '<';
0FS4\+S7x)F y              else if(c=='(')
"]"Q?-G%a^                  return '<'; @(w{ EL~0Z-a
             else if(c==')')
7F0tx%e:xz                  return '=';
Tx {5J1C(z8X              else stQ/O,B%t3m
                 return 'E';IP1i1o,}W%?l
        case ')':6J)y%{#KdS;gn vzl3K
             if(c=='+'||c=='-')
`#[ hu m                  return '>';$~$LL~!Gm ZB(I
             else if(c=='*'||c=='/')q#ZEd+A]e
                 return '>';
LEE:i"Z5MS              else if(c=='(')
n*Z0D4[;XK;[                  return 'E';;gx.X|y"DE.P;}
             else if(c==')')
'W#@J7T-\R*B+u'l                  return '>'; Do8v7pS%?B [S#\k
             else
uB:}/~Q{                  return '>';ap L:NkfJ;M2B
        case '#':1iaza)c
             if(c=='+'||c=='-')i`)f2b4{;Qv
                 return '<';+z(YdDJ {N6r-z }{b
             else if(c=='*'||c=='/')F3ba"[x+t
                 return '<';
4rIG jc t k)^XF w              else if(c=='(')!`!F~!B$T3p]
                 return '<';
hq;N@n              else if(c==')') oLC+Pj7jtJ
                 return 'E';
7`I7^G#|              else
k Wp%Y'\]&@-RiK                  return '=';
E8_0w-b"SVJ         default:RG%_xM'Lg].h!a~
             break;
1JR,{z_2[${     } B/HM MP!Qg
    return 0;    U4s"~5L'f8K
}X1Y%HT#k6G-{7t
0l"zo(Nx[ d0_
int isOpr(char c).I\ u"Y'b
{xJ^ T,cI
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1N le(|3?bQ)Lp
        return 0;
S7W/ky N     else
mP,j ^ m/]Y1e;J:M         return 1; M2Up/Q-R"D \
}
N y/a.H@4y:T@
.Z$l&\xP)w%P float operate(float x, char opr, float y)
["p.^*[Gc {Dzc{}#rBfp
    float result;9{2Dt$_~
    switch (opr)
D$K+D6H)DF9I"x     {,L d1z i#Q&Q\ x
        case '+': 0Xb-QA:f)c DQW`3G
             result = x + y;
CuDWBLS/]&W              break;
xFIE,m&@)?         case '-':
_ ll b'dy~ @              result = x - y;5V%M3RJ}a$K{(i
             break;
7KQGX z         case '*': l"jN PF2E
             result = x * y;
)Zv,YA/d&PU              break;
(H[)i xQ`.M         case '/': ]5@w6oM+^_ZZ
             if (y == 0)e?4[%GGo
             {ZOK[ Fr'j
                printf("Divided by zero!\n");I9r%n?0p+X/D
                return 0;
JA d#kcO]X              }'lLqMU4X@\*B;{
             else
5y&D!p%o S5v;V m              {
1_gC%oJtb:GRX                  result = x / y;ooH'U9oZ1Ck
                 break;6e#Z4AX~7tO
             }
X6i J@i,as H6M        default:
R)P^t-sfd)s              printf("Bad Input.\n"); l$A-g'K] l/C{2K
             return 0;
Ox+Za YY     }v d t].Y O/c0Nh8vA)P
    return result;
'k6])s|H%nn }   
{ePFU O&R.D
&_aQs#A@c float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
I"t/Xr5D6ZJ4D {
CG%OEQ"tBYa1s     Stack optr,opnd;
0MRpm&RGD1Gii     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
G b#vDcY     char c;]3hw)cL|8h
    char buf[16];
-Lt;Q V7i*q     int i=0;] B k!TCl
   
S W1d2u}HD;j     InitStack(optr); /*用于寄存运算符*/
w&I5d9q.vji     InitStack(opnd); /*用于寄存操作数和计算结果*/
K6k6b sX     memset(buf,0,sizeof(buf));
@\}/W]    
Zh+IP-O{W:s WZnB y3H     printf("Enter your expression:");
C;wsM`&xprc J0k!c         l(ck!x!K fiD
    opr_in.ch='#';9[r,B:O2rV/f^
    Push(optr,opr_in); /*'#'入栈*/6?/X)N}Qv
    GetTop(optr,opr_top);
#byn!R3Z8^2r:S k~+_0N     c=getchar();J7\6LEG S*A%D
    while(c!='='||opr_top.ch!='#')
pu_N ].s\ E     {@eM;y(SFKC
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5M%k4t']${mi
        {
nI5|-t)hYJ             buf[i]=c;
r myC8s1l2G9Eh             i++;,aX%w*Lmb8V L'B*Vh
            c=getchar();
zWLD,hgG:kA:T         }4@'~/p[K[_8i
        else /*是运算符*/
3Cj:]w ?)^)RvcN(zV         {
,pm D$N*RT ]             buf[i]='\0';
RPa-g6P'D             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
:l&`4JYu-I_u H1e             { mF"tDV\^6T
                 opn_in.data=(float)atof(buf);
7DLl C({5Gt                  Push(opnd,opn_in);c#w9rj4](Gn
                 printf("opnd入栈:[%f]\n",opn_in.data);b!OJt$U)?
                 i=0;(gN](B w.EG;Q!b
                 memset(buf,0,sizeof(buf));
"G8Dc:}UP"E M,w FL             }
3P.MuvI*fR.{tw             opr_in.ch=c;Mv!x:X3E9SDW-s
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
[] `0H4^*m x             {
9i)b%e;}0lS]q                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ C/N N]%DL
                     Push(optr,opr_in);|(R-Y9S]
                     printf("optr入栈:[%c]\n",opr_in.ch);?3w'i8g T0Nl[Qn
                     c=getchar();#L$rN!?,r#dQ
                     break;4j5C7\+?'m.X,Y5l
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/W6E!I*nz]
                     Pop(optr,e);
;f;B l&Z2F O9i                      printf("optr出栈:去掉括号\n");4VMJ\*q
                     c=getchar();
] x\ __8m#Uw                      break;
X*yZ*i5J1o                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
`h6S#e4| lo&_$A                      Pop(optr,opr_t); u;B JC4jVm/A-q"P
                     printf("optr出栈:[%c]\n",opr_t.ch);D4C0P"u:^j7S
                     if(Pop(opnd,b)<0)#]#c9zH:W W$V0qQ t
                     {
X aF| ["b                          printf("Bad Input!\n");-t`J6R&L;u W_
                         fflush(stdin);;Hy1v2\oIt
                         return -1;
e Y?#|+\2@~q&v3A                      }
)L Z6a XTyp                      printf("opnd出栈:[%f]\n",b.data);
ek_i F.Lm                      if(Pop(opnd,a)<0)
q-|]e$GiH                      {K0`}1Go$lTxo
                         printf("Bad Input!\n");
Z)V[K b.o                          fflush(stdin);h1]&W,f%Awn'F
                         return -1;#y F b}Ay'uQGY?
                     } z `G1?x\v
                     printf("opnd出栈:[%f]\n",a.data);c H'aB`%T!x
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
W5M j~2uI)@7|2\ u6k                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
bs Ui8O%M2~                      printf("结果入栈:[%f]\n",opn_tmp.data);
tK)_h6e*Q6?3P                      break;,GZ2dSb-ua
            }"?$^}5_v V T
        }w3c}B9jWp1[,w5\
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
+t#u9K)t;]hxw     } \h#ASW)t ul
    GetTop(opnd,opn_tmp);
+JWJ3Gi ]Z'd0y     DestroyStack(optr);X(r1m8fWkl
    DestroyStack(opnd);
$d"E,~@]V-Nv O     return opn_tmp.data;
K.mX'F'@7g }
Rx LGj ~
@-^c(a L[ char *killzero(char *res,float result)
_L$xO1Fr6I {u3W#n1X Sr8g p;st
    int i;a'bV'jn0ZxK:nW

)u R$c;U9n2kGk}     sprintf(res,"%f",result);I)BU7UJ.i y_&{I:bg
    i=(int)strlen(res)-1;VK1n!ff*vs V
    while(i&&res[i]=='0') r"M e C)D9G2E wP)XF-b
    {
$aA2D h,`8Rj         res[i]='\0';HM7ZQ;W._
        i--;
P"^Si;tIV&g8@U     }f@J*X rlp
    if(res[i]=='.')}s|A&oA i*n
        res[i]='\0'; L1QeN$yPk3t
    return res;
2x?']h5oF }3n0TW cz{"Hs3e9a

`Yu9o0C int main()}*f"BL4D0{E
{Z)P9_ s^&d\K%k
    char ch;
#e x3O1tuq;G6_DMY     char res[64];
Vh1q,|}9\Ymj R     float result;
1n9m pi"~QB     while(1)
J'k/J/p3~/H1q,iC     {
0r ] Ti^0l~         result=compute();)f%G8|"y@J{V
        printf("\nThe result is:%s\n",killzero(res,result));U;j*i]:hP3L;d
        printf("Do you want to continue(y/n)?:") ;
)Y6Y X \P K}         ch=getch();
k`f hB.m H         putchar(ch);
m/bQOZx         if(ch=='n'||ch=='N')
#?|'w(] W I             break;p#l3G.iV
        else
pL~$R6Y:^,vC^             system("cls");I C!_,@*D w!P8j%N
    }
9XOUXpJ     return 0;
RW;] wm#x~+h$C }[/i][/i][/i][/i][/i][/i]
7y3GeP{cu `7r ?`;d!cx,f5j|
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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