捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2]VD2n:P 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=!K"Cb#B?7|
/**************表达式计算器************/
)N#t L[#uR$U4OU #include <stdio.h>LN[;s7b7j
#include <stdlib.h>0K O\av
#include <string.h>
AC rX@'D;P%^.m #include <conio.h>/uI%]S6J$O2[TD q
#include <malloc.h> v([7y9m(r A5@^y5@_
v,E mL gU
#define STACK_SIZE 100y4E+q$Mu/~
#define APPEND_SIZE 10
1sSM Z3Sz(w f |
:`{ B;X~ b struct SNode{!YA!SB7}|
    float data; /*存放操作数或者计算结果*/
xm]6iG;j     char ch; /*存放运算符*/,t8sF)w\,f6l{y
};
G;Z.R9O)j!g(t4`:tv{ P7{:M B5PP&G R
struct Stack{
4pvX3L7_Z&j     SNode *top;
:pR\4OD_,i8A     SNode *base;;YZ5` y U0M
    int size;
hx9V2uI };
rzO xV#_ rU1c
}t g)t] /*栈操作函数*/4Tq%~4Z@)g
int InitStack(Stack &S); /*创建栈*/
'[/|'V t)oD} int DestroyStack(Stack &S); /*销毁栈*/
&T%@ Gbi A9jJ Br int ClearStack(Stack &S); /*清空栈*/P D]nSf'X
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
q+FtC;^ S7X int Push(Stack &S,SNode e); /*将结点e压入栈*/'F Y0} T:CK:}
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
,M5m|OaR4lp!@y %JOa-w;IG7A(mbr
/*表达式计算器相关函数*/
n4zp g,b1`)S char get_precede(char s,char c); /*判断运算符s和c的优先级*/BV9}QZ5rRl
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
"w%F`a3{J"_B float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/:kwd"^)D(U.zR
float compute(); /*表达式结算器主函数*/
S|C*k"jj El+|3V char *killzero(float result); /*去掉结果后面的0*/ :E~Dq8o'?D

5JQ\6|2T/\"W int InitStack(Stack &S)A8|8tt8~"Wp Nf`H
{&_5MnV)rm
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
m&pJAh ? M8Dqr     if(S.base==NULL)
Bi|/v%kt)Q~     {-H-Y#X8XU%kt:n ||*Q.L
        printf("动态分配内存失败!");
nZiQe E         return -1;
FF+C'c6qC'g)Z5`E)E     }
/um0vy[2zO     S.top=S.base;(Q |&?.b2WF#J
    S.size=STACK_SIZE;
+Q9ZS2[3\H     return 0;;vxyL'W"dr7^
} Fu$Uu vCss
uTCZcfX y
int DestroyStack(Stack &S)3F.Wz)K;C'R&d
{
4h4yV7F^r'}Z     free(S.base);
"f2h$kzr_,k EY     return 0;
!ox*J w4z }'\:?x1\u6}
amfA1bE-C
int ClearStack(Stack &S)
D5x O;`,G2vl z Q9l {'DT HAv,h
    S.top=S.base;
I-]+[)Q+Z^|     return 0;
_G4a/d a}g;W }G*~R:Y@5q6cB

-A6j%b"RV4c0EO int GetTop(Stack S,SNode &e)
S^/Sm0r*o {!].Q+~T\~A'{
    if(S.top==S.base)_!l2I/vB*gc4VF@
    {,~+@ @%]rh g
        printf("栈以为空!");_ \R4z gX)HP
        return -1;;oF"}R)F%E5{x(O`
    }n4l;s yS!H
    e=*(S.top-1);
SWp!_q     return 0;Oj&y y+s3bz9uo
}MC[%b w
wfQ%Y8H#s?n jh i
int Push(Stack &S,SNode e)
0V$D)i!x#RI9? {!a ZR9^ ca5o0m
    if(S.top-S.base>=S.size)
Q-?2X*D"Z     {
HD8LNE         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); @+BRQtH6y
        if(S.base==NULL).R u+M'x9kR1o+J Nw
        {
*K:os:b2C3Le             printf("动态分配内存失败!");
"m BVXfY.rR3n$jvI             return -1;)AJj5U'F w#z
        }
H v5DF f9TL         S.top=S.base+S.size;
o;Cy2[LyR         S.size+=APPEND_SIZE;
3|,xwR vx     }UY;j}lj}8y4a n
    *S.top=e;3Q$L L-q};Z@
    S.top++;
*r*f/p9VP#A ztcI     return 0;G[N_?,dG
}
Gk'~9T6\
2xMQ\~9S3s int Pop(Stack &S,SNode &e)?8P(^wX$O
{
5]*~ iu:`-I}J     if(S.top==S.base)HB'BCF b&]+x
    {
oue,k2E}"L         printf("栈为空!"); }]l X yeV
        return -1;
\G h:_&f&e     }
V4QO!s-}     e=*(S.top-1);yC8W_1v!a
    S.top--;5Ie2PZ{:I8C p
    return 0;@"lEN'O6X*U7A{Ko
} _6V9v(X%`d:f7@
pU^0hgD6i Wc
char get_precede(char s,char c)1K5Ys@;zH"CdjnH7k V
{o&z j3bI2_ T4i6d
    switch(s)-M;k/Fu2l%P!d/d
    {!g"Ft;sICo;Qv
        case '+':                 
*_GWHiQ~ @#I         case '-':^:e8^6x1i7uU
             if(c=='+'||c=='-')ZfIx?
                 return '>';'[y0oTC
             else if(c=='*'||c=='/')
hL}m^!WM:A!S                  return '<';f0~ VpsZ:wn?
             else if(c=='(')
%AlP{+B \x&? d5H                  return '<';L2D:_BQ E+P u8o4Sf
             else if(c==')')!pe3F;wd
                 return '>'; e9s%J U:C/re W0d
             else
#Yzc\/F                  return '>';6Og8V O,X8A
        case '*':
D2ES/Ua:n1g         case '/':
8?Y(h0h.Wo-oE8EpM              if(c=='+'||c=='-') Pk5}+k P#mv
                 return '>';
#e[N%S F#EH:^+R-v)Y%K              else if(c=='*'||c=='/')pw I)\ aYp3fmV
                 return '>';
gS.H L-K              else if(c=='(') d`0Kwn]/?Dl
                 return '<';
U[4lF?4N,Oj/u              else if(c==')')
3tY\'] r                  return '>';{F Vk6d0z5@
             elseW'vY-t9}6dF!C.OH#S)s
                 return '>';8k6C8x:x _3V
        case '(':
8B$PYR'@&D              if(c=='+'||c=='-')
0a7gU ya D ~}D+r                  return '<';7nl8x R^`.l@T
             else if(c=='*'||c=='/')
G e/m0p/S_ yw                  return '<';)r6IPG$KxRb7k
             else if(c=='('):OQo&jAgr
                 return '<';
oY"l;[0ThI?              else if(c==')')
Ep#V n%[)G'[L/`s7Il                  return '=';'f0Lc\Rd y A
             else
}:VIGX a/t                  return 'E';
4s8^+hl!Z9\         case ')':
![-q1D%F9w&} {              if(c=='+'||c=='-')
Q8k6n;g^Sh                  return '>';4h~%n1Ck_~&~8F
             else if(c=='*'||c=='/')Z8@+wvPu.a)S/I
                 return '>';]x(F.S}F3D}
             else if(c=='(')
7GS*fg^1n+i                  return 'E';V g5` ?c G
             else if(c==')')3M"j"`q&t/I7l Dt
                 return '>';I{rK6W_&J
             else
-Qx|tYL8?M                  return '>';
%Fp`L)h}f         case '#':_#x;G1c lJ$u}1Y
             if(c=='+'||c=='-')
HpC L;_ y E                  return '<';0sS]7y+\:J
             else if(c=='*'||c=='/')
#H$GK4y9op9K E                  return '<';@pjL8rypP4V
             else if(c=='(')
t(Q4n k;^zU*z                  return '<';
CO T!h(RU1c:aF{              else if(c==')')
/A0o]4e"d                  return 'E';0c.O/l4VJ
             elser ba#lv
                 return '=';;n$K*];FsV
        default:)W.~B%~"RTmJ5Y
             break;
0x{6z m([-m'w!\     }P}kLz7uB
    return 0;    o4Z(jH.ejqt
}I&Sz J!A!m$LL;o G5_ }

LquOt_!J"H J? int isOpr(char c) Y"U8R[RM t
{9@!{(K,vrQ
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')!D"c,a QHh s
        return 0;
D5o"[4^g6jG']m     else
E1Xa2{3fe-\;Z(o;_         return 1;KG;Qd*`$LE1vj|U(RR
}
3ne$A4Cw_a9K
u h)J#{4BzG MAm8k float operate(float x, char opr, float y)
A4lA0i5~yc U%z+A {#M Nb\H xK%b
    float result;
*i;E@l[,B     switch (opr)7K Y(bPLJk~
    {.wb,K$WK*yG!v{
        case '+': ?p|h2U(U9^*u
             result = x + y; `g6S+_G5Up` N
             break; F _t.p*dS v2s
        case '-': YTLI"]4vNn o{
             result = x - y;
n ^-c:~:` f              break;
,~.L_l;l;n         case '*': ;?]A.m@IA,wvC*L
             result = x * y;k R9a?'\:k ~ |e"z
             break;v m'^!?l| HEK
        case '/': )|~l~(]q,X
             if (y == 0)
*p4b_h6l              {7z;Uau%v$i)B
                printf("Divided by zero!\n");
$]T/t b c.AK6afIW                 return 0;
"jdVY7ZP(o              }
&YT2TS\ b.t              else
o`{7L@"o^%F              {g7PrGfg
                 result = x / y;
e-o%R/aDn5{;T                  break;Xf3T5~c4y](U5Ri5l
             }N ZN6J0o:@ p
       default:
Sa"b7mM$k              printf("Bad Input.\n");
Lc:h%O _              return 0;7N;T:Z7Q%T:M)v-i
    }:|.ncD&h:r,F d7D+a
    return result;
^8h)bVo6XEJy V R }    P8FFiSO2T[

%U,r!Tbe]"`n float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/n+LrZ;a+iN
{|5v8HLpIcKR
    Stack optr,opnd;
,Fu)w`h y mZ     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;4r2n:C']$Xz$b
    char c;
^ ht| cAF/B     char buf[16];
VOy'^R5Ov     int i=0;
/D3qHsW EV.jt3U    
*c Pi$Q/p R     InitStack(optr); /*用于寄存运算符*/#G)M,Kk _Va
    InitStack(opnd); /*用于寄存操作数和计算结果*/)M"]%^E.{G}#R0O
    memset(buf,0,sizeof(buf));
b8k1T u7M/sw    
Kx^$_+X-n     printf("Enter your expression:");K({HW"H+[6F
        
-UE7S)P.nm/a|U     opr_in.ch='#';[)N5M%C{,Pu)B$|
    Push(optr,opr_in); /*'#'入栈*/
w"oDL;b$Z4^6d     GetTop(optr,opr_top);q z:c4K|#G:r;L
    c=getchar(); V#]8?0d};jm
    while(c!='='||opr_top.ch!='#')
:kp}._7P` h     {!O g$A1L b1l3}o
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/C0@1x+z}&HQ
        {
P;{'^4Y LU+yd#d             buf[i]=c;
yIbzu)B({.}q"V*w             i++;
Z/O1Z;X G-`iQT             c=getchar();0B}b1|2Cspk
        }
/_6L:Y:?IRn         else /*是运算符*/9wm K%Of2e4x
        {;ZUVQ+G"u
            buf[i]='\0';6?-n@Z%i^ IdQ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/^#l0^c Gl
            { p|u#Wl(tLS,[
                 opn_in.data=(float)atof(buf);4c ?8s Ed4Uf
                 Push(opnd,opn_in);
;l)}.a u_;e$gI;H                  printf("opnd入栈:[%f]\n",opn_in.data);y5Tr0t,m)O'JW/^
                 i=0;
c.l1`KxYQ@                  memset(buf,0,sizeof(buf));RF,f ju,n,H
            }
6Zw:n Z*WCQ             opr_in.ch=c; Q)RJ@(W(Le
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ Z4e j)ow!z^~3[%{
            {
Oio6j+`6D                 case '<': /*优先级小于栈顶结点,则运算符入栈*/-I#Z9DW l Dj
                     Push(optr,opr_in);
J8Mh)`j%AJ vQ                      printf("optr入栈:[%c]\n",opr_in.ch);
WaUf7O q@O                      c=getchar();
dOSg]8x%Y                      break;GL~ge,BW
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/TR5SyX6q
                     Pop(optr,e);
0K7v"uj)zpS                      printf("optr出栈:去掉括号\n");
G3MC8^%HX]d                      c=getchar();
+X1\Eh_D fRnz                      break;
Q;l@9K`&q ^`1s ~I                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/Dv c0u B i
                     Pop(optr,opr_t);
w`5N.?(H8m/w'[                      printf("optr出栈:[%c]\n",opr_t.ch);,QRVtki9u0h
                     if(Pop(opnd,b)<0)
0W4BIL1@                      {
_D9@$L t @%VUp1nG                          printf("Bad Input!\n");vYJj\+?
                         fflush(stdin);nU:FO/B_ N"e&l
                         return -1; Cc f]dB9u,C"J
                     }
3_Y(R7r,O^K                      printf("opnd出栈:[%f]\n",b.data);
L0]$b%LU2`                      if(Pop(opnd,a)<0)!vA*[4K-fa$v,?PL
                     {Y ];ob^
                         printf("Bad Input!\n");
#Vj;?w4[X                          fflush(stdin); thvX%yB
                         return -1;l;UY3L\;tJN:`1p Q
                     }
$KQ-m)Jm.xz\m                      printf("opnd出栈:[%f]\n",a.data);
g)N-^*\[                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
fmJ2o+P)U                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5c?$g(]{,J
                     printf("结果入栈:[%f]\n",opn_tmp.data);
;?9_ } @ ?k`                      break;
/v#J C3df             }
!{+KaP-|b         }
"} gFdR1s.l!J         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                fmu%P7a1c ~8Mu`%j
    }z@(a.W&k+Vik.O
    GetTop(opnd,opn_tmp);.Z5N/HS7[ m'e.x
    DestroyStack(optr);
7Z G Q!h4o!L$p w     DestroyStack(opnd);
X ~;A"yi(nKJ F4] th     return opn_tmp.data;
m#x8~o3LnL.n }
T#l{-Y#L0pR*KBT9~
C/jH2]"z/E"xj char *killzero(char *res,float result)
ROtC HH}3Gc W"l'K {m$X1`,~k#H.Cs
    int i;
D Z} l hY}&Q)oZ
XE9lF K-O Du     sprintf(res,"%f",result);)ti$H[/p&q+@
    i=(int)strlen(res)-1;
d,[5V?0Zt Ug     while(i&&res[i]=='0')1O2ow:h i@4DY
    { ~0eD;EG-tf)b#k
        res[i]='\0';
,T1TG0YU'`8z         i--;
#u Y.bV-i3LM     }XWd3_ q*_-}'V
    if(res[i]=='.')
gy{6d#X E4`9w         res[i]='\0';
n^7D*dd;z/SU     return res;] P"EEhp{ W
}
iE-YRrU 8e!qhYXPC/mC5c
int main()
]:FPQgP {)YR1a:k9bX3QR
    char ch;
:X H^s/l1P$Y6~     char res[64];9dnbjY]Qu)}
    float result;
KcKBY8YJ'q     while(1)y?){&dQ^d3q
    {,Uh/M ^#~)gP5{N'qi
        result=compute();
7\;Y6ddoI         printf("\nThe result is:%s\n",killzero(res,result));7R,qpx7Ei
        printf("Do you want to continue(y/n)?:") ;3L"H0FG;YC.cfe
        ch=getch();
R,w~G|b+_0}p         putchar(ch);3YM}WPA-x
        if(ch=='n'||ch=='N')
r d%E&v3] C,S             break;$L M:l}B.j3H:U;h!y
        else
.U&~4JNHd             system("cls");
?E^ GL5v&^'z     }2P^FfZ4IY
    return 0;
"b6x kz6\P7k0I!Y }[/i][/i][/i][/i][/i][/i]N6H-b^AP

;Wz1Lt*y c [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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