捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.,|;~"B^c/{ v/W)z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4Q8G-PoNldl
/**************表达式计算器************/
grz["R8N @ #include <stdio.h>
g.\]#Q"V:@? #include <stdlib.h>
L+def,z!@d ]9C #include <string.h>Z)D`'vW%d
#include <conio.h>:x!X#g6A#p
#include <malloc.h>W[!f y uU&zQ
@lRW0g0g7U
#define STACK_SIZE 100:R+})Fb:BD NhV8U
#define APPEND_SIZE 10
G*\1tOW9iz Gfd
'D` _6Kp struct SNode{
S aBQ&i     float data; /*存放操作数或者计算结果*//zpPtsjva]
    char ch; /*存放运算符*/JG$y0@fl6h3u{
};
,M8Xlg7h:O 6P)ugSq9bJZER
struct Stack{Wp`q m%\)C
    SNode *top;
O.l/Q*D2Q2ny'? l     SNode *base;
H]jb&xI8z     int size;&py0ne5{+h/H W]
};
,af/i0wh I_.J"}
el-| i)Yd$o ke hh /*栈操作函数*/(UG:eZ @%oH
int InitStack(Stack &S); /*创建栈*/
?&{*^T&T3YH)l!f9_ int DestroyStack(Stack &S); /*销毁栈*/
0|~+}5l;y6cZ&NW*{(M int ClearStack(Stack &S); /*清空栈*/
"]+U h g d N int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/3H3}m`c n)u/Ls9vt
int Push(Stack &S,SNode e); /*将结点e压入栈*/vfAvwd
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
gd!`t/fY+z K%{
7{;e2W4RDU`*` /*表达式计算器相关函数*/
4Ydsk EZJlH6K char get_precede(char s,char c); /*判断运算符s和c的优先级*/~6Ko"B U-}3f ^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
(N&?7w!s7_3?f m-Rg k float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8?E)u%G(_6H float compute(); /*表达式结算器主函数*/
+_4t$c2H#W#nI8Ct"c| char *killzero(float result); /*去掉结果后面的0*/ %U9H*\4fJm:E)FQA

)~5I`Rn$`T%U int InitStack(Stack &S)
&t+iJK-CHO#e9v {]aMy1aG!o8u Fd
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));8Vv szh
    if(S.base==NULL)p.]Xg sZ*~ }
    {
'X0g+weWGLs#k t         printf("动态分配内存失败!");
_2_,ZC^*O gl'x         return -1;
$]@3SrDIF     }
aT@$| bP2]     S.top=S.base;m/w?Y1o"ui F$Sh
    S.size=STACK_SIZE;:t9l9jQl f|lK
    return 0;
b n+B%RE }
g LO#]_}t6X g&}sh"l!G
int DestroyStack(Stack &S)#ud B.iHA
{
7j!rYn jqz1^H     free(S.base);
2m.~ Ll!]G \0BC     return 0;}j F/@/Go
} CG'j$g{(z B
|;rI$aZ&F2W s
int ClearStack(Stack &S)
p i6q{nOz5h6H {&V}~i#[ O Q2g ^gY
    S.top=S.base;
%HTufPd     return 0;kE_ pQ'hL^(N
}
1KD)M$j+hb7ct k} "@}S5Y!w8{NzSv&H:N
int GetTop(Stack S,SNode &e)
*D#R.W^ n2U+X {:s"Qy?W,Rn*I5u
    if(S.top==S.base)
^uJ5H*Gbp     {
:o_kx[D:g         printf("栈以为空!");
4e @%Br$? n.Z"N         return -1;
8|@5I7Lkt     }Ks"g"kr A?D
    e=*(S.top-1);)pi.o%C1f%\i+K3] M(E
    return 0;
$l:r fn,V e6i+F,X ~ }'Sw d D~f:KgW
zWb^ b4Nog
int Push(Stack &S,SNode e)M _FA/a8`@L/?pD
{
\]dP$BH,tB/Q     if(S.top-S.base>=S.size):_ B,^Yt,\
    {
T+n [ \ X         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
)L*HoS/k.PYj^kw         if(S.base==NULL)MU2^\/]K R
        {"MkIX1D,^Af f
            printf("动态分配内存失败!");eU*w/l$UB+y]
            return -1;
3s1j?8x6})F"l'CJ         }
"`w6\0dR         S.top=S.base+S.size;da1qi&MH"Q!\'C
        S.size+=APPEND_SIZE;
C0l@0l:WB     }n.w W+n3pU W9~"R"H
    *S.top=e;SYKF~Pz
    S.top++;
u6OV}`6~ \0T     return 0;
;jp/wV4b{|Pd }
4Z!W0gjb 3Q;y |:VW3h%Xv
int Pop(Stack &S,SNode &e)
f PD^kZ3q {9M|nc2is z)` s5|G
    if(S.top==S.base)
Y.Z jd.o)s     { x4krw:th4E T
        printf("栈为空!");"ezI!W0vv4G
        return -1;
tw%QkP!v*F Y ~     }6q,M CPJ&c2afr
    e=*(S.top-1);
;L ^KK$M3e.h`4M     S.top--;
ER:{x X#d     return 0;
q7t*p2Q ^z7Xt7} }x%bU {UC X-p
AJ3T)W2N&f/z]
char get_precede(char s,char c)OL1o/Ug.]v
{O4d R{p0NG
    switch(s)t"_O$km?$I?0x
    {
J }6Bbh%|;d-V         case '+':                 
V|;@4{0v%Er6P2Lm2]         case '-':
8}%nT!` Ub U O.\z              if(c=='+'||c=='-')
'f)v)Q2Tl*j                  return '>'; H%r.G7qIZ'S7l/I?f
             else if(c=='*'||c=='/')
l4h{4r#Ys                  return '<';
pB0O#@ x*T!T              else if(c=='(')
(frdwg&`e4v                  return '<';
&^Pus?N              else if(c==')')
eZbn6W3U                  return '>';^d8K EtP
             else
&ju!o]2F%A                  return '>';5I ZJ u"i ^~%``
        case '*':9mUEI2G;g/G'N#n
        case '/':0yU*bE,{}G
             if(c=='+'||c=='-');{*Ug7}:n
                 return '>';
,q9jX6qg4Gz B              else if(c=='*'||c=='/')
B{.H/dDb,c&X                  return '>';
Tu6@$}{/D4XV              else if(c=='(')r W0O(ayo
                 return '<';!m1LW8GO_
             else if(c==')')Sj;r re
                 return '>';9c"F4OLb{q+T
             elseJ+NR*r1_8^
                 return '>';
rug1S0{3nw\ ?_ e         case '(':
E B x Y,u&d^              if(c=='+'||c=='-')
:Fw+u^#C                  return '<';8k+l9aT#L%hS!Z,t-HN
             else if(c=='*'||c=='/')l J\T8S
                 return '<';o{'_7?)S p.X
             else if(c=='(')2sam+K2u \ E ?R?
                 return '<';'E@od7W
             else if(c==')')^#n?i{F9};yV
                 return '=';c)PA?d)B
             else$MhL4tdlr B
                 return 'E';
&sN4c:tk3y,|8`         case ')':
"zn${4Iau              if(c=='+'||c=='-')
Kw9K8f#[ G/O                  return '>';
Eq7x1RZ              else if(c=='*'||c=='/')
;F'S'r3snB                  return '>';
$g3@s m4~o3V#fo#h$S              else if(c=='(')
)L6ha:k7d^wr]                  return 'E';W[y3H5|S5yF e
             else if(c==')')
H _mAO.@\                  return '>';5qwUh)G6[ krq
             elseCt1qCh,S8X]
                 return '>';#EzsH7V9@:y RN
        case '#':
5D9oL P G` F              if(c=='+'||c=='-')Ff9OY7fi*x8K
                 return '<';F&}-X#O,yL|B7R
             else if(c=='*'||c=='/')
7}b M b g/Wby)l.\                  return '<'; C? HF1I*V
             else if(c=='(')
{O D#U!`                  return '<';
`Y0EAc"xE              else if(c==')') ~7[4bu%qti
                 return 'E'; p6g1}9U-a3f
             else
+J'om*Q+X}&j                  return '=';7t"}+tB%A
        default:
V X q Dxm/u              break;e4MXq e
    } g1Ny DK
    return 0;   
z s!k*E2xTM#M2^ }$A0^aE,P9mWb

#FgPAribs int isOpr(char c)
&j-_P:Zv(B {
0kY ud TiT5Y b'CTQ${'h     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
-N.nrig0T ~T mK         return 0;
EfX*Gu{     else
AT!qj6`         return 1;8JWs Ie+GJh
}
IY}e/in:^
t6yc:e1h float operate(float x, char opr, float y)GR4qiq P}K?*M
{
f4dM+Qs(U     float result; iy9J6T/s*P{ l
    switch (opr)
6`w{9nv&|     {
Ou/dJn1x`.w3k8i         case '+':
0` F7WZb `2O              result = x + y;
:S Q |\(\bP j*d_              break;
AVoEV0a,S+y         case '-': NEX`;PbR!N
             result = x - y;
~M3F+jIE&u!w              break;
A&m[Y,q&g9Yl         case '*':
U?e7G0R2tsS&Eo              result = x * y;UIW&TR] W
             break;j;p#ksa X
        case '/': agh)jzb
             if (y == 0)
ta&W^ O||+Kj              {
u4h~"yv n;^F0S                 printf("Divided by zero!\n"); P/v0[ O6n
                return 0; p%F!p.N^ ~pi_
             }
JRm.hz u              elseM/ll$?g4v
             {2P9FA]v3kT.k'OAX
                 result = x / y; CH:R)d ~)\q7]:j
                 break;#SC`9b?Jf H,~?$_
             }.J7dj.x!tA{ l
       default: #\0zH&I8pjc2SF
             printf("Bad Input.\n"); 0q3w2D;~D3[3f-i o P
             return 0;Ap8?kt7j4~0Xi!G9_
    }
OS} H }uQ     return result;6nXF3`y+wK H"Z'\
}   
*R"]+tp:F;u(LgW |
j2F ~_,bOHV float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
*s2{r gE1Q {]] Q [ j
    Stack optr,opnd;u Sg/R)Le
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
#e-{biA     char c;P3TN.MvwUjm
    char buf[16];
:zY%h*MUfH%X(Ag     int i=0;s.s*N%f!h
   
6]%A*A!TFa:D pv     InitStack(optr); /*用于寄存运算符*/;fstENM
    InitStack(opnd); /*用于寄存操作数和计算结果*/T2V5B}"L#a
    memset(buf,0,sizeof(buf));f~(x-W7Xg Bb:c
   
R#]-Lg[^$v     printf("Enter your expression:");
(|?b/b4Sn3f_ Oyc         /Vj!_}kwmYK
    opr_in.ch='#';
+SG%V*~+HEj     Push(optr,opr_in); /*'#'入栈*/
7Vy/}H(o-A5X"}W:l*m     GetTop(optr,opr_top);
;Sv9{vV|?-bML W     c=getchar();
*`@7Dzmx#k     while(c!='='||opr_top.ch!='#')1k6plu3A'^L9I"g
    {4YFaf(fU;{ u8p
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/FNtZ-p1d7i3Be!i         {
j9` h~&d&|e [)^ _             buf[i]=c;(b)P{)O*_9y~
            i++;+f2P%ze!L3Op
            c=getchar();
&{2?z#|i4Ok8qk         }c[6TY:c@"Jp?H
        else /*是运算符*/
P$PN#Vi ucw0dN         {js#C,Hr |h
            buf[i]='\0';:b.NdO4}8^!KBS
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/&Z-K7Z#U4|yB1^
            { Z,E ?'F_!U~|t
                 opn_in.data=(float)atof(buf);
pC v!P\(pQ T,r(v q                  Push(opnd,opn_in);*J_5\*V.CNN
                 printf("opnd入栈:[%f]\n",opn_in.data);~3S9sz6?/nq
                 i=0;
*w1xLZ#lN                  memset(buf,0,sizeof(buf));
K.f7m]j             }3j-ZJf:L gb"v2K$F
            opr_in.ch=c;_3y x)D R2u$];u:D&I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/6w'gjD@UL y.c
            {
ft*I _r2Yd                 case '<': /*优先级小于栈顶结点,则运算符入栈*/'s sq|%`
                     Push(optr,opr_in);
T_j:N e{                      printf("optr入栈:[%c]\n",opr_in.ch);
Z'M-Zv`3DS!?'mF                      c=getchar(); vZv@*^P'?$\
                     break;
Lv#Be(\8}c,Wc                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/)K0Vw4v%af P9Abj&ml
                     Pop(optr,e);
9dp@ [Xl                      printf("optr出栈:去掉括号\n");L`5TbI ]0X~
                     c=getchar();
$YB;y-|} j/c                      break;z7Lx`N]@+f8b
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
!\({]H@f+\3KO                      Pop(optr,opr_t);a0dF wM+~sf
                     printf("optr出栈:[%c]\n",opr_t.ch);
m&KE \ ~C-X)E                      if(Pop(opnd,b)<0)})?$m6Bz
                     {
NSf u3Hw-a                          printf("Bad Input!\n");
9`-hwo H                          fflush(stdin);
E6N8g!`3I']k/~                          return -1;
/h*x |!I8W2J.Vn@                      }?!r*K(A9Y{2e
                     printf("opnd出栈:[%f]\n",b.data);
j uda*D bX!{ub                      if(Pop(opnd,a)<0)
K qOl{$]u+jO                      {
+OVI9Iw7b:S                          printf("Bad Input!\n");[l`?O w
                         fflush(stdin);
Op\.CQ                          return -1;"P$gtg.w
                     }e*M \? N-So
                     printf("opnd出栈:[%f]\n",a.data); C+Mch7q,yt7[
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/I!{+nWuB
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
Of6h3r1kT9Ek4n;Z'f*Sg5f                      printf("结果入栈:[%f]\n",opn_tmp.data);
Y X9J_I7c.JC                      break;
+[;` i+s/l+`_,jQLR4RO             }~\!_4If%l(J4pU
        };[LXEa h
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7l@ h&s-x0AE?5Z)am2n     }
.S}*]o G*Ad!q     GetTop(opnd,opn_tmp);
Ad"Yc B,YSe0kR     DestroyStack(optr);g'v:_{9FV+_.U-q
    DestroyStack(opnd);
)]#\'G%{_J@*S0u b$K     return opn_tmp.data;
$jIJ0sHp d?.? PZ }
-B/n3V&AO?1Zd1b
9db$Rl;? char *killzero(char *res,float result)
s8Xz'zh!^ {P|1bR@&SY%K
    int i;;~cc(Ex

2\] d$K*ckF i     sprintf(res,"%f",result);;A dKpp0Cm
    i=(int)strlen(res)-1;
&y-WK]:l&xv9E     while(i&&res[i]=='0')
%XTz#i}     {
*~&j(_P%YO%K         res[i]='\0'; A,_,i7R }}\r2iG}
        i--;wTZOB)g
    }5j1o} W$W y0]
    if(res[i]=='.')
b2{pL9sY9Ic         res[i]='\0';SHM7DK
    return res;j.d.ym0x9u
}
'VhR L&@%d
!t7h q1x7ctA int main()e#F;Q,}"s
{
t'Y5{Ldj,U     char ch;
"]\5u4T,i XF$m     char res[64];.wU+r x1KkjG
    float result;w(BN!u3QA
    while(1)
b b1i2yY2VL     {%{gv!H[
        result=compute();
}4Z0M%|4s~         printf("\nThe result is:%s\n",killzero(res,result));UQ;A7C%O6q:]&vp4K
        printf("Do you want to continue(y/n)?:") ;m:`2kv1R\
        ch=getch();|M)e mRY
        putchar(ch);
D rw4T!`bs         if(ch=='n'||ch=='N')
hJ^.w~ f%DL             break;
J X3F8k ry!c:s@         else] mM7^xH4}
            system("cls");4f@6PK GGg
    }
T-M4n0yI?%plbt&Y     return 0;*p]0y {!A#b
}[/i][/i][/i][/i][/i][/i]7xp%j-r8fS0D

(\:}cEc,E n&l [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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