捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.3sK)g{yvZ(_
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
JK \4E,zy Q /**************表达式计算器************/
^#C Wtj{~ #include <stdio.h>
;m!pcG3i EDI #include <stdlib.h>
(L8Vz#C}4T$C;\ D{S #include <string.h> rt!~O(g y;g
#include <conio.h>5V)Nl#E2@b(CC^4D
#include <malloc.h>F6^hwbS

/_V#PX4O'WR;[-B #define STACK_SIZE 100
Q0~9B-cuc-I #define APPEND_SIZE 10
3K!k ~4U;yhkE2y6Rj8] 'Hw~KNM*D
struct SNode{
RsO;^ r?     float data; /*存放操作数或者计算结果*/!N,X/x}Qz
    char ch; /*存放运算符*/ r'?5^hd
};"hDQvOQ/C-`2Z"]

(a,Z|3mg7k4d struct Stack{Y:`3c lpU9n,P
    SNode *top;
0Um8DM:t n5d     SNode *base;
;E|;I5^^%{0LSa8ozr     int size;p$xi7?]1MT/C
};
0S y3AlF8j s!pF3c
Uu6t1f4A /*栈操作函数*/
D!W:W/ZCG,hw int InitStack(Stack &S); /*创建栈*/Av:C#Ow w&b W z
int DestroyStack(Stack &S); /*销毁栈*/
v t2KuD9N-P5` int ClearStack(Stack &S); /*清空栈*/
u1B+Ltxg+sP9r.v int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/GP$_ ~(n3zE
int Push(Stack &S,SNode e); /*将结点e压入栈*/U)f+Y.s4H(]?
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
0i$C!{ U|8\*|D
t+D,]S,OPc8V /*表达式计算器相关函数*/1n:UC W1l&i9V
char get_precede(char s,char c); /*判断运算符s和c的优先级*/*e2xj*d[
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ t(Z)Ud1ImR
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6d \N,}Lr
float compute(); /*表达式结算器主函数*/V$hK)G(kb4`"[8|
char *killzero(float result); /*去掉结果后面的0*/ "\m J'_]o9PQ"G
Hr%s z!o.WO9Pn8E
int InitStack(Stack &S)c5]:\Ri G-l ?*c e
{
[9m vW(q7K"B0Q     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
}6pY,^7G2`9XW i Y M1?     if(S.base==NULL)
tjmf[,d     {
VJ"p]Jwos         printf("动态分配内存失败!");
4a5P| z$[MGGH ^'A         return -1;
D3zmz0C2^&^     }
u{*G7^}     S.top=S.base;0CV'[`H
    S.size=STACK_SIZE;
'aGd!hAn'j     return 0;
IQW @8]%E }
:blHWP5\-w
K0V8D#g'~z&iwc:u int DestroyStack(Stack &S)'j5K$sUBu^
{
'Lt M$d_-A-^(Io7r     free(S.base);
2~OH(l"J/@3o     return 0;
V Y-{+A,~2z2`{{ }
a\_i.o9u-JE
+QP%kMW3f int ClearStack(Stack &S),hl_*zW-n%n
{
.d @5cZm&T_1J     S.top=S.base;k3^4]Tk!\sVb&k/H.G
    return 0;-t]L |#C uY:s
}
7c]Ek$W@3vk(D f
g5BIz,m:L`v1g/v.K int GetTop(Stack S,SNode &e)p Uz fwZmQ
{t8X{"]+o_8I&hd
    if(S.top==S.base)5@9v6J2] us
    {
rz C;@xj#a4y         printf("栈以为空!");
V o{v;no+Mo         return -1;;[s1s\Rx
    }w6np*U6Ej EPt
    e=*(S.top-1);
v,K#X}(@WC     return 0;
| ~q o:C [mA }1wx;]`I/m9j

7rCO'eVS int Push(Stack &S,SNode e)X vbh*tq+I YA
{T G _5V ]hs)p+^
    if(S.top-S.base>=S.size)9|+[ vl#z}AO
    {
#q:mB B,K]Ce/I+@q         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));3g \;wXd
        if(S.base==NULL)
!]glsR z9ezY         {
`f-{u qyFn             printf("动态分配内存失败!");w R9k$O2n6u AfH m(Y
            return -1;4\N,v+^p+bN'b,n5F
        }
6l%l7oW ~Q;U+D%T8} `         S.top=S.base+S.size;/@A6wD ts+d,g
        S.size+=APPEND_SIZE;
h3Myb7UfI zsA;i#L     }
)f)Hr[+r8_     *S.top=e;7V@(A-g)L7s;M4C
    S.top++;
o S ~/g OQ$l&G     return 0;
,{YV)tV9iMg+r },?@}'Lr%l/TPD~

w oD e]b int Pop(Stack &S,SNode &e) M.U\D`!~ V
{
6J{7CO3b     if(S.top==S.base)#U1Zn$Q5V.TUBi
    {F7^#lOp.?
        printf("栈为空!");
^u4ld7znj         return -1;
b;C;`R8PT*H:S|     }
.|9I-m-@0H"AR k     e=*(S.top-1);
%TCFU q     S.top--;
'Sf @9[#g N _K     return 0;
@idcZP }
{c+b2s5hX5X8WS
;^Dg!w n3e gec char get_precede(char s,char c)G!{;v+O5s\
{"aP^Aq,p dX t
    switch(s)
:rf:r eZ6ByU5Z2eo     {
UU J:O@8XI#\         case '+':                 -DM+po!T'^mp
        case '-':
I?4] e H;N"p              if(c=='+'||c=='-')'e^3R6|'V|L
                 return '>';
.F6z;y)G!e[1Vmc F              else if(c=='*'||c=='/')(G-syg8}R
                 return '<';
t"i$uq[6R b              else if(c=='(')9i s.Z#h3k
                 return '<';
D+JK4K _0zNB/UD$G              else if(c==')')0kI9\Ei+]
                 return '>';
]%eRfQ l_D              else %V0A MRN!C
                 return '>';
@qC^:O         case '*':
o/PaH2Bm9L         case '/':V8nz+UI?%k{N
             if(c=='+'||c=='-')
"A8go.^-t(f`3du                  return '>';
"AC2i)aNwk              else if(c=='*'||c=='/')0f J'T9g,~ o
                 return '>';9K4sN g7~~
             else if(c=='(')
X)T{`_7RlK                  return '<';
!m/]5L^9i ]              else if(c==')')
t6] kJ2J \]b'Mc,~                  return '>';
W@.a2q s%~ t              else _5Ph9n0}y!fTw_
                 return '>';
(Sy(|5]8I)G         case '(':
7h J0C&Jj6cR[              if(c=='+'||c=='-')
"L`1m2F[;H'_ nA                  return '<';
A%o,oV?,S#|bJ              else if(c=='*'||c=='/')
P$X)es5V"pC$x$B                  return '<';
%d/[A9L&d{C'rK              else if(c=='(')D*Jo^3FlV [1@
                 return '<';-EPP b#I:e6K
             else if(c==')')
;{N5{7W Kt'UH6B/^                  return '=';
DL.i9ER0qmX              else
9w!\f"D+w"o                  return 'E';H+D!VOvUA
        case ')': N3y*U;w7au R?
             if(c=='+'||c=='-') w(YKc}$UL c{
                 return '>'; G}X$E[(t
             else if(c=='*'||c=='/')
%P5Y)gjEiHX3I                  return '>';e6L*omyL
             else if(c=='(')
IOfh(cW                  return 'E';
5J$H+H'z/v-xj:Rw Ko              else if(c==')')
a;\RmPS gx V:o                  return '>';
9ag l]#k3x~"Dh              else
RE%Lz.OjS9H                  return '>';Hq9@D6|u!X s
        case '#':
]s7m(?y q              if(c=='+'||c=='-')
ZHY+I:f                  return '<';LLH Tt+v.y
             else if(c=='*'||c=='/')
;? { m}#Ef:o                  return '<';Y`/Bq zQXZ
             else if(c=='(')
$[2jpw2~W CP%h                  return '<';
R(uE6k-Z              else if(c==')')
}:{l@Xo JEw                  return 'E';
g rG,^d,|              else H;n w@Zl.C(I
                 return '=';
#e,{&AA @ u0}F7b         default::~2I:B|#K.e
             break;
hqqsBZX?S3k     }7ILA ~?
    return 0;    ,l"{-|6@O8b)p
}
qWL o1XAD R/e0R,@,K?%?si2n
int isOpr(char c)!B~1[9I|z G
{-|.T5TO(Eau
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
:u3c7|WOu         return 0;
C Ra:n8w;r     else p/b%dr/zG
        return 1;0w!Kqc,|*}%q:{
} s:X#PWV#[O&b%Y#B

5EWY^0u;q n*X*pn float operate(float x, char opr, float y)
@+_/`7d#\C { s?g {1I
    float result;
-H&}J4N;`-SC)B/C)S     switch (opr) c0QY9m5qK
    {
:A%b"]&`DMGM\         case '+': 2C5j HK.VQ j1W
             result = x + y;%b9hc-PO5b&y3h'?
             break;G!u6kMJ5e4I7q
        case '-':
`#ddk'o+`o              result = x - y;
y7Q kUiF              break;
8TLD)~d!n s%Alg$J         case '*':
x({M [ g,vv8O              result = x * y;
9M"^Q:L4r%E'Z/\Ef              break;([ {8Y,].?1ZS'w D
        case '/': ]gzA `~1w
             if (y == 0)
$?x"pa/w j/^              {hV V0sw-x cr
                printf("Divided by zero!\n");
-c:D [7v0Z)}                 return 0;
4qo#D6_,f{5RS              }
L(Qy'\.K"JX              else
#f y"eDQ!@.GiDIy              {6?6p$We4k1~
                 result = x / y; c`X)e2X{"^O
                 break;
^'HP;Z'Z x7[m              }|` G1M'jh
       default:
:w]!O(F!H[              printf("Bad Input.\n");
0H"Kfija8?              return 0;
Z3E\e3l uj     }
)SC ? [W%j] p@F     return result;
:n'YeZ cS*b }    ,?;_\$g'o x\8v1`

:w#c0L z's*fl float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1Y"e'J%_ t1iDCO
{
/[#T$o3BN^"}8WGd     Stack optr,opnd;(rv(Z$~ G"A
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1K2i|&Zc
    char c; \5v\a6qu3vL)v
    char buf[16];
HoSG4A^$N'B9w     int i=0;&y|p4u2pmB
    %P f[LL9Q7R"N!L
    InitStack(optr); /*用于寄存运算符*/K1kOx y0f#TU
    InitStack(opnd); /*用于寄存操作数和计算结果*/
/L:Zm u qW WB     memset(buf,0,sizeof(buf));4us1S7vH{Co
   
v,{~K[_     printf("Enter your expression:");Z.n FgLa Hb C
        \%`T+c*XL*L!i
    opr_in.ch='#';qZ\;~,Cl q
    Push(optr,opr_in); /*'#'入栈*/
I6F n6e0|+n&D#n     GetTop(optr,opr_top);
t'f^*x@e M)_4`5I     c=getchar();
I6K8{/F$jy ]DXD8s     while(c!='='||opr_top.ch!='#'):`yFSo"e
    {:@qU3U7eEg$z6H)?
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/*f,J*LDc;Wb*p:t
        {Zl&L"W2N)UW
            buf[i]=c;6r-HB6]x#S$tG
            i++;5r6h)_H5uE M{
            c=getchar();
U] u.gs _         }:q)w k]qYy{
        else /*是运算符*/q4Ic*zm,tuGj
        {)P9xdkSg ]6A
            buf[i]='\0';
2x;]!{d avK*{             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9P S[Oj             {f*hi F-fJ8`K N
                 opn_in.data=(float)atof(buf);0X5pZazW0W&xB6e#~Xd
                 Push(opnd,opn_in);
7N KCtz'I:Y                  printf("opnd入栈:[%f]\n",opn_in.data);
MN"YW~d I                  i=0;
*YR2hPi                  memset(buf,0,sizeof(buf));
Y1|%YpGL eg U             }
.R0S u$dsgG             opr_in.ch=c;
%wwY#k ?0G^c:s             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
'^ d-O4G7U1lxsb             {
iy.C$Rr B5f!WS o.O,Y*D                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
!Irh'z$jC8@l                      Push(optr,opr_in);
-\J8kujc,L@,x b                      printf("optr入栈:[%c]\n",opr_in.ch);#SQ Z4h q,|#A n
                     c=getchar();
:W3B?1D;yO8|                      break;
Z*ruvcb8xij8hj                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5? e"q@6Z:a]2c@
                     Pop(optr,e);
*nc5Jq]GYJ4w)K#V                      printf("optr出栈:去掉括号\n");j~8sN7^'y)@ j
                     c=getchar();M0B3f-G#vtj
                     break;}va,C,\
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
U-RQ t,y'x                      Pop(optr,opr_t);QC@a-iaci [
                     printf("optr出栈:[%c]\n",opr_t.ch);
b)i!m"{t^'i                      if(Pop(opnd,b)<0)
A,CM/C8l'u~m&E                      {
$ae ]&]'Pv%{._(vd                          printf("Bad Input!\n");Ne c"~ H:]K8V
                         fflush(stdin); S&ub gW5R9u5X x(c
                         return -1;
M!gEe$mH6w,^                      }
9F!J0u%y(v6J Xn                      printf("opnd出栈:[%f]\n",b.data);
!h)s$Bd~2I                      if(Pop(opnd,a)<0);h8p!N@!xZ1f.jUmL1yq.X
                     {
-J,vOlN!n~p2F                          printf("Bad Input!\n");4Mfu_$WP,d
                         fflush(stdin);
'f m!qg.y#[ GB                          return -1; t^n*X`7M[xl
                     }
?w^A1X0Hm                      printf("opnd出栈:[%f]\n",a.data);
$Gx]/L8b;C1^0D                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/m9Pwn nOG
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/W'lcS p/fp9i"E#o
                     printf("结果入栈:[%f]\n",opn_tmp.data);6{2qooE xYR
                     break; T}#rc.|rwY
            }wZ4Ha$|r6m^(Q
        }
l)fP/~(rT6Y2K         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:Z\|[4ZU5G$j4g     }
/n1E+NG/WSO     GetTop(opnd,opn_tmp);
f0f/|E8V9y9a ^ Z     DestroyStack(optr);
.i%^\#kV2z.rmI V     DestroyStack(opnd);Mk]]1w
    return opn_tmp.data;
q+IL$T/} } h R@3?I

9E)B4Q{wDa4_ {BR char *killzero(char *res,float result)
N1Wn`?(n {
e3H.tFGx     int i;
-T5a&Ws2yqqG[
sIE of&|Q5w     sprintf(res,"%f",result);E WM? I0Z s@
    i=(int)strlen(res)-1;
? rfEHW S     while(i&&res[i]=='0')
,Cg d,]\0y%X7~3[     {
QHR/X+C Yk?dx~ [         res[i]='\0';[%Sd?+Oof:L
        i--;%iv:N3g ][PB:G
    }rA4_ p wQ:v E
    if(res[i]=='.')
&I+ke+];^M$]M/{         res[i]='\0';
!n*_!n`%i^!KCfl     return res;
px v{-v }GQT^M9T?/l
$t-X^-Q*x%{e0g
int main()Ixz wIJc kJ
{
4|Xl-?X$h/J     char ch;
%]qn9e ~"QcE     char res[64];c1Wau~zq
    float result;
,e`,btn#y]y     while(1)2`wpk-J%E
    {'b/T?\.b bF
        result=compute();\M?6t-@
        printf("\nThe result is:%s\n",killzero(res,result));
3\;K EH-jpLX z'R         printf("Do you want to continue(y/n)?:") ;
kR;~I@?A         ch=getch();4xY!_noj
        putchar(ch);
2~ f!oqF4\G#~         if(ch=='n'||ch=='N'),mJghaSE
            break; y3jh4_o1n)L-\
        else
:Q,woBTfNi'q             system("cls");
:^"Tf ^ \3e:f2`     }?"\@&p;LX!G m
    return 0;
aQk6F9CX }[/i][/i][/i][/i][/i][/i]
Z"I#_ y*V`:YGR
b~_vWM4R [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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