捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
"};[ v p0Y8G4Xj 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
T$I];T8?)T@ k&v){ /**************表达式计算器************/
B'_ IT4yJ"u%v*vP0w #include <stdio.h>
!r/y4I(V9UT #include <stdlib.h>
)fehM$E!WeR #include <string.h>
}judS$O@6^ #include <conio.h>f L{ k.sdg)Rsj
#include <malloc.h>3Q}c$\1K%Q

o)AL p-[ s6M+Q6m!x #define STACK_SIZE 100I-cbL)E-E _^N~
#define APPEND_SIZE 10
||&k3t(e.S2v;e eX2SHA0Cb
struct SNode{D-F:?8R`({
    float data; /*存放操作数或者计算结果*/5S g|3vNLo)j
    char ch; /*存放运算符*/(|Rs |&T|
};
U;TQ8[h.H8H }\ w3RL
&O7nr+T(X m/]_ struct Stack{3Gw^$G"~o"|:V]9p
    SNode *top;
,R#yG U6_e.G     SNode *base;v;Sc"|#Vf![0dj
    int size; l*GD*h4E'Rg1hN
};7E$Y/NW7us'e:k$z8iMB
P UM\:y$BX'P4\
/*栈操作函数*/
[} ?G#~;]^g int InitStack(Stack &S); /*创建栈*/Zw&^6E6cc
int DestroyStack(Stack &S); /*销毁栈*/cVz'sAXQ.Tg)U
int ClearStack(Stack &S); /*清空栈*/
6Y[`!];T/sH int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
]W ]TS,?+\ int Push(Stack &S,SNode e); /*将结点e压入栈*/5~2~bwDa{(r$SM.F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/!r4[F"qb6?U.PZ:t3k
5N(f Zk)~a
/*表达式计算器相关函数*/;k jQt+i-Ckhj
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
j8y H8V*f int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ RExl$](R
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
]G'V.Le9[A4M float compute(); /*表达式结算器主函数*/;H*duJ'^EV ~.Fe0J
char *killzero(float result); /*去掉结果后面的0*/ (~L@9K%L*s'q
#j5y{k5p.VXG3f
int InitStack(Stack &S):t!`D$gX^
{
;NE:}%RV:R     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));#vu%DD+Q'I)c#YVL
    if(S.base==NULL)%t.XdzQp)T
    {
D6oD\^0}%Xe-qgda         printf("动态分配内存失败!");9|2u5s;g0K0\W.C
        return -1;:H}/i s-y R8y8l R
    }
y:N?%@T x6Dg.M     S.top=S.base;K'T lSN(h
    S.size=STACK_SIZE;
%N%\p Mw7|$j     return 0;
I1t?N3FcWvfP | }
"w9E)L}4|} s)tJ3e`X^
int DestroyStack(Stack &S).TW:s iU+UY,k M
{;pX\2K9wB8Z,u
    free(S.base);'r-oh,z0pw9`J
    return 0; ^k S~N~La'l#n
}
O"Ns `V}@ E;@%h hw Or w7|
int ClearStack(Stack &S)(F/h/Jn9ly
{?:sr2]l Y2S*Ho}
    S.top=S.base; m'T)V^:B6e!\c6rH*@
    return 0; S2H~0~/n
}Eb^3V?-I"B2e
~iVA)Wx0m2G
int GetTop(Stack S,SNode &e)
d5S;OR8O8f {dC G|:O!kI!Yi
    if(S.top==S.base) |ft!ep\1j'sp5hh
    {6W*Vj+H%l ZO.Zv
        printf("栈以为空!");i"KMak,p/s$t-Gq
        return -1;m3l I+V+]?o%~]
    }(o#Max.P`AJ
    e=*(S.top-1);[J[K7rPD8wH
    return 0;4TH{Fch4A#s;iT
}
)D*^'K t^ DB/?_G U%b
int Push(Stack &S,SNode e)$A#c7Kq ?4I)k4b
{ i'N4ycoV
    if(S.top-S.base>=S.size)Q?~g [h2}
    { sa`e1z4P
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));`6Y@ _"f9TUfP
        if(S.base==NULL)
e/`I[j:ctA         {'V kP\#[
            printf("动态分配内存失败!");Z'c#K4b]9Y
            return -1;
^]kXVQ:o         }
l.Rw(GIA#V9FS         S.top=S.base+S.size;#X_-yu9sH'RV#k1Kv
        S.size+=APPEND_SIZE;l7Q8TRW
    }
n(n,q.Lo     *S.top=e;
{0VGMN)T     S.top++;
d7|t `)E&P     return 0;
k,p [${5Gg }1`!Xi!ukc

&p$k Y qb#}@%x'[i int Pop(Stack &S,SNode &e)
%[`(^ QiSy {g } Hk M6\
    if(S.top==S.base)A7AGE%J3q.g ]%]HKF
    {
,n%cU3}!bT*Rh         printf("栈为空!");y;ES8{Crk
        return -1;5j3W fwO fP9d3e3c
    }+{*^`"_5N0L(r
    e=*(S.top-1);
0B t}+~)[9mTy@:n     S.top--;Ve1s7ay/@T7G+wTQRo
    return 0;
.K4R+V9i'X+XzQ }
8U%XR'P;{'s8X|%b#T9\ ^q&t S L:m!T*~(j
char get_precede(char s,char c))u%p4@pw iG#o}3E0^8Z
{
E$x!HUz T&e3_     switch(s)
!M$_y+PY w     {kB/N F)pz[
        case '+':                 
2db2FHC5y"we         case '-':
}L"[5\b)x              if(c=='+'||c=='-')
BOU S&aF                  return '>';u&d eo4_%c)H6vm,H
             else if(c=='*'||c=='/')6T1K0e/m;|MP}f2g
                 return '<';
[M2w_&e;Qx              else if(c=='(')o t2Gf Oy0G ]
                 return '<';
1ox6p!tV O.E R;QTo              else if(c==')')
SDW ^W|7O0w2B                  return '>';
YeC5T$d.ty              else ? Uw2uW
                 return '>';7i%? ?xT z }:lP
        case '*':
U!ki5s'~d6lS0E4A         case '/':7@?(G$Ph/a
             if(c=='+'||c=='-')K!HV'B3EV*a5Q]e]
                 return '>';k;ipJO
             else if(c=='*'||c=='/')9M~v1h&h!Y
                 return '>';
r%ND1c2FV.Yf              else if(c=='(')G6p p9d1@q&J)y
                 return '<';Y)W e3}f5F_ g0_MzE
             else if(c==')')&x]'X{3K
                 return '>';\}|[ UJ0r&B&e
             else
jRBE$x3F/yX#_a                  return '>';[+gh'gf;\A0o9\2e'|x n
        case '(':]6ju4[,W(BX$B6u8l
             if(c=='+'||c=='-')uw'J8@ch
                 return '<';
2U+WEoW:W4_GbF              else if(c=='*'||c=='/')6DP/eU c un
                 return '<';
!v0uL0o7Mkf              else if(c=='(')
,ZF&_m tm                  return '<';5^E*v*Hqt9wI
             else if(c==')')x"yT;l-w1ha
                 return '=';
atq2Ump6{;I$C              else)d-h}$AW)]'o
                 return 'E';
c!e/K Zw         case ')':2]([(s;doV#{y X
             if(c=='+'||c=='-')
5@$o0sNf                  return '>';w6| s#Wl*H;XVi
             else if(c=='*'||c=='/')#y#I1EeW.q(zr:E#H
                 return '>';U!jLiQg*fC
             else if(c=='(')
u;a u?u"`                  return 'E';
7r i d!M"qI8u              else if(c==')')
4kz#LIP/B(GgO                  return '>';
2{l4P1{M%}!Xw_?              elseoT0WA*M4R e)G
                 return '>';&U*L.qaS\
        case '#':A*B?)IT3dSk6m
             if(c=='+'||c=='-')-G!LVrF*b0H_+b
                 return '<';
#^B j&}*N!Et"_              else if(c=='*'||c=='/')
8~ G\W9\0Y"rtc                  return '<';
9~{7s PP6T Hm"k {              else if(c=='(')'tAl9o6Hk)FX i
                 return '<';
rZt/\Y.q              else if(c==')')
6f,O-S ef:b w                  return 'E';.RDX&ee;K[)y
             else
] ` };z7e'S7k l)|9D                  return '=';
{9mKIb         default:3k*M,|GQY.lR
             break;
&Yx2W+pG9P U5Az     }
:pi;U)YS0u     return 0;    (zY1H8nQ:B
}$Njh;eu\*d

8Or+``o#Kvo5M int isOpr(char c);[d4FI;b
{.L8` H!y2y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')@5UA7Q){h
        return 0;
.XmF\bBS     else
U3Y@-[k?Ug         return 1;
c3C8T|bJ }$R O r3w'qyAU
#M5YU"Y9jp)I/P
float operate(float x, char opr, float y)_6^"c @J5x
{yF P o]*h&lp`
    float result;)~oVsh"O'[
    switch (opr)
UPt-EcCs     {
'a!RD-x!mF;c%oq(D&@         case '+':
jb(@F5L2jE;sD&bA              result = x + y;
G!^;dGX;nn},q1w,Te              break;IT7MK(ZG
        case '-':
fu/M _x0A+a              result = x - y;
)e!bS0Ne RV q              break;
4FV%L/?2x b b         case '*': ? ym/e6B ZF V
             result = x * y;
A$aS2^ P~0@;G#xf              break;p6csk@ Pj
        case '/': g\] Q,{H@'A
             if (y == 0)1X a'H!x:M.IZ0O
             {
?r4dka                 printf("Divided by zero!\n");
+D*Ey v1p${O cf                 return 0;
fw&BR4c0L"z              }
@d1oXr]D              else_ [.u hoQ`
             {1B[@VB{q
                 result = x / y;
T-f7TtBy4h&E)V                  break;8j(xT&q9SR
             }
K_ IW$DH        default:
+_PI.J8ge gd              printf("Bad Input.\n");
2~"o\FT8wr5Js6E              return 0;P jJx/tC
    }qcTW0x*H D(v t
    return result;5t]&\ X-Rq
}    !`0CT+w0f6a.E
:j^#T.P ^s`9Z'J"\
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5D.O:B"T v"{ cO {0QIL]UnJ}
    Stack optr,opnd;:vl!k c*FS YQW{-O
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;FN%m9h2uS] R
    char c;
5B4vc@&i/e@     char buf[16];4i#] rd\TE6y/\
    int i=0;Sh.Os4~ cKgrY
    J_4tNo-L
    InitStack(optr); /*用于寄存运算符*/
1p^p+v\     InitStack(opnd); /*用于寄存操作数和计算结果*/
cEo:K$l|w {4d     memset(buf,0,sizeof(buf));O3[(wF]k^C!l
   
&of\y}5p@     printf("Enter your expression:");s$v(Tsv g
         { D0BUP+qS)]f/n
    opr_in.ch='#';
,l9f3NzT5N     Push(optr,opr_in); /*'#'入栈*/X/tS _8p+TQ
    GetTop(optr,opr_top);
b-A])Y;R$b     c=getchar();0\.t3rqE
    while(c!='='||opr_top.ch!='#')*tZ%Fwe _UT
    {
X&o9}2WJU|         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/C3mPZ[+Y
        {
5uaD9[x X[             buf[i]=c;
(T.O0v:rY+y-m-j/d;g'r!]             i++;R5`$A1TlI"\VZz
            c=getchar();
(^3FA_.a%?q         }
Y;K ry d         else /*是运算符*/S:O*@? k%P g
        {
MtE3| F*[&jr             buf[i]='\0'; FU2{-zJ$^&JA [e
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
)O`QFr ]`#B             {
{orQ2Fno s                  opn_in.data=(float)atof(buf);
rz A"X#Pb~S                  Push(opnd,opn_in);0S0J;N)j*j'W5P3A
                 printf("opnd入栈:[%f]\n",opn_in.data);
8H(j}/@'G                  i=0;;k6D:cB%?/} F
                 memset(buf,0,sizeof(buf));
e@ `5w\$m             }R#f8__ c'p1iLJ
            opr_in.ch=c;
1x!_2Q\a|v'M             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
)h!X)u(yJGO-V             {`5\H%i l[*Xl
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
,Mie$f3S7u l u                      Push(optr,opr_in); Q$awe"y
                     printf("optr入栈:[%c]\n",opr_in.ch);
1XYk9Ae                      c=getchar();6HJ0J4y1R F i"`:b;g5[8s4x
                     break;r#JQjm
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
[!j'M;r:@6S(w lP~                      Pop(optr,e);
zC#q&i@z(@K*F;U                      printf("optr出栈:去掉括号\n");
-D'k"hZ/{ u                      c=getchar();
3IZX4@!oN]/F [z!M(~                      break;
S$P S*OB3a6x,D                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ EH8^*|k
                     Pop(optr,opr_t);
6BmXR?5^B3NP                      printf("optr出栈:[%c]\n",opr_t.ch);
}+B ?;L4v3[VH                      if(Pop(opnd,b)<0)
Tg#p"a~9M                      {
4G&B8Gf.E?                          printf("Bad Input!\n");
DBO p/D}                          fflush(stdin);
%|O)|8qI I                          return -1;1JW#FU O
                     }
~%i wze8vF                      printf("opnd出栈:[%f]\n",b.data);A[L U.yS
                     if(Pop(opnd,a)<0),KE1}3p`Fr,~
                     { U @ n;tzqaR
                         printf("Bad Input!\n");
5R8g.qb5h9A[x                          fflush(stdin);(@]C]*L^?
                         return -1;
\ f$n;a n MVR%i                      }BB2_AC
                     printf("opnd出栈:[%f]\n",a.data);
~ X$m ZnA6{ y [                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/'|wyMI
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/en,je+`!l_
                     printf("结果入栈:[%f]\n",opn_tmp.data);
&p Pi P)]d)u y                      break;
t9Yo;X:}Ty             }3` {e4x'y
        }#qJ-EB |$wS
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                e.C*{%c akVu
    }
~ ER6fc2y!Z     GetTop(opnd,opn_tmp);H;Rn\!S |Y
    DestroyStack(optr);
kHa@6Er     DestroyStack(opnd);I!@e0zb'g!X{7E%q!~
    return opn_tmp.data;1RM]xf
}
JZI7J CM
'\.BE$H"J ^ char *killzero(char *res,float result)v{ \1J)V{l:F
{
$G B%~ }aN     int i;Cz|"{[v

hUTJZ     sprintf(res,"%f",result);JQ)z2LdU6iq&F
    i=(int)strlen(res)-1;e$QH:lVQ
    while(i&&res[i]=='0'):pK7b.M3F[@
    {@a xOuF
        res[i]='\0';!_(JVH-St
        i--;\x3g-CvF#e
    }
3Nr!}7t Vk @5OO0X?3`     if(res[i]=='.')7Xs6B#E-G8m q h[S
        res[i]='\0';
ee4S+Rn!gfO-n W     return res;$[%Q `9q bKn
}
Am VC@"T:hL H AF"l%D
int main()I8^\?|~{${
{x9[g:\`c!z
    char ch;
X!F'fv*xOk     char res[64];
%qB,duH;wq I0Y     float result;
y*c&QwG1dY%H     while(1)kH-]` n^(x)L t
    {
Z5@d@ y:M {y         result=compute();@`tfG
        printf("\nThe result is:%s\n",killzero(res,result));
Z.S+a*Sqx-R)S         printf("Do you want to continue(y/n)?:") ;+a g5w4X hD"qe.}
        ch=getch();Q+Y,f~f!V$T
        putchar(ch);(a&_#I$gR%Q
        if(ch=='n'||ch=='N')
p)rH5uuK             break;
5CAWA*T*WI         elseBNL3A#_v }"e q
            system("cls");K6P#g0D t8~aXf2I
    }
4y(}c&Q*mLF     return 0;
`(B-M*s7S&Jq;{0k }[/i][/i][/i][/i][/i][/i]
G8Ff5I Ju
'w#n b8Z-w nA [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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