捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. W\3@1?3kbZy
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
*iy2N0K1pw#hA /**************表达式计算器************/2HI6ag*}3X
#include <stdio.h>
&?dSqhS2Ae2y #include <stdlib.h>)K^}Y*_8Lw
#include <string.h>
#KZ1A1QZm9}r #include <conio.h> AaHm7b}.@lz
#include <malloc.h>5gf[Y0D |;f

L2}0|;z#W$_{q #define STACK_SIZE 100
#U(j2@T0A`~} #define APPEND_SIZE 10 pJ$r7x:fg:BF3x

%T"s^oN4g W struct SNode{_1? a4dXjp
    float data; /*存放操作数或者计算结果*/*^7@']bos
    char ch; /*存放运算符*/']#_Z:t9r:l
};u-^5~1Q,\
E2yfj+jOy
struct Stack{
],n/p$dj-fG Cd     SNode *top;ttK H'@6e8o LM8[-\d
    SNode *base;8{xJA,Lw1FZ
    int size;
P9[]tf~;@ };
'amsC)w&O0x*P
4qwi-V;q /*栈操作函数*/
m&[!Gz RMY^^ int InitStack(Stack &S); /*创建栈*/
%GqPl3X int DestroyStack(Stack &S); /*销毁栈*/
3W#b }a Pi? int ClearStack(Stack &S); /*清空栈*/#N!wp{&}/z&C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/P7i3OUd7TE}
int Push(Stack &S,SNode e); /*将结点e压入栈*/y-X^6D j B|ik\2X
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/4d]Q6^2G9}
.yf#b m7F5Q2Rg?LA c
/*表达式计算器相关函数*/
:BxP6}W} char get_precede(char s,char c); /*判断运算符s和c的优先级*/2L*`1Uv,v3AM!yB
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/F7q6r;i;}&y/X1Im;c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/csw+n$I,G~^H
float compute(); /*表达式结算器主函数*/cX5T7R}GFy
char *killzero(float result); /*去掉结果后面的0*/ 0q z5E8u:c \ys
gFH6e @a8X c
int InitStack(Stack &S)
8PZP [.H4j{x {
r+Y e1y1h}'Q,m(K     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));9Qr ^n2ZdG Q)aw
    if(S.base==NULL) ar.?R^w0}V5FXN+R
    {`6~;h*_HQ1w8y)c
        printf("动态分配内存失败!");
Kt,ZF&A _5Q         return -1;1P#V5go0Ai*j{
    }
;Ub&Pgmf B p     S.top=S.base; ~+K9R:]!d
    S.size=STACK_SIZE;
YtDh q _     return 0;
;Su h[#t0x5Uz I }0mN"t/UHK0NA.Ye
V)l/HS!]PYUU#c2J l
int DestroyStack(Stack &S) SD$g8QzwN M
{
okL2\ ?Hl     free(S.base);5kdGQzzi
    return 0;pF#Ln f0z
}xCI$~Gn,p

!Ny j#s/d4W"O!B6t int ClearStack(Stack &S)}6liY3X
{ Dw5Q2f"e]-Z7^"b
    S.top=S.base;
#d*s v8^ Cz^     return 0;0ow&H_k.N5\ \B'N:^
}
t{gjK!La*@$Z 'B tH\8[ NS
int GetTop(Stack S,SNode &e)
4c2? q$cJX'C {
\WNyT,m     if(S.top==S.base)#l*x!w*iV0qBK
    {
? IUx*|A~2H2IF"e+E         printf("栈以为空!");
P4zE?*M&HG?+z!L[ i         return -1;0Z$T"P?;R
    }O?(@w2x7T"KR4b2G
    e=*(S.top-1);
;KFQ\ {`Q#~vGL6Q}     return 0;R(iA"zxq`,b-q
}TI@R!h/F*y Q,@
"?(B] Zn+S
int Push(Stack &S,SNode e)2z(N.dsPQe;\
{
*F@ B'\2oSS     if(S.top-S.base>=S.size) dV"O _(R^#fd)\L
    {
Ce\*J r2zE hAA         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Mg,B/W0Pe&X         if(S.base==NULL)L _.E dyV
        {&f}{%L2u?
            printf("动态分配内存失败!");
y%T7z"{{|,{H             return -1;c hi$XR*`2TP
        },\VoYa1a
        S.top=S.base+S.size;
*YF2O}bN4V l~         S.size+=APPEND_SIZE;
6dG ?)wV u {{     }%S rH`5Z0c
    *S.top=e;{/T c;I `A q:j9K
    S.top++;
I9x)Mr h9LXA     return 0;
-nuaEf,Ja }${r/H\ M P_)@+HfM

yQ B,@|4dw int Pop(Stack &S,SNode &e)E,o;ZcZ
{
q }&r1S5D_!p     if(S.top==S.base)
W9dj*[,TX(g2{$|W     {
S zze,sZW`2y         printf("栈为空!");pQ2}kN b*pm
        return -1;&{b&^&N ?/L\
    }`&NLb [4mk#~
    e=*(S.top-1);
v [`'\$x Qv     S.top--;
5sh&W)c*V1[1R8^1}H     return 0;!BYj,khD"}
}P0@ZX D(~
/HCy&|*Z
char get_precede(char s,char c)Ajvs6[+I C9C^
{
O]/Rm S:w     switch(s)
&l WUy"y.UT.N1BR     {!u(v;N,p+t0h'Q(Ne
        case '+':                 
fW3ttpPf         case '-':W4{a{ a9N
             if(c=='+'||c=='-')k9N7_&YM3B Yey,Jm8?/J
                 return '>';
*v8W1M ]V ^`!A              else if(c=='*'||c=='/')
;JBHPO!V                  return '<';(PM-zO6Jqy
             else if(c=='(')H4`a!Bm/WX5q
                 return '<';D-if{e x
             else if(c==')')
;t0[1j j v&~c                  return '>';
#s.Y&L1fF?$Za              else b6Q`W rjPmu
                 return '>';
([,| } [tV3LA2e,w         case '*':
_ F'z B-W [v         case '/':jT$q+eh+I)p8n z
             if(c=='+'||c=='-')B)A w;p:z
                 return '>';5J&u)B(Y qh4ra"j
             else if(c=='*'||c=='/')Wt%]@.rm$^
                 return '>';
-^JpY Sk;I              else if(c=='(')Pq%MX;A.{(e
                 return '<';
r5Ku/}3VW:_              else if(c==')')ck'Kv5DA
                 return '>';]3~ T.pRqs;qbW#i)a
             elseF$r4_W Q!Z|Q
                 return '>';
'b6m E9Z4?!x t#G         case '(':
wD,bfp:Y              if(c=='+'||c=='-')
U7P6T _ECGm                  return '<';BvD5J.?D O IR+qO
             else if(c=='*'||c=='/') hiv%Jt
                 return '<';
`$T%I2f2m              else if(c=='(')
h(g6q?!P[7o                  return '<';|XKQk X T
             else if(c==')')
%_#{7^ u&bF                  return '=';
Ak^{)[R,d |"w              else;Y!Ham M7^3G&e
                 return 'E';
CTE;~.aA-OvFSC[         case ')':_:y0Vwq2`
             if(c=='+'||c=='-')
s q1{?'y U)Ol                  return '>';SM])m)er s*Qj
             else if(c=='*'||c=='/')
+dg8}0bSo Lc*|                  return '>';GB/`"]O t
             else if(c=='(')
!e?Tu"y9o2@4Z~)_;^                  return 'E';
*VVlZ,T'@+K[              else if(c==')'):b| ~;q9K"Q{
                 return '>';
se`2u;K6[5c!S              else9||/Z mb)w
                 return '>';ei5d|r5`
        case '#': P~2R4E1XR#m;p8l
             if(c=='+'||c=='-')6k!i5c]#\8m H![#k y
                 return '<';
5h.Jq[xv XO(E7SJ              else if(c=='*'||c=='/')
]:^{x)K8oj0O H\                  return '<';
B9TcMa?;_              else if(c=='(')
xz r&Gu)^k                  return '<';fx-g"Q2r9w$M+x
             else if(c==')')
*Q%e Jm Lu.a&A/`S                  return 'E';
#pi6t|V              else(n8g;u#I!Om8ZG
                 return '=';
W;Td ds d2Q:}F         default:WN o/^ v
             break;
1K ["P_^9Ty%I     }
1]E u/|(m^9H4KN     return 0;    XI ut'x}2qi
}
)a6D"Oh z'_/Yh"}8k
N_/k4s+W PnV int isOpr(char c)a-MzNm*RxZr
{
x@9W/~4Q;c~d(A9g     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')z]y)@/N^6rE
        return 0;Yj&MJJ1H!B
    else ],R;r sex.^f
        return 1;
0X"w.`BW3Q!} }X/j;w,I+J^`

/|$h&k!K0z~ g0~Rd} float operate(float x, char opr, float y)z,da4j\&?9D }q
{*[%zw8[4}'B1M.m
    float result;]y} p-K(tl qY
    switch (opr)
bI#K-M^Z~T6m6dG     {$Nd,v/O*D w4l9j I
        case '+':
i f*|"u-O8zL3u8U1B W              result = x + y;
EDS yZ              break;
f{3fG1B0N(P&V         case '-':
_,zb` u[              result = x - y;
5e hEk([)Q              break;
U W`%@V FCz         case '*': y)nbl.t&kPmz3m
             result = x * y;
.oG&l%GKmO              break;
4v0z v!xfgM         case '/':
7rZ^ r:z[)g1vcJ              if (y == 0)l@$I?tN j0T:X{
             {
X8Yb,D3s7K!P;l                 printf("Divided by zero!\n");
fT`.I,E4s0M/W"v                 return 0;s)a @/j4l$nN Qz
             }Q%?.Z'G%xz^X+W
             else
Spk"N3AG~T S              {
5k6qd8d!?0km"YQ                  result = x / y;
oxk7J6_o5q;^E                  break;
:l*\4Q:~o,zf              }2~ J@x r:s0P
       default: 7MV2x+P,Y {
             printf("Bad Input.\n"); c6~%I#Pn
             return 0;
P:TyX^+fs     }
wnZ$R9T3hY2yqfG     return result;
\P6L7u.Ug:?;M }    #}]C^)YZ#B
gn?{d]{ kL
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
y]klC ]O {K7~-`q\ @!\j
    Stack optr,opnd;
&p:v Wh8A#n#r%o(WI     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$H(e4H.N^:Y     char c;8W%LS)Rc6vC {
    char buf[16];
)]Rp9D {,y     int i=0;c7u mr%i
   
TE#Yfvd-| u     InitStack(optr); /*用于寄存运算符*/
*N*f3l9V9M^l!Z0J     InitStack(opnd); /*用于寄存操作数和计算结果*/Oe#dy zRj
    memset(buf,0,sizeof(buf));1Z$A ny^f5j,i
    /h#\s*d m:V`-}
    printf("Enter your expression:");
/Pflx(F         
K1Z']G$Y-ob4g     opr_in.ch='#';
@XfB"BL$PKx     Push(optr,opr_in); /*'#'入栈*/6KZ,Ln^ on
    GetTop(optr,opr_top);ZV3nvz!d%`
    c=getchar();
"u%fTX#gt'} JI     while(c!='='||opr_top.ch!='#')
6Y5Wj B"q TT;H     {
$u%P'p&^/A5?a         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6r;f)CV#nJ5q         {
&dy}D:X'q G?-s ]             buf[i]=c;
*^ d-F X6U0y7@7A,_             i++;
~%u&A| i Y Lv4w             c=getchar();
b s_ hSeE0Opv         }
9V)F.O p8WH o`j"m         else /*是运算符*/
w J MLL         {
,XV _8d(l,`)s             buf[i]='\0';
2qfAjc,r r             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
v5_1b9WFzGs"e1pQJ             {P0y:O.X4`{4j
                 opn_in.data=(float)atof(buf);&@6[|@wN+A
                 Push(opnd,opn_in);
0M1L#Ze&_A1tE                  printf("opnd入栈:[%f]\n",opn_in.data);
.h-_-O0Et}                  i=0;{*sIB ]?B^*|n})bW
                 memset(buf,0,sizeof(buf));
$}faq(S)[E(U7e             }
'Fwcz8?6HK}             opr_in.ch=c;
{ q][+F"Ew s3n             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/?Kz{%Gs.h
            {
!]MVxQ#ad                 case '<': /*优先级小于栈顶结点,则运算符入栈*/'z Hb8N Q7L^ y
                     Push(optr,opr_in);
R*s? lf;B/M                      printf("optr入栈:[%c]\n",opr_in.ch);ok%}R%Zd+?S]l
                     c=getchar();+rgz!Jj7m ?d
                     break;
9^0| @a'g:jV                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
w+ePe~$I(k Pd                      Pop(optr,e);\^]oe wD4e0N\
                     printf("optr出栈:去掉括号\n");
2]Qi/X3P%d0H                      c=getchar();
dxe Pr1?                      break;
1u)W\jP1j                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0OM6\%SrEp(C$dN                      Pop(optr,opr_t);7k+d qt:s!| p7N
                     printf("optr出栈:[%c]\n",opr_t.ch);
|tfc Pxf7WMp                      if(Pop(opnd,b)<0)
|?"|Y Qw:^                      {
PhxB8r+flG#K                          printf("Bad Input!\n");
J4b\,N1j8lP"Af                          fflush(stdin);0xdUm V'Ty
                         return -1;rj)T X`
                     }
{;b MsIcT                      printf("opnd出栈:[%f]\n",b.data);n7Q`U.RE p
                     if(Pop(opnd,a)<0)
QW!a,v,Ez!z                      {+N Me5ubij
                         printf("Bad Input!\n");
D(}kU:X+Fy&u-@&BN                          fflush(stdin);Ih3eJ5EbxW Ef
                         return -1;
d3T'aD1sH h*? xp                      }
4YHd/p@5C/p                      printf("opnd出栈:[%f]\n",a.data);
7B+\ E'y#He'tL h                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
X*X@7e;g.vG(l ?Q                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/%W0c|CC}^&RQ
                     printf("结果入栈:[%f]\n",opn_tmp.data);
(g$b(D [2TJW`7p7f                      break;c;S4a NY3L
            }
NH&a!e-b$Yc         }T#|Z-\1@H HCL
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
_ @+Y$a@N w}     }EMi4H%?'Z9Zt
    GetTop(opnd,opn_tmp);
%N*N&X&Z0b     DestroyStack(optr);
,^7ErE'[ ne.L     DestroyStack(opnd);4NE+]#s&d;\8q6|
    return opn_tmp.data;\`m;V:y4ED/o+X.H$}w T
}
.ezt8Pd9{ !Ssv U3oV3_s
char *killzero(char *res,float result)9D(y.o3U!v.v
{
'B\6J mZZ     int i;
x3YyhiO;e p2oM6ihG8DnHY*i
    sprintf(res,"%f",result);uIlz*G%qc
    i=(int)strlen(res)-1;y-Ii&qrN
    while(i&&res[i]=='0')
n6V7@*sy*eQk"F'K     {
-^+K r+I/e1l         res[i]='\0';6z-z-tfyr
        i--;
A J;S4B*|     }!Y zxewsr,G
    if(res[i]=='.')
,Ft`s{Kh{         res[i]='\0';(eX/K7~Z5p.D*H8r
    return res;F'^;V)[M&j|RK
}t5f0N5Q(bT
0] K"H }h5D ]"{5r
int main()qO"D-@#I3x
{&c$g(b"EHk)N7s(k
    char ch;B%B!D%o+V{
    char res[64];-F*D3W!L7}9j
    float result;t,]$Ou0_j;m
    while(1)9QF/nZu tY+B
    {
8y6V'L'P8zYw3`         result=compute();2J!~O1G4tEgw
        printf("\nThe result is:%s\n",killzero(res,result)); pEpeX hd)A
        printf("Do you want to continue(y/n)?:") ;S4aF0R4]7m
        ch=getch();.G Bf/|m-W8p'A+s%y[
        putchar(ch);
4Ow#@S7G)f4?1c}         if(ch=='n'||ch=='N')
(U L]4Dq F/[#t&eO             break;
%k0tu$MWiw$l         else/E`6X&`*ewG:Ay
            system("cls"); ALZ${2``T
    }
U.g#x'f9R fK     return 0;Uz G Vh
}[/i][/i][/i][/i][/i][/i] t8dDq Z(u Z-X
R-o3kt*}
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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