捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.v:d2@3qh9LW4`
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=QJJ CLW[;A
/**************表达式计算器************/W_{ jzn W&_ b
#include <stdio.h>W b _*N@+o,PI
#include <stdlib.h>op)Yk4L+h cH%uCu
#include <string.h>
q Z.Gqgw8H g [ #include <conio.h>o"FE\mN
#include <malloc.h>7`xL t!_!G`8L
v*U)W)^Q9PXni
#define STACK_SIZE 100
x:I!z%j2f4c[*S L #define APPEND_SIZE 10XE,d3Z,Xy oq

kP {&Aw"T-vq;h3G struct SNode{
3x:i gh(?+wyb+q     float data; /*存放操作数或者计算结果*/0`F$rX.v+x2AV
    char ch; /*存放运算符*/5m?!\:gn/P
};
SO5{Z wB #xu2C3h!YtN
struct Stack{
3Soi,f:Ho     SNode *top;
5_2k;A\(vV     SNode *base;
)g l0O,X_ l$L@&eh     int size;i*O3p mG V)I
};aB)t:C9cZuq
|,p0t J$u
/*栈操作函数*/#t~rW"oA9oD
int InitStack(Stack &S); /*创建栈*/
.Y(v9E+Fh |p int DestroyStack(Stack &S); /*销毁栈*/
z+Cy4`"Q X!IS3CY(U int ClearStack(Stack &S); /*清空栈*/ h~!HdX&\gr
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1T:W$@c^3i
int Push(Stack &S,SNode e); /*将结点e压入栈*/
EnP&Z!N0EDA5GH int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/,e!b G5@m5f,\'[
${ ]U/ef*u b.f
/*表达式计算器相关函数*/
\mdKb*t2F,i char get_precede(char s,char c); /*判断运算符s和c的优先级*/
:i)_q8n(gG Q2Y7V:S&L int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/'n*B M;f(~2i~"x^1I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/;]QtoZ(q
float compute(); /*表达式结算器主函数*/
*y/j L.W5wA,@M char *killzero(float result); /*去掉结果后面的0*/ ${5IOPGJ5a5A/[^
pnZp c`lsO
int InitStack(Stack &S)2^?vE(B;c#u
{
,JgJT7`Y(k;s]f     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+g;y+u"\/k9O G
    if(S.base==NULL)L0o`R Ic
    { ^"w%L8k$jo |
        printf("动态分配内存失败!");
+`#PFdjJz         return -1;(P%Z.l].t!dz
    }\"j#{Ke)G@:e.Q5d
    S.top=S.base;!Dm![#Vc
    S.size=STACK_SIZE;
J5j c \;o$rl(o     return 0;
y7ijD5x4VX }XZ$Fa^,y~:t'c}5{

;Opps-q'J Ug int DestroyStack(Stack &S)nQZ}pw8L#N6bM
{
6e/T*H.Q8r)Q m"k     free(S.base);\I7k1W&hWFm
    return 0;
e+J Pe3E.GD;s }
4N!zLM$A9rEl
!p OZ#D[N int ClearStack(Stack &S)Bs'HS3~3Q5_b"g{L/J
{
b d;FM*b'\#L j     S.top=S.base;E:C[M.B,HJ
    return 0;
VS2|9S)m(s"[4u:d0v }
P.c KL4@ G i #}&d Ff[9omv-o
int GetTop(Stack S,SNode &e)
sZn0m!hh Cg\ {{#S.~7w;Wr
    if(S.top==S.base)wyZ^YJj;y
    {
-OD!Q4mdC};B         printf("栈以为空!");/h u9rDA4Z|6B4bq[
        return -1;
(Q.}x h z     }!a kC hl P!u
    e=*(S.top-1);
-h'X2Y2|r w M1GI8e f}     return 0;
`V@M%y `Y8N }
'~&c5N,Q5t] w/I d.S Zb z:X3a i-I/~(D ^Y
int Push(Stack &S,SNode e)0? Y$S5T?g
{
p*JpU!H#@Hj/R i     if(S.top-S.base>=S.size);lV6@)i ^s n3ey;f
    {5[ s)a8{1L/I x Ug
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));FN#[+d;dVS9q2D
        if(S.base==NULL)
T(c{Y ohf         {
ehC[R             printf("动态分配内存失败!");
!PrE;eN)Q0I|             return -1;-K\;|;D/n1|*uW8g&y
        }
n tELv$C         S.top=S.base+S.size;%{Xu/c2U[5U
        S.size+=APPEND_SIZE;
R0j#K-~#q"aP1b     }"wlJR"|:I%`
    *S.top=e;
Jaw)FE7fk     S.top++;
-Y~qKW(y)?"@ b     return 0;
(V M9j h3i{(mw }-~ B @$D}}I
U(ie'J@g-b
int Pop(Stack &S,SNode &e)f dK8q'P uq
{
L)|R:ySw6M     if(S.top==S.base)
(_Ef1jVKD1Jvov0B     {*n3[DO-P^&@y
        printf("栈为空!");
I@] ]4L         return -1;
d-O+p f h)H6Vc1@     }8xc |.@R
    e=*(S.top-1);
b9SV+r c     S.top--;
8c'J!\1aC     return 0;)b%^'|q?s2K:g'W8n
}
WJj$VG3@]a ;B:Yr:J#OaLf7|"^
char get_precede(char s,char c)
Z*Nk?9\~f u/O {
B{fQ$j tF     switch(s)1B CG-D e5f
    {,U c A4VX+`|3U\[,u
        case '+':                 [#b xv-x(|1dO
        case '-':
.I E!w pz6Z9g @R&d              if(c=='+'||c=='-')j P,_V @ w
                 return '>';
x!JOn4~0j TH}              else if(c=='*'||c=='/')
jKf OBvw3l,e}                  return '<';1jrS{W? h
             else if(c=='(')
c-hC5L O-JN                  return '<';fQ3M0QSQ%w
             else if(c==')')
R.Q)P EV d pPv                  return '>';G Vz({Gm.I
             else
4xvPLH4o:A                  return '>';%L(\^,e+S@'Vi
        case '*':;uK m/U)b `_
        case '/':
Z!Ia#oT.?^ @kD T              if(c=='+'||c=='-')9IbgH!U
                 return '>';
E[J | Lg'e[ W              else if(c=='*'||c=='/')-X$f5} _^(c3@:r
                 return '>';_+dXM@3@'Cz
             else if(c=='(')
H3k#bK,yU.`B                  return '<';
FL'[7W m{ D}g              else if(c==')')
,d y;}&_7XA5~{}                  return '>';
@DrC]9Z!] sU              else
?mvnh"v5V7IM                  return '>';
"L~l)D1~         case '(':5lk7bJa? W:E\"AO
             if(c=='+'||c=='-')9]C^ M dRv
                 return '<'; b e-J4q*j
             else if(c=='*'||c=='/')
H PY*bc3d6K                  return '<';
.sD8Z/lWGWA              else if(c=='(')E9p U)L_-B
                 return '<';z#y.e%C/DH w
             else if(c==')')
+eAr7E$A#?@-m9X                  return '=';K5LM @[zc
             else
)Y!ZIl*Yn+e d({ C!\_+E                  return 'E'; gw-j W*a*]w
        case ')':%E$z^i!N
             if(c=='+'||c=='-')*C%S h%j6W
                 return '>';
-g@M1b)]vJ?              else if(c=='*'||c=='/')
pX{NI3tPNS                  return '>';H%Bk l sF T+lq)c
             else if(c=='(')
5nL z4Of h3s~                  return 'E';
fWA4o;sX'_              else if(c==')')4Z)bA N'K#J c8X
                 return '>';
:q {h$t7e!lM              else%|Y^Y/d A w&N"[O
                 return '>';7h%`a{l6p VJ
        case '#':k/{;Tx_)S#{S ~7a6E
             if(c=='+'||c=='-')
i:yU ncPBW                  return '<';
;E*~?)N4vT#X              else if(c=='*'||c=='/')J3psP-u*?6e[0xg
                 return '<';K&i)@z+\ D+Vyg*{
             else if(c=='(')
h+I2B9ozK'C"b                  return '<';
Yi I-Ox r ^              else if(c==')')
V}e9Y}-pHl+@                  return 'E';
;Vl/Ls.k8WU6Y              else
m0_@{2`3k1n Y']x                  return '=';
z @%VA,c         default:
FoAbUk j#c+`              break;
}_W n ^8h+L     }{+z/n2m`S
    return 0;   
6r@.UI6m"{'w7L7K }
Qw @s t ox"G^0r.G -pfpaB J
int isOpr(char c)t-jS+C$M1?z
{
*_H)Z(WE;I3c N     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=');@i6{ ox#vf!U
        return 0;h$h[7N#p!f2T-h d.yF
    else :U/f;|ig
        return 1;
Ptd6V!A&P } tzUzb%g@

%j6e ZD*v T;QN S float operate(float x, char opr, float y)*GP j _n
{
p9|!XVR9o3~/C#E*e     float result;
F%Hd7qV6G|     switch (opr)Y!V/h?t
    {
(n ZL/E#]#N         case '+':
n w0m0E)DG^+XV!g t              result = x + y;
Y2J4\)\JU7M!r              break;
E*mou ULm@3]         case '-': /X4iZUh8i*AL|1s
             result = x - y;9K0s4X Hu gwl.X5H
             break;
+`tr4fP#@'e         case '*': OE.n%FPx
             result = x * y;0TT'@k4B?
             break;
]3fn*Qqb-`.k$v)w,p Ot         case '/':
+qy!b'`W;YA-g              if (y == 0)
2U8O+v[+h8}              {:r v|bp iM0O"IF
                printf("Divided by zero!\n");
I2{v9AM0A'y ` R.n6f                 return 0;:u4UIIWfA ~s^p6S
             }!_M5aA*La0I:YJ#~
             else
L[-n WDz'?} B              {
;seuGEK,W+m                  result = x / y;
,?.I@&fz                  break;D#fd6|-|km1x
             }
z^ hOHc{X{        default:
9T$t*e i V7G"~e~              printf("Bad Input.\n");
?*|-H C'j y$i              return 0;2X6s-z7@e D(W
    }'ix!eO6m?
    return result;,y@&Cv*K9vu tFK&t
}    n.RW'BP(m `&W-K
g+|+qr Mh
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
X V!e#C{'}GZX {#ms'Q/d'B
    Stack optr,opnd;
k;qS fJX k:V ^     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;5G4O8W|1\8h wt
    char c;
/x?6t\([,i+i r     char buf[16];
m-M`)UINL3F A4rs)m     int i=0;6O4R];jdo+k[
   
rx9^7` S-O8T:{ u     InitStack(optr); /*用于寄存运算符*/%UJ `o;`
    InitStack(opnd); /*用于寄存操作数和计算结果*/lma1_9j n6p
    memset(buf,0,sizeof(buf));
K5a,P[AHu-^ {     oM M,H$S2CFi|
    printf("Enter your expression:");[ H Am zNOD
         i?.b3Ww{
    opr_in.ch='#';;sC UV/S |ly7]
    Push(optr,opr_in); /*'#'入栈*/-|u)B8Y]4Z;G.W
    GetTop(optr,opr_top);
M5D-\.n;]XZ]     c=getchar();
7YlvF'G JeK.M E9?]     while(c!='='||opr_top.ch!='#')
6w E4Y#B4d*^u/t4x4E\     {ma#k0r0A RW
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/|,i:c?+Fq$ue
        {g'piUiH
            buf[i]=c;guj},l(r[(i)}
            i++;
wm'R!n*D;?             c=getchar();
s~"@YHj         }lIQ i4s4qo#o
        else /*是运算符*/7t qEnE1{7\
        {
'ZJ sx'O5y             buf[i]='\0';
y Q\3NP             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/d&z#Tq$x;f3R)@
            {;]1|!A d{.gS}
                 opn_in.data=(float)atof(buf);
dn*\i6_ j;Q                  Push(opnd,opn_in);
%I.GQK EF!D_                  printf("opnd入栈:[%f]\n",opn_in.data);7w;tW;K.P)X3y@
                 i=0;l2FK#Te0m"W'z4hv
                 memset(buf,0,sizeof(buf));
%L%t:LR F-S             }
v9b7E\BL#j+P B             opr_in.ch=c;
r"SZ1b&a?,l)JC             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/1dc Er]zEXx
            {
E p ] |:p {.}d                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
5VjV"D9FF7^ zOm                      Push(optr,opr_in);-w)w5m ]!~'NR|S
                     printf("optr入栈:[%c]\n",opr_in.ch);/~Wj6p @[
                     c=getchar();%g4htW.q!Vdp8g%x
                     break;p QVEY"l5w"@&@s
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8[Q,l:s7h U
                     Pop(optr,e);#Y|1co1jV Z
                     printf("optr出栈:去掉括号\n");
gi/Z/Vx'~                      c=getchar();*W P-S,d#W*a
                     break;
D1U0tzDQ4w6M                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
;FaT'q-RJ#U?)]                      Pop(optr,opr_t);
\vwF+Q}2P0r!` B                      printf("optr出栈:[%c]\n",opr_t.ch);S J6a `)@dA VN|
                     if(Pop(opnd,b)<0)o p!d%`'sg)j7p
                     {
7mGgvC ?                          printf("Bad Input!\n");'@0R6y"WC2nWG;W
                         fflush(stdin);
)X"\P'vNk5Do                          return -1;l#E&u%v7U.O Oy
                     }
,z Q5T/qp+q P*M6~                      printf("opnd出栈:[%f]\n",b.data);
zB^M0?3\                      if(Pop(opnd,a)<0)
;QIW1Z%qxcN s                      {
6Z?qea/{:CJ                          printf("Bad Input!\n");h^Ye I"p5J+v
                         fflush(stdin);G-a5A![%I0H/S
                         return -1;;_H"w ]:w"K;Q
                     }5t,Wu.T P/b
                     printf("opnd出栈:[%f]\n",a.data);/{ l-F,Mj!K?H
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
y_&ZF!Dr P2_4]l                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/Wc:p`k5WI[ Es#hT
                     printf("结果入栈:[%f]\n",opn_tmp.data);
R w}r)] ]U9a,Z                      break;'i/C+M+G0a{h2Tb4v
            }
#Z3j Os!@m         }lzj*`2uL
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                B\| C?8c8c,U
    }*G%HtM*Cp
    GetTop(opnd,opn_tmp);*_3u$a:S'_$F
    DestroyStack(optr);
o1w TOo,[9Y^-BN     DestroyStack(opnd);~ K@LT^0_u5`Y1C
    return opn_tmp.data;zLgF#vw
}X\%o;A)a1[m5r
+zz/q!X6f
char *killzero(char *res,float result)
"I cNK%^v B&p2j {
"`i5R M!YmJ4r     int i;Cz'V2g6TT'N:x

V)^'Ptx     sprintf(res,"%f",result);
`'EL8JF1K     i=(int)strlen(res)-1;.X A0t+]3H/Z/HO!u4`*yI
    while(i&&res[i]=='0')
)J"X[(y@`? J,@o     {
)u)OB;@:s8n;w         res[i]='\0';J Y%G5_h6zt
        i--; T @2Ke)v8J f9V)Z
    }
v5uF{H3x     if(res[i]=='.')m~8oFw UD
        res[i]='\0';
D'[ _.Jf8nZ~z     return res;-L"lSr:^.|d
}
C4B"A%kS &y&AV4QYNM gs
int main()
x7h4kg ` {
4`2YD!Q0K@8k     char ch;J9s)d`)Q
    char res[64];S+T(q'd0_
    float result;
Pu4|8U5lJE     while(1)
hhynug     {
\(s`c5W-lm R         result=compute();O-z2h{S-NJ ]r
        printf("\nThe result is:%s\n",killzero(res,result));v&eHs n([l+@
        printf("Do you want to continue(y/n)?:") ;
]UH j | Rp?         ch=getch();]/| R l6]t
        putchar(ch);dbPM_ o{@
        if(ch=='n'||ch=='N'))R {\X%p'i|+t Sx
            break;2{q(E nY$vd
        else Eujo^xA
            system("cls");
}~utt     }$Qnky.x$_h!{
    return 0;
h|$O6D-MU n*j }[/i][/i][/i][/i][/i][/i]$wq6Pw L5PGV
u[1nZ lBViGC E
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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