捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6p.G [zm8~+C:yq
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6?&~%h.M dQ /**************表达式计算器************/\Gmz,i e
#include <stdio.h>M`Qd"T!T
#include <stdlib.h>/c RGI*n/X?C8Z%Z
#include <string.h>;Uf^ omX3x R:|}
#include <conio.h>
m i1X1lj0V #include <malloc.h>#s5C$vIK}.E,{

(T$QU F0pI$R q)a/a-V'N #define STACK_SIZE 100
J0y0M-nc[&mC #define APPEND_SIZE 10
,}B D$wl:u *A,J6L+lDpC#]
struct SNode{
0i2bsyn"Z:u~     float data; /*存放操作数或者计算结果*/hB7sY'v W N { yT
    char ch; /*存放运算符*/
*E"l ^Kh:` h C };
bS%mH-bK+RP K^MapOy
struct Stack{
Z2|r-F0jK z}k@     SNode *top;+L&Z3PQ` GV0E0~U
    SNode *base;
/D*J%{} i^"P$SA     int size;-[.G4po"Q;oMH
};
W)XPh3V"n(M#T0s
W#gV4{e0Z5ZS VH,o /*栈操作函数*/?e|w3v&^+[9~ d8l
int InitStack(Stack &S); /*创建栈*/;@5zH5j(J&_,l
int DestroyStack(Stack &S); /*销毁栈*/p$X l3n/t I+P+HX7N
int ClearStack(Stack &S); /*清空栈*/
4[ lnQ!}J+H'M int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/&~v%D OT1t-g\e7Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/
$T%z'E g}8I4Z!n?R int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/F)c D!y*b ~

s6jAK o|d}&u /*表达式计算器相关函数*/
"w-g M"B6_)G&j char get_precede(char s,char c); /*判断运算符s和c的优先级*/
?Vv7Rm/f,g u int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
a aL(M_.H@w float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
IA^ xU3^%[ float compute(); /*表达式结算器主函数*/
)w,r:b$p*T*w)E DK char *killzero(float result); /*去掉结果后面的0*/
Nw+u6A.UW Y-ex
#Qq'VlT3W$Bj int InitStack(Stack &S)
"YG#D|U@ m {0e(p4J u3Co[g
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
#WF?V3t0N/]3D     if(S.base==NULL)d4zA i2RX"w3z0usU
    {
1]~!soE-Ej         printf("动态分配内存失败!");
T4\ ^1{^q+[!?         return -1;unT.B*y?
    }
N/n/c9qb6Dw u     S.top=S.base;
.z5qR)?6Pp{     S.size=STACK_SIZE;hPI njd
    return 0;c)g:VtT2VD%N t
}?1Z8LQX Gq#r*cZ|

:uX^1w{1wq int DestroyStack(Stack &S)&Ew~mJ}*`/ut
{
u pG1g] ~z3K     free(S.base);^S/LJt
    return 0;
5k/j#g8tc+L-z2P d }
Y9?0a/q?/qq+]J*wq 8Gy"? TIb
int ClearStack(Stack &S)
2{GFlU4C?K"] {8gfO4M.|.\K m)?
    S.top=S.base;)]T ^!Y2oc
    return 0;
;I)xti*p,{z }:t Zad H5l
0d g.JB;[1s(w$S*Y
int GetTop(Stack S,SNode &e)b/f1t4d:\m,G$~RD*Q
{
:\u5c;CrFG+h!p     if(S.top==S.base)$V n6DK4mu
    {
$j)W!B#?]P         printf("栈以为空!");Y(^!Bi.Mi4|~)i
        return -1;7C&k9\'RUbvjZ
    }evtTP&G
    e=*(S.top-1);5j0\5l;VGS/C9h.g
    return 0;+[k-JUBW X;}
}
%MdI-}l|RZ$H9^
~lZ eOI int Push(Stack &S,SNode e) A:Az4[ },TvMlIB
{
Ztxa.]     if(S.top-S.base>=S.size).C w'C-qy%EV
    {JXN*u5A R4\4Q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
pM7P7W$yi0x$QM\         if(S.base==NULL)
f4]hY'gz"mCe,@         {f-]6H[w^
            printf("动态分配内存失败!");
B6t TC!x f|g             return -1;
2K(O!S5@,K7bH%o1Oy         }&MBE!n!o2{6XKEY
        S.top=S.base+S.size;
U&E7O?f!lRo         S.size+=APPEND_SIZE;|"_ {%N)B.p
    }
%t1^G$EyMUF     *S.top=e;j,V8s&f3[eG
    S.top++;
b0Bwgb4I6C3Q'n4e.S     return 0;!Q u,O/qsDYa9R
}
r"J B0t*gbTK
!]`Hz6^waM9v int Pop(Stack &S,SNode &e)
lg7Uo e6A7g {am%T$R_5F ZA$u
    if(S.top==S.base)1bM:YhZ1f m V
    {Cw Y8REy
        printf("栈为空!");#q?c#R(m2S!t V(m
        return -1;e3g+v'iy9k2Vo
    }
W4a i\y1a1T*B     e=*(S.top-1);3_o)A I&v+i
    S.top--;Tv N}L F
    return 0;3`'x S;HZ)]
}&l:`4{*S6cw(^ DUOY`

}v,Ua'\3} char get_precede(char s,char c)tA#_l9H
{!{xRp%@ y"F6P
    switch(s)
,QVuLMw6_(S WE     {
5q.E)a8b.q(Qj!u         case '+':                 
]"b |)r$R}         case '-':
gE lnJu0ca              if(c=='+'||c=='-')
:Dx7s _]                  return '>';
7? B/B$V"A+W"X              else if(c=='*'||c=='/')8qYm:y ?
                 return '<';
,Yn8[r%X0gZ W              else if(c=='(');d"Rh n([B.Y u;jsl
                 return '<';
t ~a,a X              else if(c==')')&e |nB*k
                 return '>';
G t*P ]sX              else )k}%KY7YDZ~,C;jE.B
                 return '>';
p2Hv]nZ{M         case '*':
|)Z w{(P TT         case '/': |#Rrk]0R-I
             if(c=='+'||c=='-')8a~7S'o5F0o!z
                 return '>';$?X [&d8e6V"zx)jn{
             else if(c=='*'||c=='/')-B"v|6^y:[/|
                 return '>'; o A"Q/xU"R n bX
             else if(c=='(')
%t)P P/`;Ou W                  return '<';
]4L*P)b6? J              else if(c==')')
6D Q(M2a%?+\Z$s5@                  return '>';
v3J1n0K_)o2g              else8YfPTn p7V9G
                 return '>';
G^C U:~t         case '(':
-IN @E%H7dM'bt              if(c=='+'||c=='-')
#j#TXSF1mU                  return '<';
? _}5j0O              else if(c=='*'||c=='/') aj9JtHt
                 return '<';
oy0L7_k2d              else if(c=='(')7}T B:OQ D:MI7|4qJ
                 return '<';
,\SJ_W&Y_&P_-k              else if(c==')')I q2S8|9e8|;~m
                 return '=';
8o$r+mU]              else
xM:o\;eVE                  return 'E';
B&P"j)C7g5d _(n         case ')':
S/j s3e/^              if(c=='+'||c=='-')
Of9dD {D                  return '>';3M8k|xx
             else if(c=='*'||c=='/')}-U!eI&s_z5tLH
                 return '>';*G4}$l0D4g6tR
             else if(c=='(')AhW+mf G
                 return 'E';
%q7K r Ro_N7oG$l              else if(c==')')
9@{VWxw$}@                  return '>';
5Y%QYz0cq.Ls              else
,F o Xwv@\ e9Pl                  return '>';
!ok,vKBd CgR         case '#': j5a}.P5HIA
             if(c=='+'||c=='-')
!b%wzlR#`_'pR9F?|                  return '<';
P!Bk'R/l              else if(c=='*'||c=='/')
|~5d}0t1[%l U*A                  return '<';
_X@Y'F@3J R              else if(c=='(')
nYp%}5K%s+C`                  return '<';n8b6o `a?V|P
             else if(c==')')0Kfo9~P_ex
                 return 'E';
#x3O0r!F%r(z              else
?c6e gg\ y b#r                  return '=';
C#^!HCr         default:
!zA x0d ?              break;
A A#K0d w{2vdX!GG     }pJ)a:G'N^H
    return 0;    )aZVt9Iw|
}D ]%hM(bhB
+{#G&Tb7C p skG_
int isOpr(char c)
On&\|;zt0X {
(wE/nq6}7a}     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
*_4~}{Xjq         return 0;3j'r;A;Hu6p[o&HA
    else
X[\;w(sg(s5V [$]H         return 1; t.X4DBP~
}
+cm,nvGm*L X} SM0G-~7S a)]
float operate(float x, char opr, float y)
tX"} m_ \Te {
*[HNv9CD$D5m4SO     float result;
z;D(vAx{     switch (opr)zY(](y#d
    {
j ` U@P,q%U ]         case '+':
CRU(]ka~d~              result = x + y;dol8^7~2f1tc]6m(j
             break;,sV dNj o
        case '-':
,|2c)Q7Nm+Ih8V              result = x - y;
Ujo,kdA)^'n%P5]Q/Q              break;
ruAN5WK         case '*': Nm`w/g]
             result = x * y;#Enf}'I"rT ibj kW
             break;
!Gfg1Q!Eh.PL         case '/':
2B7D(T T-Ad7?              if (y == 0)
8ma3K+q,n              {
^l0FxA0MNF \                 printf("Divided by zero!\n");
fN'D Lr8R[H                 return 0;
;K j ?m B%VCU#I T              }4| C/k\j
             else
gB(vq+rh9X+|              {x)M/\,P.uT)Jy
                 result = x / y;
*nB-|x%I F L2V,sE                  break;P$U z-\@ s5x
             }4g_TZ3i!a$@
       default:
jM2D9M*S\`%oq4}              printf("Bad Input.\n"); ~)J? |m3Nr
             return 0; Bc,{d8RF$m9z
    }
O#\7E0t'Q%}1}     return result; d@y7mYT
}    .ra%?7v*D K]W+J/w

u2fh(F*MTf Lr4n7{ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/p]DL,I+N+~p
{
Z(oA3eD     Stack optr,opnd;f BKJ] B'[*z5}
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;;}"b+?fC*[@ zo/g
    char c;
/YKWaCy:G2L(d H     char buf[16];:]:}x{6|0U9g Q
    int i=0;
,Fk/[~e%RU|     %k3Ea:W#bsI.k
    InitStack(optr); /*用于寄存运算符*/'uL Xp0si{;\!J
    InitStack(opnd); /*用于寄存操作数和计算结果*/
8yY7^/C$ID     memset(buf,0,sizeof(buf));vU%q8Y}aoW
    Vb.L1R OM
    printf("Enter your expression:");4q Jgj3Gs
        
fy U!]l'V aT5J     opr_in.ch='#';'R2kL7Fsf
    Push(optr,opr_in); /*'#'入栈*/
)j'GB1F!sMAu     GetTop(optr,opr_top);
"Af7NH-M^E.a     c=getchar();;Y Zo,^2Y5i^MOD
    while(c!='='||opr_top.ch!='#')s~|Y,D%Ui.aa#X
    {_"K7Xnc;AWrR
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/aDf N4X.\ U
        {
y7\:?o [ob{             buf[i]=c;
4{T\&^ ~L4Bq             i++;$f}*pi yx;hwem/[
            c=getchar();
,{y:_:K SO^(U         }
J M(i&o/wY         else /*是运算符*/I:W2Y6G c b}5M8wAN`
        {9HNYR]9zUS
            buf[i]='\0';
m,n!Tc#X*x _G}             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8@(g4_ Y|2o
            {$gu7{0ltZj(}
                 opn_in.data=(float)atof(buf);c!J}W3Z IMLF
                 Push(opnd,opn_in);
g/DpC)o7ZYn.W%h                  printf("opnd入栈:[%f]\n",opn_in.data);
9go(L7G&}o\                  i=0;9s.yO5wJ-f
                 memset(buf,0,sizeof(buf));
f(gCH"ROxKO x             } O&vyT I#Y|
            opr_in.ch=c;
| a/^2SmCez.iY             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/T(k3} ]*A8\M:G
            {
Wa%X?)Uo'?                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
-~ft;n/U g4F a                      Push(optr,opr_in);
1T7SDJ {                      printf("optr入栈:[%c]\n",opr_in.ch);g j+e`.t9M.d#KR
                     c=getchar();
J |\7\W*QC:gI                      break; J;F}5I`
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/E[h2r?qGe v _
                     Pop(optr,e);
6? F1o@SE                      printf("optr出栈:去掉括号\n");v;aU;d3m$a
                     c=getchar(); a\.p;[wh[`
                     break;
B Jp/l`#N                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
&e:t&Q aLu1Q/y                      Pop(optr,opr_t);
,na H6f%Kv{;u                      printf("optr出栈:[%c]\n",opr_t.ch);
XT!n$o g,t                      if(Pop(opnd,b)<0)
+fI1z$vsDs FK8_%j^                      {
:Wd O~,Y IN2x                          printf("Bad Input!\n");E a0m,o7MdU1c
                         fflush(stdin);
m3|$W"p*[ y                          return -1;
erN P'T8j                      }
M%K4`)N\;m ])d+~&`                      printf("opnd出栈:[%f]\n",b.data);-N.Nz Z;D jyD%E
                     if(Pop(opnd,a)<0).e5_gR8gP:mT
                     {
(} {!J ?ih*O;}[                          printf("Bad Input!\n");jxLpQOl@n
                         fflush(stdin);
D$c{2b m'x;G m$A8o5w                          return -1;
f'v%B @*Y!L                      }&Eq:@5g {8L]$l ~&a
                     printf("opnd出栈:[%f]\n",a.data);
9Aepp/Z4w!q;}                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/${:u4U6`y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
g$lhm4oe9K/L                      printf("结果入栈:[%f]\n",opn_tmp.data);
K.|*hSn8D[                      break;_%n;Mfs8m$b l[q
            }!EE [2@.o }&s_1v
        }O_gO%J1{:SJ;l-W;q ]
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7z~ u WA.d7g1^q     }
CBE/Kl`     GetTop(opnd,opn_tmp);U[.z;aAi
    DestroyStack(optr);
3@n Y-T2M noz:s.W8~     DestroyStack(opnd);U#p8VaY+uA"L&Q
    return opn_tmp.data;r.Qr,|2n&q
}#EJ:^;RN0S2Nu
;~3S8cp#N6lZ
char *killzero(char *res,float result)
T7xkpR*R/k {
;H!E+z+y.Rz9j:a     int i;!d'd H Aix O6Q

"m M(z3F$o3G%K     sprintf(res,"%f",result);
(ZUPQ+|5F%p     i=(int)strlen(res)-1;
iR t*i+]1DO.]2{4`     while(i&&res[i]=='0')8aO+X&h;?*BL#~
    {
8I mbl6fB2Jx         res[i]='\0';Z&]7Rm1C
        i--;
*Tm5?9~-vg c2B5GLeS     }?.V4d([`?f
    if(res[i]=='.')
6@#A7m2W6Dh#Gf         res[i]='\0';&\$_/]W4_1w.`
    return res;-u+z6~f9}
}
#@v@;N7MC(J JShH:?a+Y @2xsE;l u4J!qXg
int main()
S-je!c0]9ZEh"K3C {t ~.X4s r;XW
    char ch;
#w.rY6{;O{'N     char res[64];
s6o$E`#r6fk/B     float result;%D-pr-TRu
    while(1)
B1?F%D\N     {)D&p Ui.R4F*m(I
        result=compute();
:y4Ki1_k\         printf("\nThe result is:%s\n",killzero(res,result));!JQ^:HaM!j
        printf("Do you want to continue(y/n)?:") ;!^w WT/[(c#f#u y
        ch=getch();u-@d0vQ
        putchar(ch);4l G#iyz.MFI
        if(ch=='n'||ch=='N')
[{x+b-x6b1uA             break; wW xRN KK&f(zO$P
        else
\ L6Y)GgG9E6R m             system("cls");
mJYX O7g'VR{~     } R!GcQb-?2G
    return 0;m \L5u,o4w6b&D
}[/i][/i][/i][/i][/i][/i](l/qI1oUd

*Y5W&J7A.F1FsI2A [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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