捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
-p'`3S-I@3p3QY ] 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
K#Zo5y#X /**************表达式计算器************/
Y,f8o[q:~ #include <stdio.h>
j;^a%WQ4k.B,w7Zg #include <stdlib.h>
(KNg2tj%n #include <string.h>-R G3e7Wh6] Y
#include <conio.h>
%JQC-x+P #include <malloc.h>
Jm U ieqv_ {Y3KE&Tv3ML|
#define STACK_SIZE 100}X4a{IjB
#define APPEND_SIZE 10
4}%q:G1A[Ft#A1bS/Q%Z
Q{;x5wcS5n struct SNode{"{R^4y1cY)a ?
    float data; /*存放操作数或者计算结果*/
Uj D1Q-[ R*SL     char ch; /*存放运算符*/6^/I0p?CUz0qb
};
1a9kAJj#K8MdDM0o _5I!qEu [4u
struct Stack{
'Kd9E2?/|X     SNode *top;;Y(zw;xX`S
    SNode *base;P;V {!e(n$WY-U Vy
    int size;7J!o k _6u,y_l
};(o[o jj.g"d/Z
n,SQQ4E S,k
/*栈操作函数*/qW gp7`4Wq1u
int InitStack(Stack &S); /*创建栈*/8Ma#l!\]%{3Qg[R
int DestroyStack(Stack &S); /*销毁栈*/
&D%l.N%Zh&x1] int ClearStack(Stack &S); /*清空栈*/
tr?*v_J,g int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ v;Spu-DO\6I$p ^ Z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
)B7F-Me2@8b int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/a/Oc[:G8i(?
,O4w+@JX"~
/*表达式计算器相关函数*/
qk,H`E_7F ]:]q char get_precede(char s,char c); /*判断运算符s和c的优先级*/
(gwRI {_y4r int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2C.waX4Y,gT3o float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/]D)]1K'J}
float compute(); /*表达式结算器主函数*/
\9i8Yy/dy char *killzero(float result); /*去掉结果后面的0*/ E-bU'P5c woV;Ty }

l8ey[DL/i9x#mH5v&l int InitStack(Stack &S)
YDA(Q&u:qMJ {
`E&pF t1r/UkJZ     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));{-_*u j}4EBD3G
    if(S.base==NULL)1|s;qY3PD E
    {
5KoZ+W2L8H         printf("动态分配内存失败!");
R.e h ](j         return -1;
4Q4g5{0H+D&E K9j)f9H     }9Z:a.q~!IS
    S.top=S.base;
)H T#el M `,|     S.size=STACK_SIZE;i8R T fCh4ZQL9g
    return 0;
#pijH`-N9a }
zE/GF(Yc
7V y7X J8Ov!u int DestroyStack(Stack &S){K0k2E$cH E
{ D9H*C0H] G]
    free(S.base);
J'S-d A2^2RC     return 0; UD*Se;x2e
}UW NVq

#w.xm4fjJ6J dn)c int ClearStack(Stack &S)
}K5Jny^[\ H@;yu P {
{ ht2V2cn$vc     S.top=S.base;
4C-On)zI_0Ci     return 0;h8D$x6EOXY?$a] H
}$n uqU4Z.i }'R
.rq4nQ!Go2S
int GetTop(Stack S,SNode &e)s\?q&db
{5q.C0L:mf5`a
    if(S.top==S.base)
1L\ q%c"~p js     {
B8N/|%qA;slf         printf("栈以为空!");!s}/p] _{;R
        return -1;
l ISp xOx0^q |     }
p"mr)ay(X"y     e=*(S.top-1);V"AC"l-h{(A+U
    return 0;'u:B"R y[mKQ1vM
}UuV U*B&?6G0W
%M)F)|'j4~5y3]
int Push(Stack &S,SNode e)5c9E1Y5q.t*^6T'VN
{hJ.|G Po`K']
    if(S.top-S.base>=S.size)
-lE_2E {{%Z4x"lz     {AT E9F$~j
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
2nYX.P0J%W         if(S.base==NULL)
I!~}B$mt|+?6~         { aZ*M3FrB-N(r(g
            printf("动态分配内存失败!");
1w2e5\o$Jm             return -1;cr |N~/NO2R9k]
        }
bRv J\#xo3A^ H3s         S.top=S.base+S.size;
o"|2T(L f'Y         S.size+=APPEND_SIZE;
*hJy`]g|3W"iR     }%fg5L&? f s)['co.x
    *S.top=e;
(Gn,m*N7Pb"Tl S9S+]     S.top++;/xq'}0F Q7G
    return 0;
3J+h"b"@|F~.p }
Ea@C0^3s 8F \(GL,jH+D&CK
int Pop(Stack &S,SNode &e)
K$w]y5TBO4}U {D}.AhO%N#J
    if(S.top==S.base)DS,j3H} T/bD({
    {
d&wQ7a/O$d] J @y         printf("栈为空!");6c'ml6sS*e U
        return -1;-IC-^c,m
    }7grReO F.shal
    e=*(S.top-1);&RZ'X rT
    S.top--;
(B1c}4dO&Mc     return 0;
#J,hr:Ew"_ r(y }\K)Dc(I4kHN)S

~ e/S6e ` C char get_precede(char s,char c)
-{ L+Ui"k*Bo2K&dMWh {Y B@AX0n%r
    switch(s)
Y,}w ^$`     {
&C/Xf7_{.j%YM7b         case '+':                 z5r@i'in2`.N
        case '-':
a/}D7A_&tX              if(c=='+'||c=='-') CG/??/zn
                 return '>';
,Z&g Jh4~)[/A              else if(c=='*'||c=='/')/U `KiT
                 return '<';:ue d.E@Uk(w"^
             else if(c=='(')
G iE|SEDr                  return '<';GsvrtF1M+p
             else if(c==')')KG8xI$k-?/BwV
                 return '>';
Z'u n |a R              else
Eo jUVP1Y                  return '>';
E||W8t9Q         case '*':co$U~'v\!OKU
        case '/':}#W%Lrx8T,N'y
             if(c=='+'||c=='-')#nD1a4GRXA6Q
                 return '>';g)X TyA+E
             else if(c=='*'||c=='/')
&~c E3Xz+F1[o8MU                  return '>';~@ q!t c,GH0V
             else if(c=='(')x-bR8g7h9_
                 return '<';}s#on%pQ
             else if(c==')')
%fvZ$N8x                  return '>';8q,k,@,fU
             else
uZl8?h                  return '>';D+t3s4k f yI0T[
        case '(':
C'A:jY5f1W F              if(c=='+'||c=='-')+kV)l,r7VRG(](j
                 return '<';#I1@ qdNe
             else if(c=='*'||c=='/')
C5aF:Jo*V/~/C:DK                  return '<';
/p~`y[8px;i'I              else if(c=='(')!R}0c[?
                 return '<';(e[m2d:Lf'i;V3]{
             else if(c==')')
2HD9Y3?*W9Tb2c"@y                  return '=';DS"^?5gY7`UvZ
             else
m(E;Vh/Amh*FZ$r                  return 'E';
3r,wM0n&f.I$S|7d         case ')':
7fpoV]rJ              if(c=='+'||c=='-')
F%[;Nhi0l$D8~hx                  return '>';.i KZotVa5\0Y
             else if(c=='*'||c=='/') t&u0gQ6B J}
                 return '>';
4G5~4f/J2O3B&o4F)B              else if(c=='(')
J6lp'h&a'w`                  return 'E';
4a-_#~%JF&wv*?              else if(c==')')
Tx/G`,|"q4c                  return '>';
{*B5nE1tN5w              elseg c E-KD!I(HU
                 return '>';
0D+_^ g:K"eX!~o         case '#':
8D3QK?$s9|              if(c=='+'||c=='-')
n#e!S+Lh4Q                  return '<';/h!G7I p'm1DM3b
             else if(c=='*'||c=='/')
&ZpO-@9l ]                  return '<';LBop0I ~L
             else if(c=='(')
@(Wy6_?-r                  return '<';9HqZ7iJP
             else if(c==')');iz{ f4l3jl8Yc
                 return 'E';
D.mn;TF              elset | x Lv h/CJK T
                 return '=';vGS DO2Gl'^
        default:
}yL-J_@h7l1Y              break;
r*_?-[ x%k     }
.{"a(_c?)c2Zfj5FFp     return 0;   
o#iK,S(@/^ }-_)]q_^1T"R4i,\l!_
F M^y)} v/DM7h
int isOpr(char c)$P T%U.h9~&M0Zu
{
*Zkc1ULQv/m9Lo4x     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
f/z%zp/O*J         return 0;;om(Lq!qY#P4x {h
    else _g6b0Z+w,Q
        return 1;
|j/D0KHl}T }
N,t!|2i HLj q#t 0Ovr,k,MI I-^,c ?]
float operate(float x, char opr, float y)+e8u+TBV u d3~$@-zX_
{
,N2t{V$~*G2\*p     float result; r*q(Q h*xO@[
    switch (opr)oO)^*ff,i
    {xirf'nnl
        case '+':
5{(p_*sT#A              result = x + y;
{:ME5L0] CL c              break;
bRl-f'[IIm         case '-': m(`p T*leLW z
             result = x - y; g Kck*e?
             break;
Y&[~4G xe/c7w }         case '*':
6G2~`jt-N              result = x * y;
H4kwl \pq'x              break;G%D9J-r!p~c|fS
        case '/':
tE ^ G)POTs%o              if (y == 0)7qoJ_)l&U
             {bCJ7KL5f
                printf("Divided by zero!\n");
6c B*k s0Qn6G}                 return 0;
5nA8?/qq,x              }
8Qb&MnEu1G              elseh-Z5^1f f yA
             {9J#["s(@'s
                 result = x / y;
-rVg.ej0U l-]~                  break;
C h9wtn9|w$]2n"I              }
(S(f Zg+wx(t        default: E;q^ t qO w!W
             printf("Bad Input.\n");
@ Rp-{ lX3p%A G0?              return 0;%X){dWZ([J-J
    }8X@r\} h0BJ
    return result;
nIJ7z(M)d*Pr }    rC/O P*?1z5g-Y_3f

c$T&m%{b9J float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/&O.{H&t tzx
{
6Qt,yD X HB!K     Stack optr,opnd;@W$\1YMZ$tq5t{
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
AFpAM U wT     char c;
&E:gIF bi"U     char buf[16];
![Q:V+e\H     int i=0;
q O+CLK     iD)B:Z*vqQ
    InitStack(optr); /*用于寄存运算符*/p o YsHP&b
    InitStack(opnd); /*用于寄存操作数和计算结果*/w.f,~dU6~*p
    memset(buf,0,sizeof(buf));
S:feHy8]'o x+W'EV     'z(n Ap6R9IDm
    printf("Enter your expression:");
,I8QE.{EL"V5c6uD         ,W8v_a1r-E_L1e-cF
    opr_in.ch='#';4b3L0~ _9Mw
    Push(optr,opr_in); /*'#'入栈*/5G2m9]A6yz
    GetTop(optr,opr_top);
j*NV"[ P ~.N|w$f5A     c=getchar(); |)V?h H/`
    while(c!='='||opr_top.ch!='#')
Qz8k[@ Q8jt/G8Y D7l     {
5@F!X8k+UT]5e@         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
!M/S6~k]]3\3on-D         {v8Lg#n$Q__4z j
            buf[i]=c;
&Z1?&_XY:A             i++;
0~ flm5j+WF             c=getchar();I:W$Py t8w~ Z
        }
C5ki)@+|#w VG6BW         else /*是运算符*/p:ZNN4KEu#p
        {
:{"Ux*T6o q8J!@1W             buf[i]='\0';c WGt5mi O3v
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
\EoO ^9qeJ:Q             {IzY c/f#\ba0pn
                 opn_in.data=(float)atof(buf);
1X;[ @m/b0L\                  Push(opnd,opn_in);
-e\:bSvkC                  printf("opnd入栈:[%f]\n",opn_in.data);
v*`-d/P*C5P8YH                  i=0;+FQ:qh QZ.}"`
                 memset(buf,0,sizeof(buf));
R2fe3i}!^"v             }l v-dvG9G1{
            opr_in.ch=c;$W Y7f)U:rHg"U3L
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/~H)]W `RR/J7s
            {.Z b.IrC5^D`&j
                case '<': /*优先级小于栈顶结点,则运算符入栈*/1ZUr&{)p4h'n
                     Push(optr,opr_in);
TP(lm'w                      printf("optr入栈:[%c]\n",opr_in.ch);$R0T#ry(s(NS pV
                     c=getchar();
f}E,m.Y'P2lCiTL                      break;:G nJ%c3zV/K%Z!{
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/p?xT9p G-|                      Pop(optr,e);5w;UH(] {\`
                     printf("optr出栈:去掉括号\n");$~\:{-j'| Hj/A
                     c=getchar();;u/j(_4JmPR
                     break;o&PB4MQ&rI
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
-c$P!N1A}'zBw                      Pop(optr,opr_t);IM!x sN8X
                     printf("optr出栈:[%c]\n",opr_t.ch);
d5|'r.{S*xL.`                      if(Pop(opnd,b)<0)} K R1m{s ~G/u@
                     {
)cG8on\2Y8X                          printf("Bad Input!\n");
-V!wf.P r aF                          fflush(stdin); ~!l+\-y2y)pY
                         return -1;
,YO6f@^IQAI8e                      }
SF]s;r"T*~u;m$_                      printf("opnd出栈:[%f]\n",b.data);
)}+y8Sg!v~#R                      if(Pop(opnd,a)<0)
]l Xl R                      {
8z#_P^*k3b9sR2C                          printf("Bad Input!\n");'IWo^4USF/X
                         fflush(stdin);
8yD q"az4d3m3^ m?                          return -1;2fMA2T%k0t.O b
                     }
O\3_4M`                      printf("opnd出栈:[%f]\n",a.data);S"`C6?!iF)C9V
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/lZ/F MjcN
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
gq5FWAmI$J)e#l                      printf("结果入栈:[%f]\n",opn_tmp.data);#R4_j1T/Gs8]u)K$]
                     break; O-l3~5`"F
            }7kmAz-x"Gh O-q`i
        }
@W3X5VRq!O         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                @)@u)@@x6H&|8b4D
    }Ts ek2O`
    GetTop(opnd,opn_tmp);*P(WOv+M x%s*Y
    DestroyStack(optr);
3y9~ l b'y7Q;np     DestroyStack(opnd);,KL c pW:b8y
    return opn_tmp.data;
[/U4W:dX HW }.] JG~`7yu b
r[;nX]1[c!y6u
char *killzero(char *res,float result)
G H4K+q$ihP {(zL sQ{'a Po
    int i;
6^FY4n3J@L9m]0wu
,|n"L3^d"_     sprintf(res,"%f",result);
\d2Xr"H#M_v6|+d@ O     i=(int)strlen(res)-1;
4Ot].Ll h     while(i&&res[i]=='0')$unV K:H
    {9] _|I q9|
        res[i]='\0';
iv3p:K6O:s}         i--;
+mZ2['I/S6~-Q!_(n     }
)VZ"g0c(|     if(res[i]=='.')
)l?|u"Mx-f5P         res[i]='\0';r$y|EA"T5\
    return res; j&tfO'~ d vf
}O2[~(~B+c}

3RG[,Z1a} int main()_O_CGJ+D%}9\ ^
{
{)h:N"cFbB~     char ch;#x:` ]6J(B\$rGC5U
    char res[64];xv"n`\,u4T
    float result; K]0pyy*V4Zl
    while(1)\8}0w9mA6\ Y z p
    {
V1p*]3X/Vr         result=compute();
b1Y/z*u3V^6`         printf("\nThe result is:%s\n",killzero(res,result));Z{GZzikq
        printf("Do you want to continue(y/n)?:") ;
e[Mb[4x%RM         ch=getch();,?F7g+wsg"yQ
        putchar(ch);;W3D_,{rv @
        if(ch=='n'||ch=='N')s9]:B,o.}4b'^7o
            break;9u9hBA-N+w+Q"eF5]/L9f
        else1d3pG} n^"Y+c
            system("cls");
k!IxH'n1t3k;`T     }:~ cnp h:v
    return 0;
9NPg*A9x9g }[/i][/i][/i][/i][/i][/i]4D\ b mm.U?u k

a%U8y,f!dn,_*Q [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.