捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.p[*J&Xm)C6K&Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=!_&~+Mh|"du I
/**************表达式计算器************/%av:K B Y4w0[
#include <stdio.h>
$|+~#bPV1W #include <stdlib.h>
Slk!}2Jl #include <string.h>D tY%FtD Nop ]
#include <conio.h>
sb5x/K\|1])q` H #include <malloc.h>
nm#jN1okD ^G'Z0O!cd"d
#define STACK_SIZE 100
0qJU-h%`+L0m3C #define APPEND_SIZE 10
e;N_/C0N.xf B
!eX;R:` cX6} i Or*L x struct SNode{
%G-MCX"N3L:k     float data; /*存放操作数或者计算结果*/
M UM ~U*ZP:^     char ch; /*存放运算符*/7h]X`7s2r
};
;w&]8a q&R%O0_wL w
&BmQ'U%cd/^*U&N struct Stack{pa)K1]b"?-E
    SNode *top;^ j7t1e\0r
    SNode *base;
)Y!e&e/JXQA kq-o     int size;
Y;EEt{EIP };
e&GUy:tj
Xs*c&l#C/[)~+lY /*栈操作函数*/Q$~N9\j(G,s?
int InitStack(Stack &S); /*创建栈*/
,B B8Tv-@0R int DestroyStack(Stack &S); /*销毁栈*/
"n;P:iC5aCn int ClearStack(Stack &S); /*清空栈*/
tr(M l#vnV int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
%X?&A&Y7KkT\2? int Push(Stack &S,SNode e); /*将结点e压入栈*/|t-Z)z7pz
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/Uk9P(^qm0l
ODn6r M
/*表达式计算器相关函数*/
9m+kwk:Z8M,z char get_precede(char s,char c); /*判断运算符s和c的优先级*/(dmg8W/@)t T![u[
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
/a.IOi6Tip float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/+s^Gz4W C%aJ3[8C
float compute(); /*表达式结算器主函数*/:s Hb`d gb\:o
char *killzero(float result); /*去掉结果后面的0*/ \ L:wj B+b{y
N6Xy\j qO;N
int InitStack(Stack &S)
5Kx S'_m4j {
M)H'G9V$B6o\P     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
HW&l+Yf X     if(S.base==NULL)r+SZ#FCkf_
    {
1o1_y8J n v         printf("动态分配内存失败!");a| Ur%A/Lw
        return -1;UeMqt{*s g+G!|R#H}
    }
*U!iEu+W     S.top=S.base;
aF`w.g_"uqj     S.size=STACK_SIZE;s;Ci9uN(Q}/kL3WS
    return 0;
6W-ULh(eGp JLC-n }
;d{ Xw/YB
r*g2k%]"I0FB9t+d int DestroyStack(Stack &S)
~fz I mHAB {
O L HU5^SI f     free(S.base);
7v^6w-K N6Z`     return 0;h2~ y{-q*P
}
(xXU"Z5g.|8jO+m%aN :~{5p3ZA'S9w
int ClearStack(Stack &S)n }9V!E'D
{o~NX"PbC
    S.top=S.base;
#[n_*gP:zf-N     return 0;$Y@7V%P5pZF(O
}
9wmVL0Z`4h6[0n9H
*V'X"v(Q5Y0[ int GetTop(Stack S,SNode &e) oE;e&b/M3k-|0W
{
:w/Z_T)hN     if(S.top==S.base)
;QV j:?-H1I'd7o6s     {(cg!duD,T@
        printf("栈以为空!");
:pm2{,waZ3oO         return -1;
A*ZiB[K     }
0sT'D;M WL     e=*(S.top-1); C c%xgTLk4f
    return 0;2R)E:\v"S'F;f%t
}
*T6jX3ry T:~&V0A
3I7v7K E'i int Push(Stack &S,SNode e)s\WH}9BOg+go
{[7KOf9O7T.Dd Z
    if(S.top-S.base>=S.size)(o+x%c'T|L,K
    {
q(xwbDRN         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));(}5q;`8A7d-fN
        if(S.base==NULL)
@_ N6c`Fd1L6WK         {
-I6q@oq0@6EzE             printf("动态分配内存失败!");%i0B4Dt(L5V S ]/Zy
            return -1;
6b"XGNyC&zt         }
HF`1Q9J         S.top=S.base+S.size;j D'w+x\!yl*z }4Q3ugV
        S.size+=APPEND_SIZE;,[:kYim x2}0B o
    }G4B*L.cF.g!h`
    *S.top=e;
NK@9q4g5|M8t*r#v     S.top++;
K7|tV%f     return 0;0F+hV;j$g$Ic
} ugw+j3v

"XWcFX@0` int Pop(Stack &S,SNode &e)
g,tA:k,hZUAP {_Ea u#G c/@ P
    if(S.top==S.base)
C ~kQ)f T*aKk     {
fv FX2F         printf("栈为空!");
,e5hRdU,d?&\         return -1;KZ*[*q1X E.|
    }
&Vkd1F#]i     e=*(S.top-1);
+pg;@_3TC&N1Z{O_     S.top--; D7~u1es"@lA R o+^1]
    return 0;
xE [0t9R+FP)goq }a"Y,He!d&y6G`i}

XsL\8f h]G char get_precede(char s,char c)
'[ m!|6{S(c(s&~/S {
?BY*?~ h     switch(s)$S8EW,?[;Z^u
    {
|v3P i o/O:{[U/Xn         case '+':                 hJb5x)y`
        case '-':
r7V{5r#r8he%H              if(c=='+'||c=='-')!VY%{E[mVV
                 return '>';~ VM5`Sg$L
             else if(c=='*'||c=='/');j0u5iL(^2`
                 return '<';
2qW _*DS x-y$K              else if(c=='(')p~*u'W |hL
                 return '<';
k1T5DH/U-vevg NC              else if(c==')')7vF'U0W5T d R
                 return '>';#L?&U'Q/i%e
             else {tn,D.b
                 return '>';
b4V4Z7hy         case '*':A2EQ;o)k$H~ E
        case '/':
O` Xa/J+^0uX8g5RT              if(c=='+'||c=='-')
m%r| K4hd%I                  return '>';
lg T]c]              else if(c=='*'||c=='/')
H*|g _J0wgs5o[                  return '>'; r`F6s S7bO"@%Q#p
             else if(c=='(') H3zvmp SF[
                 return '<';/Z8Q c7Y9]4I3}
             else if(c==')')z8UU3dz#O
                 return '>';
jE$QV:e#c*m^              else DU2fO @0}#` X4nvR
                 return '>';
;x)k"?5VXU HpE^         case '(':
'U&oiK T$O)e J              if(c=='+'||c=='-')
0J9[u@9F                  return '<';)G-e [r'Q]Y*EX
             else if(c=='*'||c=='/')~ nO)x2^%k+Z
                 return '<';
*Y1AiFKXYBS              else if(c=='(')
%ns'sge%p                  return '<';Y;x}7e ?w$W
             else if(c==')')
5M.p quRC(P\                  return '=';:N?,u${,C3N@
             else ng!S;P%G9B
                 return 'E';
,[E2[9k u+W\:[E         case ')':
7Y0y \;D8h6[T&H              if(c=='+'||c=='-')
J'J;f4Yb1z%xvL                  return '>';i Av@F6Nl'P
             else if(c=='*'||c=='/')
B UR8[} vy x                  return '>';
"k5e0|#B I;k              else if(c=='(')5vy$jp `f3Px
                 return 'E';M G:^1g)G)l3{!r!kU
             else if(c==')')i | ` O:Xz$K
                 return '>';
8C9\yr2jn d8|              else
0Ayz~)~6|p8A'I6x                  return '>';
Q%yQM)A7Cq8@K         case '#':OL5y4S{4U5@!_
             if(c=='+'||c=='-')
D"u^?;\$p%}%c                  return '<';
^G;S3LE#G              else if(c=='*'||c=='/')
p^0P_9wn9v#~                  return '<';
-A/[ h:H|bxwn              else if(c=='(')
"QL#GH,A VD6A/w?                  return '<';7Hj"P1r~|O
             else if(c==')')wE*Zs0}.I!]
                 return 'E';N+Zc%B u;|7wF_7j
             else0M+wV.|za2S9O
                 return '=';
@b)ST&`V         default:
+V"pS.x G8\!w L              break;b]N^zzK
    }
%M#N-|5s;O~;d~'q     return 0;    9h)l+rc+oK
}
9g&Z8g rf:Q5`7F WU {cb W p |
int isOpr(char c)]WZCaE
{
g*WA(O9Bj/v     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1W*hB5P&G[ v;|         return 0;.__PN!Q/JwW
    else 5a]4x3XDl0^
        return 1;
7l`;m3o-h6r ^ })nCGm1EP^J
X}0BbVG,lx+T
float operate(float x, char opr, float y)V9Li%jEG
{*C"m;e7i9z7O*?"o
    float result;
K }A d1~$dn A     switch (opr)
U*HQ*W[?$\     {
's6V,Z{0Jq)eg         case '+':
a]6ZOr'l              result = x + y;x["S${u FPT_q
             break;'E6I|c$^$m
        case '-': Xx?7Z A@ CO
             result = x - y;
!I+CvCLo#jGv              break;c:Ev9aN&W7{
        case '*': 8L%kbM I){D
             result = x * y;f[Hz;x&J@;D%Z
             break;*wp$\D%@!L#n
        case '/': 0[%t.t6} Z{eRg w
             if (y == 0)
c6\(jAJ*]Bxx Y              {
%@b1N I%` V {g                 printf("Divided by zero!\n");
hDe[Y0u,w                 return 0;
0A%N;yr!V5omd              }
4Jk4WPs~.]8W`              else
4h/H$N/Ib/l*n              {
(kZ2k)Yw_C?;P{_|:y                  result = x / y;
/J3[g;Hs%y9m                  break;"`2|M@/p*w-}
             }
L6w r IwgL;w        default:
X0SJO#z8V              printf("Bad Input.\n");
1^%])j NM._              return 0;+r9Z#Dc0o U)K |w
    }
%abX$]2pK._6f     return result;
lT:N|;D Q:d~R:w }    1} ~ pqYY/?*~
7r Y*L Ws
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/q rR9a)K(? nYH
{
S D}4J&[zT `MEQ     Stack optr,opnd;
hp:z\ _ ?     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;4IEf bS l?
    char c; Qwm6m)` R
    char buf[16];l`f:wz+DW
    int i=0;
w"c'gj\J8T0AS'x P     s-B#l$|_
    InitStack(optr); /*用于寄存运算符*/
@/EkO!b @_     InitStack(opnd); /*用于寄存操作数和计算结果*/
t'BRfE-S&{     memset(buf,0,sizeof(buf));,p"s:x.M5F_.B
   
7{B(h4j9^V`w     printf("Enter your expression:");n3N_Cy$Pj
        
s9xW\"E;Hx8c U     opr_in.ch='#';
0O-p xaO3Y9g     Push(optr,opr_in); /*'#'入栈*/
{?,w_A$Au*n8tU     GetTop(optr,opr_top);CH;MMy!g3I:]
    c=getchar();
a7D4z P;x)R U'T X     while(c!='='||opr_top.ch!='#')"@l)_k{_I C
    {
F9O|%x o:Oz6aD         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/LeX)U{7G^
        {
g-b3Zfx-Q             buf[i]=c;
QkE5Yc\z-J             i++;
4]F!u'B eTJ[4H#H'G,b             c=getchar(); ^0ns?R.}Q[
        }
)BvN/]$z#@8x         else /*是运算符*/ |A/f5PA#?u_
        {
}5a@^b1q} T             buf[i]='\0';
^*KVSof             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/Vj4pc4P8~8x&X!U
            {
hm[C4?@                  opn_in.data=(float)atof(buf);GE(LcE}8z
                 Push(opnd,opn_in);b5Uo^ v,{&I:E/W
                 printf("opnd入栈:[%f]\n",opn_in.data);
p*JMJ)x CZ#OT                  i=0;
vB8BMx%o%t                  memset(buf,0,sizeof(buf));
#a v}PL2q             } zuMvbH.OlA
            opr_in.ch=c; N,],D }Z[.AH
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
uq p3M"m6Y%T             {
`5V-{%F&QX5o)Y                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
~"s/jW3d0jw1t`                      Push(optr,opr_in);
-R4eoBi+xk K)U                      printf("optr入栈:[%c]\n",opr_in.ch);
sAMd a,Q                      c=getchar();6hU YB3Ie$v
                     break;
]N U3OIe                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ R\(}h4S\.u
                     Pop(optr,e);)Z(S F2C S#Cj&bz1An%j
                     printf("optr出栈:去掉括号\n");
-nI` ~` ZZ                      c=getchar();ZW#tjp~T$W
                     break;-j]6m \u)Q dt
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/a(Z2J*w0b(W
                     Pop(optr,opr_t);
8~c~ N&@~ E                      printf("optr出栈:[%c]\n",opr_t.ch);
!s D fIG;_                      if(Pop(opnd,b)<0)
:@!NwX"JF7d                      {
yi2[u|k,O                          printf("Bad Input!\n");R8?'Tx_\
                         fflush(stdin);ovE9x4KIr
                         return -1;{s:}(o(n0pWJQ
                     }
8Pl9H6U g-e3?6G#ki                      printf("opnd出栈:[%f]\n",b.data);
:v!`QW-y w                      if(Pop(opnd,a)<0)
DKW I5v                      {
2V1E1ii1R%@                          printf("Bad Input!\n");S v~9Q,Yb
                         fflush(stdin);
nN!Q(CAV1Z;P%m                          return -1;
(I S*|Z"Xl1O                      }Il0d5PFg/U)p
                     printf("opnd出栈:[%f]\n",a.data);%r f0koB?!Q \
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
sH@ShB^                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/qp0RlO{*F
                     printf("结果入栈:[%f]\n",opn_tmp.data); j)VU1]W o%[O Y
                     break;
td+s h%Y+A$d             }
F'Bg+zA6FB         }
8]6D ?q0F;_/bJ         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
8d2wj p$h_#U h     }2e9KE?DQ
    GetTop(opnd,opn_tmp);5n)Y!eT(tBt3eK5n!T
    DestroyStack(optr);
fE2@4G|&r r7p'D     DestroyStack(opnd);w1cg"Csy
    return opn_tmp.data;;?ccU*mb!]1E
})@n!KuB-u

'\U]2d-b[;tT7W V char *killzero(char *res,float result) e9js2?+r
{
t7rbm\     int i;vg0he @9y;GH3z0b
`a U$Gx8cy
    sprintf(res,"%f",result);4k J'Gc_7f'S
    i=(int)strlen(res)-1;b6LC]9]9QV
    while(i&&res[i]=='0')
m2q P PYm     {
E,f^1|o.^'R         res[i]='\0';%K+L8E:G1u-|&A
        i--;
0EwL%Tf(s#v     }ax)ZC,N2v;?.s p
    if(res[i]=='.')N [ RY;^1l7k~9v*ab
        res[i]='\0';N(WbXy
    return res;
4R"E5O YGL }
$d J?-orM0er 'xmfB qj E/j
int main()
s\;yb?n/rx:C {
| A*I.{/a     char ch;
mPm c%\8JN     char res[64];G SeN2](c
    float result;
g#hC q1Dw)dR     while(1)zN A0M5?
    {
q5qtF-|         result=compute();%TX,@!a IeBeDJ2d`
        printf("\nThe result is:%s\n",killzero(res,result));
%msv(C/J,x3Qr         printf("Do you want to continue(y/n)?:") ;
k}"@qT4Q`-i         ch=getch();
j&z~ _shu         putchar(ch);
&IyO3Jj3B)~         if(ch=='n'||ch=='N')$dX6W:l'Af N[e
            break;
5R `5qG/x1i&W8Y         else
0NV{g;kL             system("cls");
r]k-T#Gj     }6\[Fy&HaS,^#W0q
    return 0;0_;IU7fBxx6I
}[/i][/i][/i][/i][/i][/i]
\6OsL\:OT J)_%Z7q3Cp0Fx v
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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