捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
I_4e"\QkK\qT[ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
(XSC1V)d /**************表达式计算器************/
)No*d I;\ #include <stdio.h>
$GgL\&PkG9s7l;P #include <stdlib.h>
6o4Sc.dmS:p #include <string.h>,CU+w B:if:I a
#include <conio.h>g&h.TL\` |
#include <malloc.h>
;M0EBU;g.O9D
wp$E7V3B\!O Z iD #define STACK_SIZE 100 hjFu7P[:@3o
#define APPEND_SIZE 10fd8LCt&?H
j2iA9x#l
struct SNode{
9]8y8Wa#t     float data; /*存放操作数或者计算结果*/6f+|Slo
    char ch; /*存放运算符*/ DZ/l1nQEML
};-Bm/`YN

?j1t5CO1M struct Stack{{ A-I,z B8X-CS0f
    SNode *top;(w;txbd'uQ
    SNode *base;R5A#R}CC#g@
    int size; }J6K)lG"C7O3d ^I
};
#] H,s~*u,Xo+M
7JAQ%V%j&~E?-xj,w /*栈操作函数*/7q,Hv+eEa
int InitStack(Stack &S); /*创建栈*/
yg%BD9maD'P9F g_ int DestroyStack(Stack &S); /*销毁栈*/
Q!?f6{k int ClearStack(Stack &S); /*清空栈*/
"~*}`X\.v,Cc w%C int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
^PeJf/y int Push(Stack &S,SNode e); /*将结点e压入栈*/
4H s#j'eNj*C int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/k7z7b:Z.w#y#wk

MSX3e5k_ M /*表达式计算器相关函数*/_?4f!C} Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/tkR8y1]$c`
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
(I5IIZw|v float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$Wx7` `-e-~ QK$DC8c float compute(); /*表达式结算器主函数*/
a1o1[-\J)a S?^M char *killzero(float result); /*去掉结果后面的0*/ x kv'? ?"l
TUpD1r h
int InitStack(Stack &S):D~s U6L@7vV
{tL;F8S/c+yOP
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
PRSrGr#p     if(S.base==NULL)3|]CV!RBzyz3A
    {u/^ ?o luZdh
        printf("动态分配内存失败!"); E_Kr0^ua
        return -1;!q8IC#S?
    }
v+JI IE{-}     S.top=S.base;DP+FTT
    S.size=STACK_SIZE;;M/D9m0_xVr
    return 0;"xf mD1u%s]"U
}
&@*@3V7`)_yg-Xaj T&v
%U o |+Y#C7\!L int DestroyStack(Stack &S)0X@'N?~6y$Q3fQ
{
)If3z!dw Ad?     free(S.base);9aX8FfP:r*WP
    return 0;
h JYb;wPM }!oH*]x a

:z6tEQUZ2p int ClearStack(Stack &S)
+t:u)n&XS^we {
:iy2j{5]t;sw E     S.top=S.base;
Bv-E5J Z9j[o9W%E     return 0;GK(uHf2O
}H*j];x*D ~\
8`/U,J'O:d+RTf x
int GetTop(Stack S,SNode &e)
/ftD9F`%d(n yTv {I7^o}4xF5n
    if(S.top==S.base)
$w/s@.Su7w&X     {]O&E3f4qJ/^@
        printf("栈以为空!");x&Q j+U(]1X U
        return -1;6FQbw*yB
    }w:BbL k(w'DQP
    e=*(S.top-1);+D+r/i'kq R~
    return 0;
$xle,J/DW } T`$uuJ

"\ T[E:Y int Push(Stack &S,SNode e)
'ns!aRV"s {-ycUkR9D
    if(S.top-S.base>=S.size))k'U uZd2Q
    {&RA/li/I*d"U*Y B^&Ex
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
jfwz@9?Wk         if(S.base==NULL)@}]0|'\"_P i{1@ P
        {
i { F&G3U             printf("动态分配内存失败!");
!jk6ui.@Z/|U%n             return -1; },Y6HEt
        }#^ h#~~ bb'Mw
        S.top=S.base+S.size;
Z7u)q?"q0DI!I5i         S.size+=APPEND_SIZE;7W]1JsPX
    }]2dh'aIHe J^|
    *S.top=e;
} vM1]GR     S.top++;
k)jL!_;x_     return 0;8|#y n"lq?iW
}
L\\3Y:H X /z3o Tg{&z4v`
int Pop(Stack &S,SNode &e)hwi1{{f_](n(m
{
:^\QvEfu-B     if(S.top==S.base)Oj1c#qM~!@}/@
    {"n I)mDR&[B5w.H8CL
        printf("栈为空!");twi t-U:K uDl
        return -1;$L Kc.x!Za_
    }
'G8S3SN(~     e=*(S.top-1);mo7O A9g?
    S.top--;'TB,T]3[ ]'l+d
    return 0;
]#n}9O{0| }rM*WZ{

F;t7n/? Z%Q$X{K%e char get_precede(char s,char c) n Qr ?/V1We0f/CW
{ V6s N}^Ek [
    switch(s) [9]~"udiy:Z
    {b4D~+f2X&E8W
        case '+':                 
Pw2A:KfUt         case '-':
)o8l K;\ m {d              if(c=='+'||c=='-')
Y5DP;k9~/|Ep                  return '>';
D3N dv-p |9owN              else if(c=='*'||c=='/')(fqr4M(y.S n!C3e
                 return '<';|ZW3A l?*t%C;?
             else if(c=='(')
%Ld)Oo ?(p                  return '<';Rtjna&U5GF
             else if(c==')') mA1B4n Bz.][
                 return '>';
D*ZX?8_[^%h-zv              else 5uB&RX [_7JN c
                 return '>';9Q8?_a_Z{
        case '*':%}B wxP
        case '/':
` c,e'gU PvR7@              if(c=='+'||c=='-')7r0VtC"O6I;h'ULki
                 return '>';
-e7_^^*{d[              else if(c=='*'||c=='/')
$yE)~#GPm                  return '>';Gb4o:~i?8e5l
             else if(c=='(')XAa2F1sK
                 return '<';
h1Y&X o8z\ sG              else if(c==')')
%~t7BpA                  return '>';
~2hE&d0b_S              else7C!c4a5r!@X ^8@
                 return '>';
1oiS$Je+n         case '(':
T"UXG4Z}6Y[*S              if(c=='+'||c=='-')[,]G8{5u T6w8Gt l&iA
                 return '<';"b!T7xw?\0ZO~
             else if(c=='*'||c=='/')
/^`[a M}D#Z `                  return '<';8]B9}l i[T
             else if(c=='(')
"N'I&F"D7|.a6ZCq                  return '<';
/{ Hf{ y+k+J              else if(c==')')
S#zef `                  return '=';
G[,q9`K%J O              else3qo;I~)l.V
                 return 'E';;`e U A3{/~ eb
        case ')':L1sr&y tE\
             if(c=='+'||c=='-')~%`:j y2[wH3u[i
                 return '>';1V`*r-Ct%|T2|(U b l_
             else if(c=='*'||c=='/') kyJ8c.D&T5G3dy
                 return '>';
qq2v2v3jA*x              else if(c=='(')bW+^]I
                 return 'E';
Ujy L!U~$F              else if(c==')')T![1\`*?&ei/Ct*E
                 return '>';:vLUm(Wuq&n_3sI
             else'af;ty-p.TM
                 return '>';
R&`"h[:~7J U#B x s/R         case '#':
g#L gut              if(c=='+'||c=='-')
^S+Tf q*p                  return '<'; aj9U7x(m1V
             else if(c=='*'||c=='/')R"Q/{h dt
                 return '<';
%ec^,pL p              else if(c=='(')
7\$K JVr)Fc@                  return '<';~;@aq Y
             else if(c==')')}t[2L'P?u
                 return 'E';[p{E9k"C'D
             elseBoI\E;X(wCk
                 return '=';
u`4_4E1d.nK)Kl.Ne         default:X!dP MZV\
             break;q{,R uY9w!q W"C
    }
/qYPy1r0{)_1ysjFE     return 0;    6JAq~-c_6{"Z
},e/P(X3P G`{qV

:J9`'sE@z:o$|1c int isOpr(char c)
8dl+zPV3J {
[:u.f'U D.L3bnywe     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7U a5b!DJ+h7W.e
        return 0;
V;wtKI"j#Vyp     else { nwge;d5Ar2P
        return 1;
ze+l(e\{ }
e*x$WOY_ A0IL4a"F1R'| \
float operate(float x, char opr, float y)1J,cTk*u~t n
{W2@*?q6x,Tk#~x
    float result;,pNK,D,b
    switch (opr)
0j2ci4?(N&Y     {W!C!^'E|uP
        case '+': L2X@ @ \ WA4G.m$m
             result = x + y;5A9xyF G@/Q0x;V,H
             break; G;pL7w;@
        case '-':
"hz-g7z l R V;R              result = x - y;
vm:_6H0RCcR              break;
WclWO5w-r         case '*':
1{.t7Oi|y&V bCL$v              result = x * y;kqH)@2@+~ \ n*mS
             break;}O1~,qM1{KJa
        case '/':
$IYA$x6];Y,OIh}              if (y == 0)
:x M+~!o U7vr              {
v-T#p%u$P6Nv1M                 printf("Divided by zero!\n");f/?q];X+cIl5R
                return 0;8y+azJ!fh4Ii_
             }m.NFI t.^c-S.D
             else
dxC:g)s              { l)b3a4b~/NE
                 result = x / y;`|0vIH&s
                 break;
Ss xy)o5t*?4e2}g&FL              }
`E4q ^/E W6l6\1x        default: 'JU0bCs@bW
             printf("Bad Input.\n");
|/KsMaRC)L_G              return 0;
:QwAn~#F1k:E     }
2{tQsD7n+FI     return result;3]F:]Z;k}/w D0w
}    fQ,L;MP3E

:iZ?G.D float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$rWj$]N*T {
VY&Xa2v$Z7c     Stack optr,opnd;
/vY8pBku$zd     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5e2XvA$fL&@i     char c;#B0vQf"`]+w
    char buf[16];
0j4V2Bo~:Y;J/L     int i=0; u!_ngv J0a#r
    V|#_4z0r XREu2`
    InitStack(optr); /*用于寄存运算符*/M7r,|Tw:|Y
    InitStack(opnd); /*用于寄存操作数和计算结果*/j*v,I,n K/N
    memset(buf,0,sizeof(buf)); K ?z&t2\iF&Z!@Q
   
c o#o^-j*b     printf("Enter your expression:");)qg.n"~ YSd9^h!j
        
A qH;\F{+A     opr_in.ch='#';
-g/R8RNw-a     Push(optr,opr_in); /*'#'入栈*/
6w:h[V*xx z^b     GetTop(optr,opr_top);P w5[(fA
    c=getchar(); jF? F;@J\h%a
    while(c!='='||opr_top.ch!='#')0i,a8BO8\)u t
    {
E8Y6`/Dog n         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
3nL C e0KP         {@sy(b1?%x
            buf[i]=c;
$FH.J T U!aZU8h8v`*?             i++;
7e WZ&]L             c=getchar();&e.j;AJ/} m
        }
D2i1_C E(nK         else /*是运算符*/
!AV7| D_:]Y^`3R:J         {)P:kC+c&x,ER@#Mq
            buf[i]='\0'; yW fClU"\Q ]%r
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
]u8Sl$~ W&Y             {!B/? NV+U UBP
                 opn_in.data=(float)atof(buf);
5mWq#Oqt ]                  Push(opnd,opn_in);5oU @a;|d_)K~
                 printf("opnd入栈:[%f]\n",opn_in.data);
4` _J2az(f                  i=0;
{@;X YP:h2n                  memset(buf,0,sizeof(buf));
8P0Iv,sY+Km             }{^m ^!Atk J
            opr_in.ch=c;
Nf%rI%Z             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
oj!aNlh\             {TE"r W aSa
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
Q u Ui4h-zD3m {nS~%sj                      Push(optr,opr_in);
y\L ? m1t%~s                      printf("optr入栈:[%c]\n",opr_in.ch);
-r/v.d8c LH"w                      c=getchar();v7ef ChDQ
                     break;
ly+U)W7@Q                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
h4~/Ju?s6aN-nR                      Pop(optr,e);
&@T^Onp                      printf("optr出栈:去掉括号\n");
P%w(i!V!J|H'V                      c=getchar();
}'ZF'lYS                      break;
d[.t0oPT w                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1F$Sb#vE{m Xb6E)A
                     Pop(optr,opr_t);O?/n/g-O
                     printf("optr出栈:[%c]\n",opr_t.ch);}X*? J\6zXX Y
                     if(Pop(opnd,b)<0)
p1i0?~3G AlHi                      {$Q m%_*T7AV
                         printf("Bad Input!\n");
m'Ua{-b[@$U                          fflush(stdin);
JuY,y-[d.WE                          return -1;q&a M*R&EK n J_&l
                     }
#mI l2q~7@$];c5t-x                      printf("opnd出栈:[%f]\n",b.data);Xn7X g7u
                     if(Pop(opnd,a)<0)
2If$x-B1?f                      {
9M}:G?%s1|t                          printf("Bad Input!\n"); Z u)ziap
                         fflush(stdin);
4X4v OMkC!H&y                          return -1;q y!^2Y#nPC%o
                     }${&^Af6hO;J-_2D]
                     printf("opnd出栈:[%f]\n",a.data);
.cPGIXzd#q\                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
{^;bmHiV                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
Km p2G#sdBD                      printf("结果入栈:[%f]\n",opn_tmp.data);
8iif!v.W%Z9?_xH                      break;
yNfA e             }
G8\"h2s"f*S3l g%h         }
(ES[[ X&NQh         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                L4R QN:HA
    }_ L/K@` O0JR
    GetTop(opnd,opn_tmp);KdS v1k ~1U$_
    DestroyStack(optr); NLb'v c]%Q1U gOA
    DestroyStack(opnd);
2Qd"n-Sm%e4P     return opn_tmp.data;+TNa%D`'a@&Ic%S"\
}3N^$gmh
wE@ wSL+w(Z6j ot
char *killzero(char *res,float result)ZzZ g!qZq
{
jb j'L;i/Mf     int i;b*z4d7} n
0a^&a3nV
    sprintf(res,"%f",result);S4STf%q~4^'?$BL#d
    i=(int)strlen(res)-1;v o;A4r]L6BO
    while(i&&res[i]=='0')#}_Qj([c0M9T%O&]
    {
P!C?,A7I(j\5Q         res[i]='\0';@} VB$i'C+W@)i6L
        i--;)\0g4R:GF
    }6u1[{ d"S5Kz4B(h q
    if(res[i]=='.')3uZt8Ma E.~"k
        res[i]='\0';.B R zB-H"@
    return res;t9T f4n,r^&c HQ
}
:A(Ts2B-I}A:I;K
"g!yr;S? int main()Q$n*_cA6g
{
\9w,wD^ m"I     char ch; B]h4\1l? wb m-V
    char res[64];4x)?f~|9O:f
    float result;
fY:N3~(a.tr"n/f"D     while(1)
NV NFM"}     {
y`y2?t e hf         result=compute();
9}?@/jnx$N         printf("\nThe result is:%s\n",killzero(res,result));
;F0i _ Z@6V$SL?         printf("Do you want to continue(y/n)?:") ;9I hP)cs q"v"g5Z
        ch=getch();
,Vp Tv}         putchar(ch);s3}'J YnZn
        if(ch=='n'||ch=='N')
{:p z H8cw0s QC             break;
K FF NU"Q&H         else
svk^^ z ijL d             system("cls");QQ|Xc*n
    } Yv+@}/n[
    return 0;
i;X;q txs0cj }[/i][/i][/i][/i][/i][/i]
r:Sk|z heC[p
J'WG.RK-V$f [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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