捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6wT@_$`AQmH
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=Ln|&wAy#{
/**************表达式计算器************/ R8\/}&Sc5sENf
#include <stdio.h>]+?Z]}sr,ps8r
#include <stdlib.h>
m,M bO,v,q #include <string.h>'ub/BZ v
#include <conio.h>
,M`;k6Fz #include <malloc.h>]Z.x8pa*^}!f rC!a!l

j6I4rr chI_ #define STACK_SIZE 100vcBA| AO x
#define APPEND_SIZE 10{oNgj'^9j

9w(?@K;FM9Svd struct SNode{rJ2?sGx_6ho
    float data; /*存放操作数或者计算结果*/7z'WOe5[do
    char ch; /*存放运算符*/ e#}p N-n!s b W2E
};q(w M x~8f O]0ES
n$yS(I3n z*N
struct Stack{6VPo8X*Ue/B
    SNode *top;
zA@q5?F.^2f     SNode *base;
~;FJcsl#vE     int size;
3\ K _3d0g DU W} };
iY:Yv4~"NE
f6A&Y,i,Ib /*栈操作函数*/
p5|O ab int InitStack(Stack &S); /*创建栈*/+VM C|IW
int DestroyStack(Stack &S); /*销毁栈*/
-u4S7v_j int ClearStack(Stack &S); /*清空栈*/ z [0S7df
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
r!Nv}v T1|1EG8k-~ Bh int Push(Stack &S,SNode e); /*将结点e压入栈*/
"K,\~ r$m/KC*B O int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
]ZLr#V:n!v$d0Q ;n?m]&y5`GrZ.mf
/*表达式计算器相关函数*/ hd1T$s5ge#W
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
'w:?e y7pfhN4hS int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
V@`;AT'U{ O-U;?mI N float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
m[`!k8fCW.Vn$T_v float compute(); /*表达式结算器主函数*/2[y5\.[D%Ozh)i
char *killzero(float result); /*去掉结果后面的0*/ WP*c}.`4B

4ArW0u"Z l int InitStack(Stack &S)|Ja.g VE
{vhP|J9p+Q7jg3P#T
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));pF7{ Tz B2y&Oc6h
    if(S.base==NULL)Y1Yxy4X4a X
    {YQu8P-Y*KW`5o
        printf("动态分配内存失败!");KlNLX o
        return -1;
3EA}~b4D;}     }-V*g5I~Oa;iy:R
    S.top=S.base; c l"VEtQ
    S.size=STACK_SIZE;
%TAUM!_     return 0;;gYg!h2R$\
}
:W*l4Amvd Bu5L $L OP*oE
int DestroyStack(Stack &S)
GgTD:lU*^ {
GHBw5Gy'CwZ3r     free(S.base);NA@g1t
    return 0;
n8ZM|o pYB }
:S2`2oF v6@:i:Iyy$p;t L+WlB_?-hm
int ClearStack(Stack &S)
CM ^j)H/O${6} {
'ie0~@m5AJY     S.top=S.base;
{t*}!?+N9s&[ZT%f9u     return 0;#r0u0Z;s3Fp,}
}6LS!Mw-}

gyy6pw&C int GetTop(Stack S,SNode &e)tIR0?_KJ
{
ldkmW"fN     if(S.top==S.base)
B/l8{)|R i     {
XTIO"_-h3bVT         printf("栈以为空!");
;jlQ3AM         return -1;
mi+]p2`&j     }h4wu XF'B9yQ
    e=*(S.top-1);
uo'I?f&f     return 0;
;Z@ w0g$h_'` }
+h~l \gn
&X#`1Ff&y*p?1Er int Push(Stack &S,SNode e)
-h"L|3W8h&ex {
$s,W2T th4i%z     if(S.top-S.base>=S.size)
X^5`/M-{o{;y~     {
N I,t6YB0Q8p-us|]         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));zN(K^'E
        if(S.base==NULL)
4nSBn/byptJ         {7EvuP!l
            printf("动态分配内存失败!");
$E1{d P?$Q             return -1;
l&\ {`{         }2W2jj3ZZC0t!~
        S.top=S.base+S.size;
zJ-F'SKj&{         S.size+=APPEND_SIZE;
@ eO [J;d#w     }Oi8Go|:?
    *S.top=e;1g7o0cW(qk'H%c
    S.top++;q9?,D5FLX
    return 0;
(s geJ'I SZ%R } K&\usA5QB
v0_ q Z b5\!`7ri
int Pop(Stack &S,SNode &e)eEXk7C1l
{
Sm5M UoT;ac'Zf{0h8o     if(S.top==S.base)
)t!SbH/l     {kW/JA1X C'dZ-?
        printf("栈为空!");z+Z;y j:\:is
        return -1;
}i%{0\6W!O+L     }Cn.MOop:v:dqJ
    e=*(S.top-1);z;P6^W!rI
    S.top--;
,s,^ lY3Y5t9y]     return 0; G/bHXrbp:J2Z
}&rgx9Q,gD!H

0y3Va/@K)Z char get_precede(char s,char c)
VV V_ j3t'gs {
|(G_6S6Vlt     switch(s)G(@W:rif%W2u
    {b"xSE tC3}4B
        case '+':                 O*aL~LC#]q+I
        case '-': u'lN}AH
             if(c=='+'||c=='-')
&D y'Uy5R4i"?1S                  return '>';
)lA0IP.tkks'v              else if(c=='*'||c=='/')
b,^lGG,FO[$@#U                  return '<';
P7MS0m@v x8e,`              else if(c=='(')
!e,cA7J:n4c r                  return '<';
/W}-k1GY,Y0Wt&YT2g              else if(c==')')
1n?1M5RP:Bcn                  return '>';;y_Q*K E/l mm7W S&YZ
             else *g|xJ*{]
                 return '>';n8r.TG:Gi(}q$toy
        case '*':;K] ~5\+Ky~"wRt
        case '/':
:L;e-Z5{] SdR-E              if(c=='+'||c=='-')4SM|st${t!r'c
                 return '>';f6j cK+Idq1T0K
             else if(c=='*'||c=='/')x @1i7N j6ZI Jo(]
                 return '>';+I mY Y-m f3r-e*J
             else if(c=='(')5i@u!?9yBo
                 return '<';2R^L ~9D \fEKXb8w'{
             else if(c==')')
r W1k P4S.X                  return '>';M2eF ~Gk
             else t[}2VX+F F
                 return '>';W@u.`:OgxT
        case '(':
y6w[8{j D:Tw              if(c=='+'||c=='-')Eap#h8Twl
                 return '<';
1|L&~@F8GN              else if(c=='*'||c=='/')
$yxFE z                  return '<';S.Et9dlV
             else if(c=='(')
;@a3u+{"K&x                  return '<';
xiM)fG(S7iX%{(y"G5h              else if(c==')')!Ne*^AMhIr,Qy
                 return '=';U0f2G uA1_3t8t6v
             else
/o/s:F^1U                  return 'E'; mY D-J(A]"q#PR
        case ')':
*y?3ojg              if(c=='+'||c=='-')
-L&Q4BK1}kn7s%E0S                  return '>';2k![GX4`9~|t
             else if(c=='*'||c=='/')`G p.a|Ey
                 return '>';
S$I}/CBH'ulg              else if(c=='(')l gI)p9^
                 return 'E';PHR ^7DPx:c9B/Q
             else if(c==')')5~Fj2j9R\sY
                 return '>';
'r4Lq(sv UN7t"~? m              else
O4[qz6GH UBbn                  return '>';
,s!N1u7t_8e/c q*e F/X         case '#':7N'[Kk+a
             if(c=='+'||c=='-'),T\U ?A]-c
                 return '<';
$fYzV"r L              else if(c=='*'||c=='/')
LQ;gzr                  return '<';
pOG9kmt!~1`.[+YC              else if(c=='(')
t?(SNsGt                  return '<';
h1}g'i,iC+d              else if(c==')')t+h's:T$\&}YB^:K
                 return 'E';U e B @S([
             else
/Jf5Q ig5[ y n&o                  return '=';
cA0C\6^/k         default:
3oo^|"r R!J'ZX ?              break;r$A.c$[[7R5D
    }/Sw:?\ut _.K
    return 0;    ;\*u'H,t(Ev
}
x Q2?|{)e$M X9Z
4R-u-?$Q7E int isOpr(char c)%O0KSc&Y$X3| L;b
{
|PP0c;m3?P\e4T6H l[     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='):V L[ q"b _
        return 0;]D%U?y@ ]
    else 6MLQ? \HR
        return 1;"T|N(i8sEY-`\t8]
}}/jA2Q'^)Q
7B.qV0g8yU`hqA
float operate(float x, char opr, float y)oP:R)h gK0R1~\)m
{,x$oM"f@8BT7kb
    float result;
u c ~WHZ(L AAS     switch (opr)
.CJH3J`I5l     {L n.s2ofDp
        case '+': ^3K6_h$X5qpea
             result = x + y;
k8FX;a@ A+jF              break;
-R_/l&Rq6q\s*[ o         case '-':
S?,S%z/Dv/|1lh              result = x - y;
O;q8P#n1ydcX              break;Zd u@ hf@1Q,m
        case '*':
(HB![-L#qk8hQ z8o              result = x * y;
nw/v!X,j4g              break;
yR h[:C         case '/': :vK0` W&bd3j4Pmv
             if (y == 0)vH)?``i$G8Iz
             {
.U'Z5Y&}Sw'p3Q                 printf("Divided by zero!\n");
:W;Bi/]X'rs                 return 0;
_W O7o1Z              }+}c f*n.Q7X&Q&r
             else.rtU@e M/cb
             {BlF%R*P@1X ~
                 result = x / y;
:S,T"y7E0O c\                  break;
| X9MI |"vTiE              }
_\m6}6| CT\        default:
^'bo!R/uC'i9A              printf("Bad Input.\n");
F#H+^ R"rIL:Hs              return 0;
&Lk+FE2@v#i     }*U8}X)H$s/|u f
    return result;
U-CM;u9c^ M Q }    *^xx-q O!e

I#v$^GQ+o float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
R.Tz5@"HU a\e {0H TM K$a2Y`A
    Stack optr,opnd;
A-[&J"w DXG     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
|;Yl6s\7B jE_!H     char c;I?n5Tspe{@#U
    char buf[16];1S g `4a+n-N5|E\
    int i=0;D v mOI+DJD7S
    !i+J9[(d~2W
    InitStack(optr); /*用于寄存运算符*/v9Iy _.IG-M[*N
    InitStack(opnd); /*用于寄存操作数和计算结果*/
D)rX0c0VI.?}     memset(buf,0,sizeof(buf));,a+\}/DWC7MY}h
    -it(_w b@.~,bL
    printf("Enter your expression:");i4a@4e;S;O3{:t }mu@
        
8zs&L.k?Ud6] oui     opr_in.ch='#';
iH}'@Y8]CF&wO     Push(optr,opr_in); /*'#'入栈*/
\p6bb|(_RW1y     GetTop(optr,opr_top);y$^bI u$\K
    c=getchar();
#H"yKd^D W     while(c!='='||opr_top.ch!='#')
^9Roe O     {
aC1Sd)vv7~         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6Wu(e+tm aT.`         {h#\ff }d
            buf[i]=c;
R9Kv c%Y0t)[             i++;p-{y&R'D
            c=getchar();
)Br-R5e Z s         }RwCR&Q/z`
        else /*是运算符*/
G5a!?!k1d_$R_         {Pv#cSt7}m|q;Z
            buf[i]='\0';'l jU8cNMk/uN
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3l,z3X$|(}H             {i*w#E j*P%C
                 opn_in.data=(float)atof(buf);
P(JgZ.{v%T3Xs5[                  Push(opnd,opn_in);`^w2Z(@
                 printf("opnd入栈:[%f]\n",opn_in.data);
"W_(GnS+^6?2F                  i=0;B\/XI?
                 memset(buf,0,sizeof(buf));(kp&b4s E%[o0R\
            }m t R/Q.M/Gk
            opr_in.ch=c;9P/w+sq,R@!T Fk-Q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1~G(|/R[8C             {4YYRv$Q ]W
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
E.Q;w*t Ee                      Push(optr,opr_in);e3W#r#x#fBC:pS
                     printf("optr入栈:[%c]\n",opr_in.ch);t v$He)b^P5i
                     c=getchar();
O6Na*yd*} QaI                      break;
B9ChjlYX                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+D0elrVle[                      Pop(optr,e); I!}z+uo!P K(b}+ikU
                     printf("optr出栈:去掉括号\n");nJb3k JM
                     c=getchar();!L [BGK|
                     break;\x @;hf ^
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/"|Xp,kN {
                     Pop(optr,opr_t);;@0hR1v+C
                     printf("optr出栈:[%c]\n",opr_t.ch);D.T#P9_ kM8hz
                     if(Pop(opnd,b)<0)
d or'[2~R                      { KQUw_(S7W4q4p`
                         printf("Bad Input!\n");pc7_p0P8g!]Cx`D
                         fflush(stdin);
[JE(Q!M _]:x                          return -1;
Ql9tRLG8r                      }d6s1y%]}}:I&E(c0~
                     printf("opnd出栈:[%f]\n",b.data);.hI sam7G}
                     if(Pop(opnd,a)<0) t&sB3C ?s ZyPk"c
                     {r)c^&P,X6b
                         printf("Bad Input!\n");I4oiv&y nk
                         fflush(stdin);Uvuk$YwC
                         return -1;4F,E*c@]? Z!` P!W
                     }9z$lr/D_*Z
                     printf("opnd出栈:[%f]\n",a.data);
B?0a r%VjvN etv                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/&\$t zzz9Z|"k
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/X v?F.c.Q(f
                     printf("结果入栈:[%f]\n",opn_tmp.data);
+U1io,I;z+hs-{                      break;m;{i5m;~D
            }miS6sgB7w
        }
W^7O0}v9z#?         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                gk-?(Dya
    }#q6}5p"{hG"k
    GetTop(opnd,opn_tmp);qD9e1F.|LR1l
    DestroyStack(optr);
HsvRh'S$?S5^8K     DestroyStack(opnd);(Z9nDj|,p$R
    return opn_tmp.data;9t Tg3t\G.D+}
}
9Rr\p1nA W+`jTr sSVPk
char *killzero(char *res,float result)
0QJ!uT-iJ&V {
E1w^*L8}y%wb{     int i;N/]"?%V U%Q

j~)o'f+QX8NA9h#{     sprintf(res,"%f",result);"j"O6fV)q,|
    i=(int)strlen(res)-1;
7K#md?Hpl9@X     while(i&&res[i]=='0')^,A cx5W R/Fu V)}
    {(bYb*](H8?t
        res[i]='\0';2s6Mn+D*@3M,r
        i--;)iIj8k E M[i
    }
q;n-Fn ]0L:N%q W     if(res[i]=='.')
T[4f Te,}/s5[         res[i]='\0';kEN/\o ~2K x
    return res; J^2C enx([Jv
}J&jQ;})WA!`

W+q5s Mj*v!uAX]3UH int main()
J3D f8kYjx {
/p+FNY }Kx     char ch;
{}2Ywhc"r(T w     char res[64];
&Kt9?[J D |p     float result;*]VF.H;X9x[qz#s
    while(1)(h5O:m%v7Zz`?
    {
qb `/f{(g6A}"]         result=compute();
(jZ.{4kUN/{:ihGW         printf("\nThe result is:%s\n",killzero(res,result));&L6dW.c*G/PD
        printf("Do you want to continue(y/n)?:") ;9Hdm_k:@ pp
        ch=getch();9lB0wRd~Q {
        putchar(ch);
:H6h9b yA!wr+V         if(ch=='n'||ch=='N')
{?l[9_.ar             break;
k8K P)m v n|6MQ         else
5E-u*jV5Zku             system("cls"); [:t[Ur#m$pi.Q? t
    }
ph0gVcYR.?+H'@     return 0;s8d$Ib!i%OM!L
}[/i][/i][/i][/i][/i][/i]
5[*h0^ tO@YQ U
~;S7a%k(})RS t [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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