捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.EL,w6b7]3R
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6H^0z"gDUCd /**************表达式计算器************/3ZV7} K],l/m!a&C
#include <stdio.h>/d\b"w/f6tZL2^
#include <stdlib.h>-KMefQ\
#include <string.h>@}9|'@ p(hg1Ue
#include <conio.h>
MfM{i6?%EN/Q #include <malloc.h>
"~$a {-Xkf6h&Nk !ie:MXA0r3l D
#define STACK_SIZE 100
"X2o6U? Z #define APPEND_SIZE 10:kbg,@%l?-?'\

M|xB)u-O-H struct SNode{
E&?\0k6O6X!XHXY     float data; /*存放操作数或者计算结果*/
F)c5v[E#F7?     char ch; /*存放运算符*/
yzj*Ib5g:V P };Vkh/c9|3\i
,`)EM(x:L6g%z Y
struct Stack{d+Pl ~)T-d/@
    SNode *top;um r k9W Sw(D{.Q
    SNode *base;k2u0s9H4X I4d&bg
    int size;
/@2o4y:e4I4O D:~(O };c9c ztV@;FE

8r/a&rrrpHN /*栈操作函数*/
&QT IP4| int InitStack(Stack &S); /*创建栈*/
/q(b3R4h9z E int DestroyStack(Stack &S); /*销毁栈*/
"~y U?0Vc/J k9g int ClearStack(Stack &S); /*清空栈*/
@ ZG-AX int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
;qM4}ky R"o&M_r,Jx int Push(Stack &S,SNode e); /*将结点e压入栈*/~&`O$?.nO
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
T'S#ra&[ ?bE#l !Gf r k:P3QbS
/*表达式计算器相关函数*/Zr;@[;Hc L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/a9G!~ C2Y:`
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
XW8J I ]}9_ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ ~&g L-c2N G
float compute(); /*表达式结算器主函数*/M/r] jmJ%EF
char *killzero(float result); /*去掉结果后面的0*/ :F;X Ak3R4s(l&u

IC?/@1c$jte_ G int InitStack(Stack &S),u T7h3]$KS
{
+c ?^idxX     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); b D!g9gc-J$d
    if(S.base==NULL)
]#R%w_ liV     { W[*n p$gz
        printf("动态分配内存失败!");
&w^w qG         return -1;v!k{AM1n+B\8Pz t$S
    }/D9K |)Y,xbQ0K_
    S.top=S.base; h ? pzg.K$q
    S.size=STACK_SIZE;0R n7|%tzI
    return 0;z7t7u/l+CU$R
}
4Y3Vrgn
&pS^P,Z?1y(_$_ int DestroyStack(Stack &S)
E}2S\XE5t[.t"j {
5^)?+V)T$D]     free(S.base);5T|npdgv8}
    return 0;
Nf#KT]U6V }
z;GSu E1?~,V]4| Gv!e@-h!x
int ClearStack(Stack &S)
Ua2U#dR0a X {I }(qDK!| [
    S.top=S.base;B#|F/O#Q2z y
    return 0;3s/C3LOK@W1M
},U)G%Oe8pC3\!} Q0i8W

gKnO{%|p8| int GetTop(Stack S,SNode &e)
1R!Jn%Ik lO gH8RY.u {6p%JGS:l"X,l.l}
    if(S.top==S.base)
)y5Mq$E B j*F     {
!d|`(PY(| YCh-H:YN         printf("栈以为空!");
E s7L$dLX%i U         return -1;,mr\fh7hb
    }9^` E-YI%O
    e=*(S.top-1);RS H"E G \|`0i
    return 0;sE0_ e6[#tH5N
}
;\"M[6f-a
R&Gs1OQ\ L"GK int Push(Stack &S,SNode e)
T-_ t$e&p Mk {
tJq;@3f+nG!@y     if(S.top-S.base>=S.size)5[;bsta-l&fa
    {+s j`FJi JC'XvO
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0H lR4v{ P${]
        if(S.base==NULL)
T&Sp(LH4t)w W(^         {}9G3UY YwK8h
            printf("动态分配内存失败!");
o5k Ij ~H&GTx S             return -1;_5or3`!b3W
        }
`1N|g`d         S.top=S.base+S.size;Yywso vo9{
        S.size+=APPEND_SIZE;:Pw\o\ H
    }2XVKKl6ZuJ
    *S.top=e;
jvUQ)tY7B     S.top++;.xy n/C/Srr"I
    return 0;
*w~PvFc4sa6j }
V;Y{&p G+kgeX5Q1N8\
j{9}!YI"T^[ int Pop(Stack &S,SNode &e):l'P R1R"\SCf'v,n
{#|#A0PFCsX\s
    if(S.top==S.base)-kYh"Ifz }
    { D{ I+YO'@(a\*ff
        printf("栈为空!");[!t}6GA-S'T
        return -1;
)](zH o }     }
lj;H*F _(Hx     e=*(S.top-1);
W]"av&AOCh     S.top--;
w;R d/g1P     return 0;p9~en2u Vm-u
}9LaO?n8I0x

:H'\;DYq U char get_precede(char s,char c)
G7dKil_6`8H {
6YC:lQ1W     switch(s)
x2J[Ui+t!}:rr     {H'z/?z0V+Xw8lVfo
        case '+':                 1W N2U"O,e3t3y.NR
        case '-':
3eL z:Q/t.g8@              if(c=='+'||c=='-')
,Aq:k i)z$x8_*~0a i2K                  return '>';
:N-q[8QI)x              else if(c=='*'||c=='/')nSWo#J f cC
                 return '<';?wZj[}#K
             else if(c=='(')
5QV3v^(lf6R                  return '<';
2am X-m![6]'yS*H              else if(c==')')*lQ~/M\7i4j UI1A.B]
                 return '>';
8^!tk8Wc(WS|JI f              else cg1j5R-i9Y)\3d
                 return '>';
t t1ziv         case '*':
?7J5G:TK!m;~l         case '/':F5W4D5Yw+{Jxe
             if(c=='+'||c=='-')e#O f6H5V,X w H`2O
                 return '>';
nJ!F v&^              else if(c=='*'||c=='/')$ws{Q,C;eJ{I{
                 return '>';q-am;u+Lh_Z g+uko
             else if(c=='(')
Y,qfvJM                  return '<';
4Qk Sf@7a              else if(c==')')(Q0KFe7lf$T
                 return '>';v0D:w)A_3Q9F N
             else
Y%u-g o,Wz5k                  return '>';
rcGAm!vC         case '(':
:gT(?.SH.dh\G              if(c=='+'||c=='-'),A s"u"f.V7i4J*D;z
                 return '<';
l%D;d;y0Zd*Oo,UerN              else if(c=='*'||c=='/')0a"H)_0?-x,gTi
                 return '<';
j*l#X`d!`)t              else if(c=='(')5s$F)|#u O-N
                 return '<';,t9`9F#D8OFB1m
             else if(c==')')%GL$Qbx
                 return '=';
]J:Df0|:y-AU&v              else
}U1H U9\s                  return 'E';t&T6DWf7M&da
        case ')':8_at@u
             if(c=='+'||c=='-')
y(W@1Q v EK                  return '>';^k}^ V5aZ$tD
             else if(c=='*'||c=='/')
^6}!U;h0?b,x#P                  return '>';#biL] qYy w
             else if(c=='(')
/NH0ZwnQ0qj                  return 'E';4O:Y!~g4V0z7M7F+yt
             else if(c==')')%rJ9^ Ak ~
                 return '>';b#K `le&|
             else-K.L yl,SM
                 return '>';{%I:GP7c%Ox:OS
        case '#': v(`mU[Sv2d
             if(c=='+'||c=='-')6{'z,a c7M,E1h
                 return '<';
1A/vz8|`9C-R$o              else if(c=='*'||c=='/')Tp+M9pm }6d"O i
                 return '<';!`VH+n/R%{
             else if(c=='(')
E?5`p z u                  return '<';4}sd0mb:|rK
             else if(c==')')
CG&HJ}9} N                  return 'E';:j6[ W/Iv6p
             else
4ih];Q)ep{5_                  return '=';
#`9V0KTb}.laZc         default:bO+u6Q5l,i
             break;9n akZ.W5?dAs
    }e&Y6p*HuK`
    return 0;    /]+T?.?(I7{8F
}6S \T&ghiV-se

'c iB7Zf E-o int isOpr(char c)
.LPA,_0m ve0Q {
4\'h \'pc X;v     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
^ f6{ Azmt         return 0;;p!T7m T ?2w&dj%P
    else
$oZ;Kc%n3|+R         return 1;
:i X+u%Ja*M4_.E*Q2o6x }
{Bz"P2]BT],a tg u7iGpy.vyI
float operate(float x, char opr, float y) B8k4I F6C
{j3x[O9F)W2h
    float result;
0~4j0F4r]     switch (opr)
(Q,|N Xno6q;rh     {
M uS;~IC/\^:@         case '+': *L3\#fH3N!^.ll#m
             result = x + y;
NI-}Es,Z$f4Y              break;
3I$xG,C,Y         case '-':
bp X1\L%a4Y&Hz              result = x - y;,|dL8};[3L}rO
             break;8`GI G)t
        case '*':
N~l/W7H|*cL              result = x * y;0o6C,z;Q5OUp*z
             break;
v/] sq4Mfc         case '/':
)GX b"kS5P$p[              if (y == 0) t0Y1x'x4r/f^~n
             {
R Z Q3M0@!WO                 printf("Divided by zero!\n");fGL1q5eTsYIQB
                return 0;
n,L3N$A@P;\?b              }
5^hbF%E2c              else
$c5TZ;P:jf2M              {0H?C tf*nR0{'g ^ s&j
                 result = x / y;#cJU;J(N#j
                 break;b5Cz&lB3j.W4a%P;j P
             }
8w#iJ&l5Q+e{        default:
/}m v tUF9~V              printf("Bad Input.\n");
R.o9z!j PWY`"z&P              return 0;%L;L!D]l"K [
    }0l?!mzh a!w0^
    return result;
\xV6V&Vc&qX }   
\7vN%L$L 4Df!k)x dQ
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
l CtE%oc~%cW {
Ig{.K9g$v     Stack optr,opnd;:sTHtX@
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; T#m!\ R+j5B
    char c;
:Ab6J| PD*q(c5}Y     char buf[16]; V$a-x e5Xv
    int i=0;s)`G#l2ia
    .IM;ut*ACv:Q
    InitStack(optr); /*用于寄存运算符*/]*^A!cHp
    InitStack(opnd); /*用于寄存操作数和计算结果*/)i)vj | HK
    memset(buf,0,sizeof(buf));
Jj9L&K/e*~$_#T4P     g0t8X\k$J,|_R
    printf("Enter your expression:");
F8V QE8d-VP         
~\K P2lyl3u     opr_in.ch='#';&qpe%r'|1R*f
    Push(optr,opr_in); /*'#'入栈*/
fLa1J8{     GetTop(optr,opr_top);
i:^1|6z,c4K%^/^     c=getchar();hN'F0rQg
    while(c!='='||opr_top.ch!='#')
!q4?U2f?1YRZe     {4^#G*J&AQ.@
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
m` EN+dm#@.gH         {
6bSB Xm(S@!JoR             buf[i]=c;$La0v Y/hH
            i++;
(`f^tJif             c=getchar();r\Y'O%n2Uz
        }i} b&j(N Z0Gk}"J
        else /*是运算符*/T1U ]|3[J&}
        {
PCt'V2YM-uc             buf[i]='\0';w6\mA1]"RF aZ
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/9kwp!N)s
            {
/Y O2~pA1{ z*Qw                  opn_in.data=(float)atof(buf);
N |;Ga ?l]                  Push(opnd,opn_in);
O6V-^&^qW%^l(C.CS                  printf("opnd入栈:[%f]\n",opn_in.data);
Z5s3DY#VW&GRT/[                  i=0;$VR/`b_p
                 memset(buf,0,sizeof(buf));
0_;}aJno             }
^p)]*jZ3t             opr_in.ch=c;"hA ] `IN'~0R5T
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
(bF%]m,Ck$MYN             {&o.Rz w_].Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/5t8a8z7G(`(H$t.E~B
                     Push(optr,opr_in);
u;Anob)n-t                      printf("optr入栈:[%c]\n",opr_in.ch);1lk$ME,aA
                     c=getchar();
z(O0Mv.xa _:W                      break;
&M4QHE%DA$\K]h7H                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
7V8a j0w+SX\#D                      Pop(optr,e);
tlDcmv4D                      printf("optr出栈:去掉括号\n");
C1qW6e4V1Ed                      c=getchar();
/l"Q9kj['J/J                      break;?#J r9{I{'\
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
&c&wS,M9G;wjTB7C                      Pop(optr,opr_t);
8|!a0n X}y3a                      printf("optr出栈:[%c]\n",opr_t.ch);
](KE1o,]S%i,` T                      if(Pop(opnd,b)<0)
U6d4pK(Li,k                      {-d3_;~Zp(W*dGK C
                         printf("Bad Input!\n");e J!O+N6Z~3R;?
                         fflush(stdin);R8U,{ XJK#UJ!k
                         return -1;\(P$^{ Og%X
                     }LF8vj7Lw H H6[1T
                     printf("opnd出栈:[%f]\n",b.data);
cNE#n$B1L+U6BPOT                      if(Pop(opnd,a)<0)Rds1\W4x-u
                     {!_Rg k,J
                         printf("Bad Input!\n");:Y?Jv({+}oL
                         fflush(stdin);5x"TQ PX-e3w#I
                         return -1;
-wH\g7yU g pM                      }Rh C,y4P{I)f
                     printf("opnd出栈:[%f]\n",a.data); |9J\T+ZZ0|8P p
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
jN5a-V]/uLb                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
E0q,c |.|[                      printf("结果入栈:[%f]\n",opn_tmp.data);
C7[X+h!IY@                      break;
\C KJ2CgsH             }
kZ-G#P8z*aC         }
'YzyX6FV v&B         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                "d2W[7Z:@:w oQ6N }
    }HXH-L`$Mz J
    GetTop(opnd,opn_tmp);
vi@o$U x'Aw     DestroyStack(optr);
E4kvv {7k:{     DestroyStack(opnd);
%q(W8c['@7fI     return opn_tmp.data;
nS+I C] y'U*UU,d@ }
`1YP(r3I/s e6Q
'm'J|$SP0Rm0}%S#p char *killzero(char *res,float result) x-ql?ev ^,T
{
m5_7s]IN4op(u     int i;mj'^aUvQ
6y([ W+`/_zE Z
    sprintf(res,"%f",result);
zd)B NBUj+r     i=(int)strlen(res)-1;(Lz4` x~)l4HbyJ
    while(i&&res[i]=='0')
&YR f;y/J M(o     {
]]@Y L ?4B$@         res[i]='\0';
v+n*cwje:? ^Gz         i--;
+f#p U|Qx     }
i hDP V7m G     if(res[i]=='.')
NUK/m&BJl h)kr/\         res[i]='\0';
RE@z*`g     return res;K ahbD
}
/_Jo S3E7O o!rcO #S&_ ~P lSz
int main()
,U~z7w-C {
0l5o4]2qHwf Xj     char ch;
T,eN-SqwO Hi     char res[64];
R6e)IRQ     float result;o;rRP;\HOV
    while(1)9{nyX)u"?$zy5p ?*t G
    { y+D ]\1x)y h1GML }'~
        result=compute();
c.R#d2j9B*e Yp         printf("\nThe result is:%s\n",killzero(res,result));
;b/Vs[!BPN5F         printf("Do you want to continue(y/n)?:") ;
^@W0uo+C         ch=getch();
|T v4{S-ye         putchar(ch);
-?bA { u+s)Og         if(ch=='n'||ch=='N')2F{D9sCO.x
            break;[fH4w4L*EWpu b
        else
|#G _2Sd AkwA0h             system("cls"); T@4`M3Z4V'Y
    }
8MKwk1WoT.J*PH/K     return 0;]-tDE"]{"t`R3n+K
}[/i][/i][/i][/i][/i][/i]u'b8qR,Yw+P
'jkLwA6RF*B2k
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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