捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
P {J#D @1ECG4] 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=I'}!W;h2{;h5V
/**************表达式计算器************/
~$E\'E[ #include <stdio.h>
l*nd8FjCD+ty #include <stdlib.h>
v2H4i:N \(Q5^g+@ #include <string.h>!D:JT3Ct"s0R?8o{
#include <conio.h>pdB\0^~y
#include <malloc.h>!R[W7QY
5qHw+tZ+l
#define STACK_SIZE 100
XY'{1loU;q+x #define APPEND_SIZE 10S;F"s2hNX|;P
`x d7I#HB*UV0QT
struct SNode{
MhMP_ii![(i9]     float data; /*存放操作数或者计算结果*/
MX/P+[+Q],nTJ7R%_k     char ch; /*存放运算符*/
~b,hS(~,N6F:}&l[ };
_WI/JX9@ 'L;Z.D}(]R
struct Stack{
\Q$H#N;s h3s#^     SNode *top;
*T m;F:X u E'o     SNode *base;FIW+O7JXyc
    int size;Op-w'I W*Ey"ldq5F
};
L,V^'J M/NcA#Z
"a}z9X].b]1pp*l /*栈操作函数*/
E,Z9y2SPgS;k"T$ua8v int InitStack(Stack &S); /*创建栈*/
S1|j8t/y} I int DestroyStack(Stack &S); /*销毁栈*/ ij U Ae7Hno+bO P
int ClearStack(Stack &S); /*清空栈*/.z:GZf7P'k^
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/o Eh}0zv7he
int Push(Stack &S,SNode e); /*将结点e压入栈*/
?3[(UK!zuM int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
;m#Y(m%I;] Q-u\:h
e-LM}^&@,x~N /*表达式计算器相关函数*/NeQ+I;d!}
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
L}X4L2v"V\ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/jAl#s6b
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/:B+RV a%J\!o v V
float compute(); /*表达式结算器主函数*/
7V$U/M J hg B.?O char *killzero(float result); /*去掉结果后面的0*/ DLi_g

v1uU5A$i(F)}5g&Y int InitStack(Stack &S)'[3w eV3eWvO:g
{K+vBzvn+l
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/F.QxtJI'Z     if(S.base==NULL)w*k!n@8f'kj9B;tV
    {
(_ Xv{+J         printf("动态分配内存失败!");o4e P W;e`X
        return -1;
2x:c;p#rG;`"N7oO#T!X7d     }
j/L d{xb[D5M[     S.top=S.base;.m;B1YPpK
    S.size=STACK_SIZE;H8] F t6I#WSE;f!`
    return 0;
6^0f&M/UpF }fT-jk&@4W%KB2x Y
-} r ucK5\Z2DA
int DestroyStack(Stack &S)
C;C`^lS {
`%h cZI O     free(S.base);4^%?VT@#h
    return 0;Ko5TGt$`Q
}
aW|2v3^ H"i.P
8wV"K l `T Xz.I int ClearStack(Stack &S)
S.j.Ba+F|tR {9vj[b!lUL
    S.top=S.base;
O/L _+|FOG+V'Z     return 0;
YdJ*K2j }
$G o^)KG*|
{ _Gg6fqc"j0Lx;} int GetTop(Stack S,SNode &e)
A ADz%P4Bc0J4s1bN {T Hb5cY.vf A8Y
    if(S.top==S.base)v;],m&S*J)O&IU
    {
p?iF MyidHlzx         printf("栈以为空!");
O1GSN2h         return -1;2@JS5I&I `^,KA
    }
&o2prY${cq{     e=*(S.top-1);)vt CHT6qt.C\
    return 0;
y"|(? x3s1jb6S }
H M6^rz|\Z
"u vy9m1qMhP int Push(Stack &S,SNode e)~9Us5U!^.[
{r"W R1mRJX'F1\
    if(S.top-S.base>=S.size)MXKk%h
    {
$VV;M A^+w L/^         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
K%zK1V(l:d4h I         if(S.base==NULL)
!d\BOgK         {I A(ei{ K
            printf("动态分配内存失败!");|| p(CQ Q1O1b
            return -1;V,[c,N*e0R&w
        }
7s6}i3z']-O F z"q         S.top=S.base+S.size;
V5PmPw&J%U         S.size+=APPEND_SIZE;
1|bBgvCS5[ rWR     }
|(Y6{G&UivM]F7p     *S.top=e;
A_&p{%lD     S.top++;
*HyZ]pQ*CZ     return 0;
*]"Y#K0~P.? }(x"u }!] r JF@
Iy PyE4TK
int Pop(Stack &S,SNode &e)
c0Q-ZW.`G}*M7x O {C#|NM@c
    if(S.top==S.base)'H:S,U\u?
    {(B3ytBz?"Y
        printf("栈为空!");
TTi6^f9}         return -1;
!{a Ul7C y9[3~     }4B~Bwv&B
    e=*(S.top-1);'_zrQm*`"K2Z
    S.top--;"^.[;Z;m;y
    return 0;
(q z @ M8a] }
e A@:W5\8Nh!ez[8Z h} l]9x q'@
char get_precede(char s,char c)
2gA5V.u-s6P Tu {
,D+QDAfitc3q     switch(s)
$CB8v5mj7~     {2PJ-a mE9D}.o'l*l
        case '+':                 
"z)RRcz ^         case '-':
0R2kqI~ j              if(c=='+'||c=='-')q$xK |2uM
                 return '>';
E:I w;Y|8D E              else if(c=='*'||c=='/')
L;~a:x"f;EN                  return '<';
"A[8p8VLx              else if(c=='(')
X#e5x`?5D                  return '<';
,n$CC%P&Dwn              else if(c==')')9z+},u+aT$I!Ew7Bl
                 return '>';
v'P%E$vw.{j}"rS.v-T              else
{,k*G7a,W2SpI                  return '>'; }#`Wbx
        case '*':
D7X:C1Od SX"B2bY         case '/': S!Y&xk r[n
             if(c=='+'||c=='-')2W@QJ0j{
                 return '>';dHQy#f x\
             else if(c=='*'||c=='/')
E#jORd;y                  return '>';8t9z2Ur j%j W
             else if(c=='(')
x/l#U6?*L|                  return '<';rCP,IN:Dqn
             else if(c==')')AGn)u5n9QW*aj
                 return '>';
1SG#OnA dq#u              else }(s]ITfUv7[!y
                 return '>';ajOo K-z SEc(q
        case '(':
7\5JH1[Fw0O9fb              if(c=='+'||c=='-')
/s&\8|pDBo7BwtI                  return '<';
TR[(\1v~              else if(c=='*'||c=='/')Y D5p LvNzn
                 return '<';-}/m}4Y]2n%g Q
             else if(c=='(')|}-x#~{]K-L
                 return '<';^8TI/gc
             else if(c==')') e4_0r%m'hdlKA1x d
                 return '=';
d*O_a6DP              else\2io%n%?Z[fH
                 return 'E';,l7WM-WrK*Gb
        case ')':
3a@.GC)Z@'P$Y7v              if(c=='+'||c=='-')Ir#t_'P!`
                 return '>';B5Mp8F9Hmz]
             else if(c=='*'||c=='/')
QfC!M9M"A%y                  return '>'; T#\*Z/yk&fW&|^
             else if(c=='(')
5hC'i&cq {!R)A]                  return 'E';;pP9a4v-N@7r
             else if(c==')')
c| H#Ae/WD |                  return '>';
,E4lrvA              else aT(h#n8Yo oj0J7o
                 return '>';f"\)H!IxU!C)M
        case '#':CL6\-XD D
             if(c=='+'||c=='-')
\$l+z6wYq"q                  return '<';NWM zm N
             else if(c=='*'||c=='/')
4Wmm4ia!~                  return '<';
G!C&\X8W-I              else if(c=='(')
X2lH({H7[g                  return '<';
T"uV7A } T#v9Z              else if(c==')')
-D9W g!BK*f"cdbN Q                  return 'E';
!\uj/AKiyN              elsed/_#~8|;mt-z+B
                 return '=';
;J r/dS$H8K1b6a         default:
|L.g2x A.f              break;8z6XJ}-Y.G)};]D v
    }
5}5~1L+ol2Q     return 0;    yKT`$@
}
Iux7Y[m {!HZ d
c ~:A8VJpx int isOpr(char c)
&g5ys&{%q$qL;j {
,D&S.otL?}RY     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
.O%K!Q#mx]ab {         return 0;o;^5VcU s*x~}
    else [w3yB(D3Tj
        return 1;
F`K%I3[8e }yM.Tgn?;u
ysi%FI*N
float operate(float x, char opr, float y)5Xw!H;g| ~
{o n6P|uL
    float result;
5H8h'}ua `     switch (opr)[ Ot ]'Og2q*P#vs
    {2NAJ%[)mc5Uj
        case '+': i ZJut#m9N%V$S
             result = x + y;_!i*K0uCVxKC k$N
             break;9?!`P+H BS:ZoW
        case '-': (JT ai8?5yF
             result = x - y;
4G9l4Ka|r              break;
I&j9Ss)Ix T6]         case '*':
O2c,{ h3y5I5U.^ kmok              result = x * y;,p;B*C'CbF
             break;sP2I4PI3n`
        case '/': rp+TLdA WqO
             if (y == 0)4h1Nh:tMO.M
             {
k]Vo8B,{Zc                 printf("Divided by zero!\n");N J gW.@8o-X En
                return 0;`;_:f'D G:s QSQ
             }
2T(S-Avtw;G              else Y:sC9Bm;u2a
             {
&W.XR%KaUCt9Y                  result = x / y;
1p;\@;G"n6D L                  break;^OmhG1F H
             }7|2j$p;Df.Zyy L }
       default:
C'r0nn*^ {w              printf("Bad Input.\n"); %t*OI"N"~U+D'? Nmzn
             return 0;
"W j[ds-t|#D     }p+ebs,Z&r6~G"g9G1Iud'w
    return result;
&KI7J%p)tF }   
:N?k)L&e uC`S c
d.^ F2j6o float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
,feL"}+@,F {
&L$T!BAF#olH     Stack optr,opnd;
?$~%P#zCh     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
6ura,} u5aqzA_     char c;
dZ _|;Ek5n     char buf[16];
!hTx;_+sR,j     int i=0;
"{b#C;m3_ _0DN    
!Sd@g&Xc^ ]-??     InitStack(optr); /*用于寄存运算符*/
F8FI ^\6Oh     InitStack(opnd); /*用于寄存操作数和计算结果*/
Z2O+MJo7^)q     memset(buf,0,sizeof(buf));
j&@ LaO%{"j    
l9].v~4C8u     printf("Enter your expression:");0}|Spl6]F:w/K?L,eS4a
        
s)t7c3t e}     opr_in.ch='#';s I Dv@
    Push(optr,opr_in); /*'#'入栈*/
0E1}+@w7ID     GetTop(optr,opr_top);
%Q|WmB'D]p q8z0^     c=getchar();
pH"vtg YR     while(c!='='||opr_top.ch!='#')
8J%C:iuu     {
3OF4S#?n/^         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/I\(];X-L2[
        {
/Aj2ZAQ             buf[i]=c; PrN!lY x3n4L(n
            i++;
3i}"sZKtMh l             c=getchar();$t&_'f%tt F
        }
y\N)[mT,J         else /*是运算符*/
g ye$q&_kn         {u(zF!R'W!Y+p[2Xv
            buf[i]='\0';
V$^ Y5L/S4Y             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7u5tJmH@%@*P             {
po1Q?/ky,ab                  opn_in.data=(float)atof(buf);2G [S R)\TZ E
                 Push(opnd,opn_in);#v a D'T&t.c$x
                 printf("opnd入栈:[%f]\n",opn_in.data);,n:m9C t`1sF^0f3z-z
                 i=0;
`'gNKhk4Q/E]                  memset(buf,0,sizeof(buf));
.| sXc6o;o;R:NX*o             }6R!]-Oz;}w
            opr_in.ch=c;9r%z6j|{J3v
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/@Nzv)j7E"x,b-s
            {
$v IN HH                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ b$N#L*G yeE*^ u
                     Push(optr,opr_in);$c {R dK8H}#M
                     printf("optr入栈:[%c]\n",opr_in.ch);
%`7rO _"G|2J]                      c=getchar();K _%ma`4UL1|
                     break;
E2T b;\C5c?                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0}?q)l4N%T;T
                     Pop(optr,e); Y8^M/L`
                     printf("optr出栈:去掉括号\n");O:gI ~9`Aqc+v(S
                     c=getchar();}\x {0ii%PM [
                     break;H+t O7sm
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
@?-ayD1@E                      Pop(optr,opr_t);0]AqZM.et
                     printf("optr出栈:[%c]\n",opr_t.ch);O]\H%_?!V
                     if(Pop(opnd,b)<0)
P4] rN`,]0|'C,a                      {
4`V4^&c+a                          printf("Bad Input!\n");`?)S.t ?J Xz*?
                         fflush(stdin);j X7jA$h(R
                         return -1;
du ^#{|*V                      }2[/eTz.Ypu
                     printf("opnd出栈:[%f]\n",b.data);
:H-VpM|3Y? s"Z                      if(Pop(opnd,a)<0)A P6_` {p,Q\N[
                     {]^+wf4N)_)B S
                         printf("Bad Input!\n");!V^9}O+L @-b'ZK
                         fflush(stdin);
-o2i#?rzhR                          return -1;g+? Uu|"p
                     }\,P0yg H^ om
                     printf("opnd出栈:[%f]\n",a.data);O_)d L:F!DW
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$dh8Z M@Ee
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1Q&r4z-c2Yi)D8O                      printf("结果入栈:[%f]\n",opn_tmp.data);
4a\2Xi1Mu&\                      break;
dl#f`U Q/F             }^Gh^ fvbg
        }]b;o:B[MR
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
m${5mL j!BUA _     }B&U)o)G] @
    GetTop(opnd,opn_tmp); eHr"e iXqM
    DestroyStack(optr);
c#Hdn:F2t'n     DestroyStack(opnd);
#g|?C:`Y]}}7F     return opn_tmp.data;
-e&XW [+vZyc;P }
RDy5NmbGj +QH@-bRY#k;`8r
char *killzero(char *res,float result) R(K:C,w M ye
{
6U m V {8p9iq&lR     int i;
wm8pM(C7BA#R#ae &Se2L*~ dY
    sprintf(res,"%f",result);NyGusZk
    i=(int)strlen(res)-1;
M#p7RB.X[~8r     while(i&&res[i]=='0')!AZ1\mUYk
    {
KR%nf"T(|         res[i]='\0';
jK ho7`*?L_         i--;&O0Vv%I,DM qo"Z
    }
PC n4{.e'Edpe     if(res[i]=='.')xi7@D'W!K"s4e
        res[i]='\0';
%c0b[8d9GuN4@q     return res;3Y+Hs |'m8T:U
}
3w\v*IYu`W;|
GoB b!u2F)W#Pt int main()p9uyd6c#z;s
{
;Qp c1{}3kv'z     char ch;D7B;S.E+lbF"@ u!jmw
    char res[64];
)FU*F/mcmd l     float result;
0t^1r8l jyz'V     while(1)
J Vu%S x#nGe0y{q     {
3gl(rIat2?@         result=compute();4g[^f!pM?
        printf("\nThe result is:%s\n",killzero(res,result));4^My;u1Z1Vh
        printf("Do you want to continue(y/n)?:") ;bH+DA8x
        ch=getch();ymR*H7o X/h0g
        putchar(ch);
` d&\x@"WuA         if(ch=='n'||ch=='N')
(z[L!n^N             break;Nm-Zc*r.ds
        else$Q(m?3}P
            system("cls");5S*hz/O(hE&M
    }
|A9R.M4s X9_U3B     return 0;L!YY{1c"U
}[/i][/i][/i][/i][/i][/i]F xm3W{u/w,y m.l

b3Y b Z9XW7D [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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