捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8rmn%Eb~$~a+U"s 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
D S\r0|5KX"y /**************表达式计算器************/
)x6mrvLD @ #include <stdio.h>
7WL0?aNz'{$y z@ ?V1W #include <stdlib.h>D(PcC'{#W
#include <string.h>
0Q-nW?_Qg #include <conio.h>
"@3gy9k1F #include <malloc.h>
a.\-Ce(F$V B*d`p*xC+wR R4k
#define STACK_SIZE 100 X2T:Z2@,mV
#define APPEND_SIZE 10
wW&Rc`B:|E
1a*{vOZceX&L x struct SNode{
&x6T,iG3AA.p |     float data; /*存放操作数或者计算结果*/R E |F!i"H4R
    char ch; /*存放运算符*/
`1T%}C*f:p3U e };
&HZM+i#lPd
m2~cpo$e$}uh struct Stack{
"A u;M%K'u&XDP4G+Q.\     SNode *top;u)oF%rNH ? A9a
    SNode *base;|)X K"zF5S
    int size;(O1\1v#sdRJ\t6G W
};?'?*u_ nBq
2T&j2C&Sy
/*栈操作函数*/
0R1A@.x+kj int InitStack(Stack &S); /*创建栈*/
Y[6Y/[)R~ Q int DestroyStack(Stack &S); /*销毁栈*/+zU _.Jd@DBq5Av
int ClearStack(Stack &S); /*清空栈*/%n`f6|$|
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+G+M Y6x'oEL/x;E H int Push(Stack &S,SNode e); /*将结点e压入栈*/
(xl|AT!Z7{2F int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
'p+I(]-z)` x#H3m 3S?7`OOT"aik\
/*表达式计算器相关函数*/o;vO%E*|H#`(~)d4Z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3aU+Xm%zDO8| int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
K3x6sTn j float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
@%Q4OruY?@ float compute(); /*表达式结算器主函数*/1zg].M%G)F
char *killzero(float result); /*去掉结果后面的0*/ X3^x&AZh(e:E m0g

/} L;S,p-_ {7Ap int InitStack(Stack &S)8pv]E yto
{GkL.]Z4d
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));%X/@{N-zU,mKA
    if(S.base==NULL);aP"MZ:d/~ }(c
    {9m7Qc&L)b!M!h5rH
        printf("动态分配内存失败!");
d`!O l QS%c$M#Q         return -1;
o/ip4@F6r~-x     }
6g(f M;sB     S.top=S.base;
I~Gr'J I     S.size=STACK_SIZE;
LUpn&}0G8A Es     return 0;
H tsQp:{t0F }3W:b;E!r3ppK:E

V;J"TSi int DestroyStack(Stack &S)HEXws"?&uD
{
0V$}eO l!`.ul2g5h     free(S.base);
_`4w'S8h     return 0;h9~@m!z;lT
}
;h;q1LcC u I\i \-JO5P]
int ClearStack(Stack &S) ] zi9j~)cZ1?m
{{o/A Z9`\(x
    S.top=S.base;r0c%VYPQ
    return 0;
Q dy} n Q }.BhJE;a6^/t$t5j
J7Q7V${!{
int GetTop(Stack S,SNode &e)
6`$d l0RWG {
;F0F3S7d8sy P`     if(S.top==S.base)
.V%T0@ux#{0CP     {
H'oqbWR/rd         printf("栈以为空!");
Ud3HY:f#^g#`         return -1;
;h?@'k:OE8|     }
F7[HLG*@ l-\     e=*(S.top-1);
(@P!x&k$|$R7N     return 0;}(o2RoQt!b'X9H-fcM
}"b$O't;T mw*x

Imz$wT"vh.Q0s)W int Push(Stack &S,SNode e)
&x;jB-@_9Hd)M {H;k,DA#k)M&W
    if(S.top-S.base>=S.size)4a9UnkuEf\ }
    {+v5G2}{e)K h?X4T7H
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
"l"}~3z4o6c"v         if(S.base==NULL)
W MA`1D|L         {
6j'q-t8sB3e             printf("动态分配内存失败!");3EQM7h Yq)Q;Z
            return -1;(k$dFA?7qk2x*u
        }
:f2b n9lkrK         S.top=S.base+S.size;
y4jel%mZ         S.size+=APPEND_SIZE;
#B#AD} S     }{X ]I2NTd$b~R4{Pp5f
    *S.top=e;
B|'U,XoU.\}&P     S.top++;J!A$?U8tl \
    return 0;
6e,J9M6dJ(m a }
$\B;g,X&x@0_0A IYY |6V
int Pop(Stack &S,SNode &e)2uf Q2`-~+E
{
T5I(PN1YW$L     if(S.top==S.base)es(~S;^"U_iN/m
    {n0gk/J[ a jV
        printf("栈为空!");cx5q%\/[B O
        return -1;S(ul)On'Q
    }
6BF'fa tgw |^1CB     e=*(S.top-1);
7r2PCi:Dv_6p     S.top--;O/{? h6p!NB/C4w
    return 0;x+Y4L]vx0^
}#y!p.R$[ ||Nd,o
3S1P KNy;A
char get_precede(char s,char c)(w#oF[W({W/yaW9\'e
{
R @ G,G)sJ ^ t     switch(s)
X/bg-u:J&Y?"F     {6n F%n#Z2pe"\2ZkU
        case '+':                 CW-R"@(K{3UN&|
        case '-':
{)[(F9K&MxZ              if(c=='+'||c=='-')%i"m3i%@H'u*M[4d|
                 return '>';
8A5M@*q N{C%t              else if(c=='*'||c=='/')
0aJp y[7\                  return '<';d-t5p?&iB5H7Y#y%f K
             else if(c=='(')
$] p:fnb pE0d                  return '<';.gg(|!N1h-x;p
             else if(c==')')"d t8L |)@
                 return '>';
Y-rZV(H              else U^}G3Pk n
                 return '>';1t vO-B!x%zZW
        case '*':
iDM5fk5]`#qx-uQ$a"z         case '/':
M s!a/f%gM vd.c              if(c=='+'||c=='-')
]-tZ.Z:b:S                  return '>';
i@|L Ow+g h\              else if(c=='*'||c=='/')
9?2zpQ+w\Z                  return '>';
L S?k].j$x)@              else if(c=='(')"ujj@7R&wuLK
                 return '<';q~9r K;Rra N;O _
             else if(c==')')
h{ b,V(L]                  return '>';
6K|#RD\ hab.u2q              else
(bt`:W"KjT[ U                  return '>';#y(U.oAg'h` cJ
        case '(':
5A7iG[%e]v(ikw/H              if(c=='+'||c=='-')O ~9FX,s G"[ M
                 return '<';
/G&~b5Wh2q^ D du[              else if(c=='*'||c=='/')
!hd&nz8BjM                  return '<';i9BD9c0j T(TI
             else if(c=='(')
3ZXTe P b#e"?                  return '<';
wTB!f6_Ybn n              else if(c==')')"]zx x {;q.i2hn;c?
                 return '=';
!C.cS!~1Wf!y              elsezg6{9HC pLL
                 return 'E';
nrJ9B.Y#C         case ')':
(E(E9A Gm%{,QD)|E              if(c=='+'||c=='-')
y'i'w3m T%{S-y                  return '>';
v^e.]z;N)[3`P              else if(c=='*'||c=='/')|)XjZ-h
                 return '>';)f"` k]h
             else if(c=='(') f0J [/S&?Y
                 return 'E';+GSpd|/D
             else if(c==')')4yp+x6p?T:U
                 return '>';v&`!g&h rWc e*b
             else+GyN/oL(@Q
                 return '>';
Gl1K(F8^8S8U}         case '#':([?/zT!Q Kpy{
             if(c=='+'||c=='-');c4zi7D6\
                 return '<';
}ZR$Z_E              else if(c=='*'||c=='/')7I5K!rTP VF
                 return '<';
6r5Q mj!K ^{9[9i1i              else if(c=='(')Z K5eMqPO
                 return '<';.T3fq8{I4c
             else if(c==')')roT:M kcZ3C
                 return 'E';
:{%s*LQ!HG)oT6K              else
? FZ)`/BE5mI                  return '=';
WZ c v)z         default:
"|0o4M])Ic              break;
:{+N@Q+o#R x X     }
`lg&mvG     return 0;    -x8tLG,@N*x I
}
.GB i-W0\9Y@A
&u{?4ITFa int isOpr(char c)
S;w7C0B9V7[A1x-b {
(U"]$H/MBM.w"L!y     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
;o j-i(L%n?.@         return 0;
L{-ef$_l     else
b#q1_4OnW#S+Q Ag         return 1; x!b7uT{a
}
$z4tc8H7L&o z
x9|b%}B"~w3P&rhm float operate(float x, char opr, float y)@3g4D[p9C5mR
{
6g-[D&`??     float result;0i7q;LK)U!g3M6K&u0E$p
    switch (opr)
;Jsh5Uf~+wc     {
TQa)N8a8a         case '+':
4x;k4S"GyNp+} {l              result = x + y;
r;VB(xb3s1L              break;
&a%L3O?w1L-T br c         case '-': $^!N"sMGDk4d},[
             result = x - y;
rE$o7|xJ              break;7?0D5Xx#KX \$NHl
        case '*':
D qQkgW              result = x * y;E!B+qAS2c,y r%M
             break; T9b/T9L?JkT
        case '/': [ C r3j y6C(k:WH
             if (y == 0)6wM?rni Z"\:{o
             {
@5w1AKR b`` @4ka                 printf("Divided by zero!\n"); d}*m&t |_H
                return 0;&e O/I9lI S7Pf7t
             }
3Z'J.h/N1] |*hR              elseC9rCgf
             {
c Y4u2b2vHQ*|                  result = x / y;
`BvVp_                  break;
3P){;p2E@              }6p^ ?Y Hc6| K
       default:
5HE.oP.G M3h              printf("Bad Input.\n"); @ SW.@ Vt,{.MbTW
             return 0;%CWGW5_G3V%RG
    }
9Bo1^MI2j     return result;
2k5C#zo_wmg D um }   
C4B6W\hg&hb9\x {
iDd0t Sk_5xo float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
v8Y#{[0u {o4iukh
    Stack optr,opnd;$x z'MpRo ]\,W~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
.X3Gd(G8W"k{!^     char c;'EV*{6F^/A
    char buf[16];
r a_`F5?O     int i=0;
.mzdfM c!Bd     T `%HQ2Yd X%d
    InitStack(optr); /*用于寄存运算符*/
O a J7]5M_,A5n3M N     InitStack(opnd); /*用于寄存操作数和计算结果*/$d| D2C(n|4J+u
    memset(buf,0,sizeof(buf));
\3Pt)k%e'Ig9zn     (jHg#M3i*@v6V
    printf("Enter your expression:");v,[lT&I:Mm
        
8i"@mn,D W9m     opr_in.ch='#';
}A U`%~ ^#kR W     Push(optr,opr_in); /*'#'入栈*/
`tosM&R$i     GetTop(optr,opr_top);g%zc%u(j2BU3X
    c=getchar();y1a-? Q;Or4UG D
    while(c!='='||opr_top.ch!='#')9H \E4YMh
    { O(^5j!r3gF1}z
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1GmkL+[ w~s6G         {
5s\;K |/j#v!C)c             buf[i]=c;
)`I:w!Tj)YM7W             i++;
W3Uh'WW"t             c=getchar();Tf.]4E|%q
        }MS%jm9y y2z"V
        else /*是运算符*/n N){ V.['p u
        {qu#Vwsv
            buf[i]='\0';
f v Z1{6h,GC9g             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/:U#| U3V$Z ^vBz/Aut
            {-~OAYT'H^3X
                 opn_in.data=(float)atof(buf);H\~TO;D7D O{'w
                 Push(opnd,opn_in);
,n7jP-fBaJ q"W[                  printf("opnd入栈:[%f]\n",opn_in.data);
ZY9Y/s$h3b!G c |                  i=0;
"\h:Yx\!Kp5un                  memset(buf,0,sizeof(buf));
^)a?rh+R%|Saw             }
x.DJv$d             opr_in.ch=c;mV ~/A)|v%P0i&Pr
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
:ML `6T:\,zN/H9U             {
MN JC:OYKX:D?M                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
9Oq1?0FDF6y u                      Push(optr,opr_in);
#q OY/jc-{t#s#L/oX                      printf("optr入栈:[%c]\n",opr_in.ch);~V3eD1j*{
                     c=getchar();
8[9s&mP7ntN[,X                      break;q{ I Mi7`'C E
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
;T;r+G5^;O6f                      Pop(optr,e);
2J+wc2?#e;^                      printf("optr出栈:去掉括号\n");
;nK8p&Fl1s(u q                      c=getchar();
#WU$G,Y,eS                      break;_u^ K?L
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/,vp!Ca0dC\m
                     Pop(optr,opr_t);v*@3Hu?3@1_
                     printf("optr出栈:[%c]\n",opr_t.ch);
7].M mO$V)YHE&|+a                      if(Pop(opnd,b)<0)F#tw$_r(T3oB
                     {
2r[,iY_)B7``                          printf("Bad Input!\n");
.[zO7iC                          fflush(stdin);
7n[XEf4M9eM,~                          return -1;0j(e-Z!` If$i|y,@
                     }.k#db J.h,h$S
                     printf("opnd出栈:[%f]\n",b.data);
W;ZLgFIEi Q                      if(Pop(opnd,a)<0)
5QK$f0J9A&D                      {
t-sD!hOjM~_                          printf("Bad Input!\n"); o `g&B+Dt%E6s(O0v
                         fflush(stdin);B:N GF'N
                         return -1;
;mBrUD6w`                      }
c)zc.P Z2P?+~'I)]9g                      printf("opnd出栈:[%f]\n",a.data);
!Rv1z8Y9ZbSm                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/O v&F!w$` Qc
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
SI ^EPO                      printf("结果入栈:[%f]\n",opn_tmp.data);|v3i4f~o
                     break;{q1T+~c8bKVG/o
            }
/V&MKQtj8x q         }
?G5x0P1R8?+Q].p         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                0G:?%_2JKp6{
    }
0[+hl ir8FWL     GetTop(opnd,opn_tmp);
3q9_5x@7{ ^     DestroyStack(optr);RW4R_ov(V
    DestroyStack(opnd);)E"@ K;EC)e0o[
    return opn_tmp.data;
5X `]f&aT } B&HdU4[T[?^

7e ef8Kq.F char *killzero(char *res,float result))i(S2rvpu9mAf
{
'\c/QNq zu3m3y     int i;
A y*X[VU
0va x;F~6wHj.YT     sprintf(res,"%f",result);^1R`!X0|8R6|:u
    i=(int)strlen(res)-1;?n%qc9J!ccV2b
    while(i&&res[i]=='0')
bD7}%` ^*l[y     { fO9yD[
        res[i]='\0';^ wh:`-L
        i--;_8`4},Y-B A ?
    }1K0K G6z#N,{Aa*M,s
    if(res[i]=='.')
8S0|&Bq:k7O!e(m         res[i]='\0';
Y2f&x8X8BO,y8N     return res;p t9~o2N&wyy\
}-cYPQ*Z.y&P*_
9l$cTAqy g E |
int main()R-U S3p!~/~m_
{*N:rm*U9V v%zb9s
    char ch;
$`k}p @'Q)V|S     char res[64];
j/@D*oS.[ z9lx     float result;'o r+Q6xp y*})N*z
    while(1)
dpY'}(kS^!Q._     {
!tqV'W o6bj         result=compute();:_ M N v;s0` Q
        printf("\nThe result is:%s\n",killzero(res,result));
3IR.H)QC,L-[!^^o         printf("Do you want to continue(y/n)?:") ;"QG ?'cEe2s|
        ch=getch();&u u^A3O?
        putchar(ch);GFzNf,D
        if(ch=='n'||ch=='N'),w*p8{3}4W?a;n u
            break;
n O\ `#kSJK         else7e6t {-]J![2t X
            system("cls");
6],r&?X.{     }[,T3Qt"G!u
    return 0;vk~1bj
}[/i][/i][/i][/i][/i][/i]
#p&TB b*OYy*Y %hTiA {x9L4x4Z
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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