捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
a,J;|2} r!fc6m 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
;q;Zgto/r~ /**************表达式计算器************/#V6\` D@e*q
#include <stdio.h>
2ai?6eK7G #include <stdlib.h>
|jDm*_eY.o L #include <string.h>
i a:Y-P)]n } #include <conio.h>Sl[N r~
#include <malloc.h>+h.Ss"k mP

U,KJ|` #define STACK_SIZE 100
3Ur+jDI #define APPEND_SIZE 10
j9b"c1ek$_"[.D Jpg#_7~
struct SNode{8P^{(}l2Z
    float data; /*存放操作数或者计算结果*/3qYqw9^8urR
    char ch; /*存放运算符*/
x,@n ^%B:pzJ };
/bIY],vs7b#S6e 2b~B]I}Gz,O9K-L
struct Stack{
Ny nW2_W9Y4bkk6K+u:e     SNode *top;
.^/g Qy%h P+tF     SNode *base;
!~S!B(`{,^ h1n     int size;
/|{!MGSwA N#K };u5}uU/o!r V8xQ

q y4aA_3k /*栈操作函数*/
#Kd:a+~g5y int InitStack(Stack &S); /*创建栈*/&A'|1?3J er,Jt
int DestroyStack(Stack &S); /*销毁栈*/"c4| e O[e U
int ClearStack(Stack &S); /*清空栈*/
rdC$X ]9u1D]QiK int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/V4@ g@9Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
$pfU;zT[P$R int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/R2@ V{!J'SC

E:y_)l]W /*表达式计算器相关函数*/
Sc6kWLWdSmTn char get_precede(char s,char c); /*判断运算符s和c的优先级*/@(`;r,K0hcvj
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/d\4Ggb
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$v5TAD _ OK float compute(); /*表达式结算器主函数*/
l1{fm1G$]4P4z o @ char *killzero(float result); /*去掉结果后面的0*/ q3u q5@/obn&q
-Z^ ^*R Y6\i
int InitStack(Stack &S)5P w2r(QaLX
{
H3Qu:l.A:q6IQjn     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));!U^4CY1BC
    if(S.base==NULL)
(s o4i RG     {$p;~/K;J H1T|R |
        printf("动态分配内存失败!");
%P/lRUx         return -1;1oX`2Jj
    }
*H(a)a%mZ1hx D     S.top=S.base;
:i6^@,{g%VI"N AHK     S.size=STACK_SIZE;7hF {V\
    return 0;#`zn#}(^?T
}
0Qb6G7[#YO B*JIZ Q [&HN.v;nXbjt R#I
int DestroyStack(Stack &S)
$[F&?z.~0?B {
K"^0|Su0T     free(S.base);pe bq3t9t I"W4_
    return 0;2[7@'T(^ E3Bl#t
}#U)yM:q?8c.|2vdI9NS
zU'R'B{8b$~
int ClearStack(Stack &S)8J"{"U*v9q5F"`
{uT~TA f&P4} G
    S.top=S.base;
1]!rH"u!^9aZ1x     return 0;
:jQ~:q nPp }
4^ D$LI3[hQ/q6Y .T)Ml s a3Omb&_
int GetTop(Stack S,SNode &e)Ay1uU2|8e1yxN'_Z
{
7kc l]b w8@!G     if(S.top==S.base) xSN(Mt
    {
Bl3xXuw,_ ]+x         printf("栈以为空!");1iW%ND$V
        return -1;X9RDNnS
    }5C@ F B8r-d&bL
    e=*(S.top-1);\L&L;H#OE4j8g
    return 0;
k4\6A^&po }SP6it6a[l
I9`||2O%V
int Push(Stack &S,SNode e)
.z4N!Da&r`4fK {$A"i;AJ1Wcw
    if(S.top-S.base>=S.size)
?!E}}O1M4mn4i     {
OWx vP}         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));J9[l!e-oAh9U
        if(S.base==NULL)
ut UowuGG         {
(U M6O6CKn7H~m             printf("动态分配内存失败!");[pB!F!gUC#s5F+tMt
            return -1;[%d*yS8iS8S6K
        }8o"{R*Kq7{
        S.top=S.base+S.size;?,`Jf;S ^ g
        S.size+=APPEND_SIZE;
+C6u;W?3Z1V@u     }JREg!|:s/k.n
    *S.top=e;EG-f-Y&X.b9u
    S.top++; |2i3],u'DVHh
    return 0; Z/S"Y;I+l[PC9p
}EcM&}G!`K

5O LT@4[G e int Pop(Stack &S,SNode &e)
y7l4yF:Q {^*t0MUZS
    if(S.top==S.base)
)F pWc `XL     {7Zt(br |-a6OQ
        printf("栈为空!");%w8z&tp1iG~2O4C
        return -1;
nL8C-~I     }t8KgN%~N
    e=*(S.top-1);#n4t"CL\i0N,WY-Y
    S.top--;S${ ovw)eQ
    return 0;
3J8J)J-AED }
9`'z R Ah-o exo'\1X]
:vN.e.d:D char get_precede(char s,char c)
7J3I'MetR {
9SP6[ k3GE     switch(s)b#ZWeD%Oj
    {pZA.PE1b%o
        case '+':                 
o WW'Q"J6qp8LTb         case '-':
9GvHsW2D              if(c=='+'||c=='-')s4S h,JM&z0r.V3_
                 return '>';
'`;Q!_p*y0w              else if(c=='*'||c=='/')-mC1oTAq kt q?}
                 return '<';
G9O? oV(sd              else if(c=='(')
t B eO3wN-J:seT                  return '<';
KnH4o)P+n)M1}              else if(c==')')
~1[v0Uw^5_q                  return '>';
u,scB @'MO              else v4hi"?6u [I6l o
                 return '>';:k:e8W)Kj#X$u
        case '*': @ kI%`B j {`,?]f
        case '/':wQ%_n.e
             if(c=='+'||c=='-')t"Bw _ FhG
                 return '>';
:h-lH2Z[T4p8Y              else if(c=='*'||c=='/')
7a0F/P)f3EW                  return '>';
o J9RL/| ?(i              else if(c=='(')
6_'x5E1M eH'Q                  return '<';
7u nkOwy8}qZ|f              else if(c==')') f!k&x'pq
                 return '>';j/j ]BR6`*G
             else p:b!|e0J$n @$h
                 return '>';
M"yvr.F         case '(':
^J4I9i%s5`.f9g&?&V              if(c=='+'||c=='-')
lP$a]%l7oU                  return '<';A a QTG_Q$IDb K
             else if(c=='*'||c=='/'),vT"R kx4Y2v
                 return '<';.E+}~(k F2xO/S5j#a
             else if(c=='(')
"~.E2T5U _1HuM                  return '<';4Z3sH](UM2CY
             else if(c==')')
E|*Z(y Nu                  return '=';dl9C3dJp
             else d!@(KeS%~1h8nUc~ _
                 return 'E';2\ p0u}xXQz2t
        case ')':9b)qr,Nh8o.E8[
             if(c=='+'||c=='-')'[X|)gpB nA5?!q
                 return '>';C\%Zl5S6c'YR0N p
             else if(c=='*'||c=='/');]nn.q'Re
                 return '>';
:n(u:u(R#Bh              else if(c=='(')pe%\ cs pa
                 return 'E';1V/{Lerr
             else if(c==')')/K8GKR6w5{O
                 return '>';s3`+_5NDo9\ W7oY.y
             elsel"WHJ V!H
                 return '>';"Ci%Ij1z-{7jm
        case '#':,m y_~%~}4N,g
             if(c=='+'||c=='-')AQ\:T*z!w/^
                 return '<';
8B c M m IZ~ j              else if(c=='*'||c=='/')/{cd)E8]8h
                 return '<';
*[\Mz$XAr(K              else if(c=='(')
0X0uv0b q F                  return '<';
@ @p1p `B ]7B              else if(c==')')
hs.r*Ow:?{M)eM(b"T                  return 'E';n sJ7n4G_ C;N v*`M:~
             elseR2|u+GIG)Y&j(rPL
                 return '='; ~u/J7u5M\*xa0|;[
        default:
7ip*@or @ h+cvl              break;GS_1p.m8hxI
    }
-|:diQ%pj+cej     return 0;   
6oH*X(h8{&_ D(@ u };T CGi(nJeSQ
kB.{n`
int isOpr(char c)zkU}-s:X
{;^"|6\#w1RuJr h}+B
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
W/M Z$fl\ i         return 0;
x R4O}.MYR3SS     else
|)c4AfGTl&J h*h         return 1;
,{QoXX6k }
5e ]q5C7J
U l(rwr float operate(float x, char opr, float y)W*ZeG f1FA'H2k
{
6eXye6_ ? r'|yP Q     float result;
L#aY'| `r~]     switch (opr)c,N/n0QGi:B M[BR
    {
u'bk2f:k-X8X         case '+':
9o4m gd#EKG4DC              result = x + y;
"s v[sj*Tp)U              break;
_h)R#my {~#O         case '-':
)Gn%_-n+q(bW              result = x - y;}xVqf
             break; l vZ{9H1m X%w:m\
        case '*':
4l/`s8oJ a^              result = x * y;'vY+A rb/s{5O
             break;
L$u*y:^3af9u iO         case '/':
MMv*fId              if (y == 0)f"V ?hM:E0M
             {$x^$C;zT!c/T2E'V
                printf("Divided by zero!\n");$j)eR8H~[
                return 0;5F7Q^]x? oc
             }*Y3w&S:F r g
             else
2`6yy w~ P`              {
h5f(U9JE$j                  result = x / y;
$?-ID5K%X                  break;WoaPo @+g4?;kT(m
             }*v ? Z"QvN!|'L
       default:
kH(P/Q9E;RT4^S              printf("Bad Input.\n");
I$DeFN+x7| T              return 0;
*|{;J9n0k_wFq     }"rOk,bwP\
    return result;
M8B;a/Z3_2} }   
/X)I o$]0G:H3K!`
SpJy)t,[-traqv float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
VR4|lbP {`S2x9z.{.D+fk'hS
    Stack optr,opnd; O(wC g,_3@
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
r:@GP\#M3o     char c;^BA qA5U*Qo8Q{y
    char buf[16];
*q(a k0v~@\     int i=0;3{ GdZb4?
    sv~-_+~C&nb@e
    InitStack(optr); /*用于寄存运算符*/
rg"J6O1o5PE t     InitStack(opnd); /*用于寄存操作数和计算结果*/
_A6]*MvF     memset(buf,0,sizeof(buf));
$bh:sP6C[Y&z/\7e     5~-sO%cfe
    printf("Enter your expression:");
2a&R/N2k5} eVuZ9N4}         
#D1JxLS0D     opr_in.ch='#'; BdU En#ow
    Push(optr,opr_in); /*'#'入栈*/F2AQ2?CT qG
    GetTop(optr,opr_top);
(V;b&{ y%g;U     c=getchar();`-_!w~'G-lG \
    while(c!='='||opr_top.ch!='#')+vo"eJ L iwV
    {bj O]vJrKn
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/p@(J/TL2Mdm
        {-Lif_u
            buf[i]=c;'^U.Kk/{ ^K
            i++;0uQ+z`.{"w
            c=getchar();
Y'eL6kW(p         }"Lu5z ^)G(YZ'Gu
        else /*是运算符*/
(tRC(m+Jm         {
:j5o Q|n5o/f             buf[i]='\0';.FHi(^{Z0Ls
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8U:L(UM"fUk2k
            {
/ch,\$v'K3g$w{!\e b                  opn_in.data=(float)atof(buf);
d-bWU)H A B,Rm+w                  Push(opnd,opn_in);tlH/E9T%]_
                 printf("opnd入栈:[%f]\n",opn_in.data);J!UH/mMnz/c
                 i=0;5?K*E?yQ["?'~&[
                 memset(buf,0,sizeof(buf));
T!c2z'j3Y(c UL|0X+N             }
p K"_c7b9UxF             opr_in.ch=c;1UE gE#Cbk
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7SJ3`6E!|v
            {
*P\8eHw5naV`                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
d0F-|jY ?#g                      Push(optr,opr_in);
n:i/q3[c [l$id_5I                      printf("optr入栈:[%c]\n",opr_in.ch);
7H*C8Wm MWjD                      c=getchar();
!H ~3DWg(g                      break;
U8m)m,Z.X-V                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
(jB&\\0P+{ Hi                      Pop(optr,e);-d(a#a {c M
                     printf("optr出栈:去掉括号\n");j l-vqDx+h{A%N
                     c=getchar();
N,pLj(tN                      break;
1k:gn1og0nk                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/|:]nNT(VJ
                     Pop(optr,opr_t);
SX:b'|F0V                      printf("optr出栈:[%c]\n",opr_t.ch);
8[L]"B5Bq3^                      if(Pop(opnd,b)<0)
@"A3l#IG/t                      {
L'?Q2v6cj{*sIs                          printf("Bad Input!\n");
o8\3l%IUSK                          fflush(stdin);4g-{:]q&|l
                         return -1;
q5GFw.f0G(P"z                      }z+~ y3qP)Ab q
                     printf("opnd出栈:[%f]\n",b.data);J4Li9p$N7X0P.t
                     if(Pop(opnd,a)<0) v yHAYq7m
                     { xT?)Pb
                         printf("Bad Input!\n");{z pFh DW
                         fflush(stdin);,D!B.]kXM
                         return -1;6A*n*nx7e
                     }
r$\o)Ary|~                      printf("opnd出栈:[%f]\n",a.data);!t9J&LU+eES'_
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9yL5Z0R2N1y0z                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/YEY/Z&G3`2wi
                     printf("结果入栈:[%f]\n",opn_tmp.data);'J'Cnr3z
                     break;
.J^F*L'H3u             }
y^R's r.\VBn         }
8c:R#J z%H?%a7j         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
Z$`2lU\R     }
o%B8h$I9w4uEOE+A     GetTop(opnd,opn_tmp);1y3Kk]}-JN t&Q1M8P
    DestroyStack(optr);BFNY7M)P zhX)Rn2s
    DestroyStack(opnd);/V4pi)O'wt]
    return opn_tmp.data;f2\9B0W MF
}
0O.h:OXE|dp
+b ~$KQQQ/x char *killzero(char *res,float result)
] t2^pY&k H? {;`'m-NMGbH#SZ
    int i;
1Vzbe"`$d1pw `*\)[{/P~!C hO!X
    sprintf(res,"%f",result);oE%QHbc6o
    i=(int)strlen(res)-1;
&HL0ph/In)s9`4p/s     while(i&&res[i]=='0')
"G6VD^-cmv&z     {
&V$KWAzgb         res[i]='\0';
"J(^)jQ|W/n#tV         i--;
T a#TY!v,jP u     }
rp H:QLL3R     if(res[i]=='.')y@._ j7J!i
        res[i]='\0';h7mr9}!}4R|
    return res;
:Vh'c5b5V'q } \ |H;a y Z1V/I
XX.a^qzl9l/]T
int main()%Q6`-X3ic&Y
{m*cM,_&G.I
    char ch;rrgY cCg3T
    char res[64];:v?"n_c{C
    float result;eP.zh zMdz2N
    while(1)
N?]5r Y8Dt}     {
$h.qm)br0EC         result=compute();
Kg6kL5?C,m3b         printf("\nThe result is:%s\n",killzero(res,result));J,TT.u+[
        printf("Do you want to continue(y/n)?:") ;-Q;XPjT
        ch=getch();N |u SN5eSw'qQ
        putchar(ch); k,i.G~9u+o&Xi\
        if(ch=='n'||ch=='N')
l&sHr sT/_             break; Ap Q ttp)D
        else0G l%y a9Nt`'H
            system("cls");:{Z X5?ix~c&D
    } vo4F9D8|qA
    return 0;
^w?UXdqg[ }[/i][/i][/i][/i][/i][/i]0~7G'fqI(PFy[

a~ y e6t [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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