捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.#x1H)Q LMU
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
y}S6O(e9I0b [ /**************表达式计算器************/A eD'x&j(oQD
#include <stdio.h>
y6a(FL6Q(`0t \Z #include <stdlib.h>
Q;X4z'N9rjE4X5|;L%J #include <string.h>rS"T H^ e1Nf
#include <conio.h>
tW5t0?!e? vx!j!\ #include <malloc.h>9T4|&sm.fa6h
vZ0h2]+xb}lC
#define STACK_SIZE 100
;VJ"{Y;| g"Ak L #define APPEND_SIZE 10
(^F'f*w6vR
8\ r ]"oM2FJ4c*B struct SNode{
sQEdW$T     float data; /*存放操作数或者计算结果*/
Ft9Q`uX)a'@}     char ch; /*存放运算符*/ PIyOS'qH$^o
};#q lK;^5Q+G/[
-FBWi+Z;c
struct Stack{5U&V\(Qr0c
    SNode *top;
G&Y Y u2Z6U7Q:w     SNode *base;+a/OI!p U#d2r Z
    int size;
!T5Kn9t!`| ]*[ };;_+w!]/k9@kT.l
WAc lI%a:W9H+Ri
/*栈操作函数*/
eP'wS L(Hv Pr1E int InitStack(Stack &S); /*创建栈*/)A Y~3_+N LA7A/@`
int DestroyStack(Stack &S); /*销毁栈*/
S#i G\RlU int ClearStack(Stack &S); /*清空栈*/
!zd'X&Wc9m/Z int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/*Mo _F'CK'H ]3u
int Push(Stack &S,SNode e); /*将结点e压入栈*/
5~L:bst|MQ R"g$K i8b int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/;f&X[.j!jq-F
X5|:ZuH'R s7^
/*表达式计算器相关函数*/
G5N1H xH(Lh char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3f!XE {h9y,c&Nc \ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/@ g7m-hF t&w
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/%u O(dSD
float compute(); /*表达式结算器主函数*/*BN X S\Qg
char *killzero(float result); /*去掉结果后面的0*/
:F0^ j6_ ^'A
v;l,k^ k/t K int InitStack(Stack &S)l4|)? z\*G Q)Q
{&X\pI:jF
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));&uB|Q|tX
    if(S.base==NULL)l6c8R3b%cZQ
    {&L5aJ+jz4S U0_!Q"b
        printf("动态分配内存失败!");MW8]'t6W2w
        return -1; YMQ @y
    }
MB/AbTS8EMvWQ     S.top=S.base;
#Y#I4f]IM YM     S.size=STACK_SIZE;
G+^.gu%G)e     return 0;
"W_ b vo)c(p }
0Oqr:UW4rz6C
u9d.Q PE[ int DestroyStack(Stack &S)6u.tFi-^~ ^6i
{ U6L)je+R*qsz9h
    free(S.base);
q.Ks#}4g j-k     return 0;
8?9O \$OyTuP }
@xAl'j g 'lNg @@BH [
int ClearStack(Stack &S)8t,C\&v1X[s{8e
{ L uG6lA;O
    S.top=S.base;
:X v O?u     return 0; zvxJ K S+D+S
}"z|A2x|*u
4S,JbCS!`}v
int GetTop(Stack S,SNode &e)*lR'o _ S7c'i'Cn7`
{7F6S-s6d5O[({
    if(S.top==S.base)?1qLlnW#m G)W E
    {![&} H^ ~Xp
        printf("栈以为空!");8}C6@1aXLQ ue
        return -1;%sT9`X&s
    }5?g'l%SCCw/TS
    e=*(S.top-1);
P'_;{*~-LS     return 0;
!TZ:?m U }P;\ Uv\|

8kebZ.Msv] int Push(Stack &S,SNode e)_+p:K a1}X_Q(P ~
{5bq}$w9`(Ef%y
    if(S.top-S.base>=S.size)3Lc3L?/^ p\3@o
    {
KG[)h}2B         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
,BL'd!J|%v:v         if(S.base==NULL))ZZLWLa
        { R y9l yQ2E
            printf("动态分配内存失败!");
tiv"u dDD             return -1;
xTM(lU.x5k6^         }P]!N X-S"n n h'e
        S.top=S.base+S.size;
&g_O0[OZ Z         S.size+=APPEND_SIZE;
@s"]]a{     }
*G`*C@q.^     *S.top=e;
obUwvYyc     S.top++;S%K Gn5dvJb0Y
    return 0;
2p^]S0d }
T+_r UsCj ~ ~MY
!y/A%iB+{B(c2D T int Pop(Stack &S,SNode &e)"Wu#ZgJL"U!^
{
5~C|O+|3b/Re     if(S.top==S.base)
g\DP ^6j8D     {x&WJUH0V
        printf("栈为空!");
M_q2m.eJ         return -1;
MK7k4]I     }
0y0k\ulp     e=*(S.top-1);
;aEhtK/HU     S.top--;b v?N(v3b+N'Q O2JD
    return 0;0F:V,K h|\2p
}
.q H$l%C d)ldE.[ H$V3TT'i \"J5Ux%n
char get_precede(char s,char c)
-{6p5m:w]$` {2vk;yyKW(zm
    switch(s)
-L i'cWI J8\Q&j     {
b} u3Fg|         case '+':                 
wDm*w:A         case '-':
s#D b Dg%i:Qq              if(c=='+'||c=='-')
J#~+IZ1p`                  return '>';
,Nm ugwV)bI              else if(c=='*'||c=='/')5n0VVFu v(P
                 return '<';
1Q _1Bm7_b"F(}              else if(c=='(')L#d7P+T2aX9Q
                 return '<';z[-})} zc'P&V&u
             else if(c==')')
#K$R6i Q1i0t M*p'R                  return '>';
;u/} _;U7]0|;B1DY              else
{2B|3Xl;nYcS/S                  return '>';
h8\$}-|xnya         case '*':4km!K7z9|a
        case '/':*t/Z8nn6uJcu$b h
             if(c=='+'||c=='-')l I/Sx3QX0Ay y
                 return '>';6r'X8X B(y0Cm!TD
             else if(c=='*'||c=='/')
uPGA d+O'c!Y                  return '>';
*X,{)S*e:w&?!l s              else if(c=='(')m nf1K(s9`e-f
                 return '<';
\i/k9Q6O:Wh              else if(c==')')z^e6n0\P6o/OM
                 return '>';
nN'Rj yCtq6r              else
2kH`/K'|m#cMT M+mK~                  return '>';
F-YkSUJy ED         case '(':6w'J5aQ3NW&Z7k0M)?
             if(c=='+'||c=='-')!? ?`$M!y^z
                 return '<';+W$zOz t
             else if(c=='*'||c=='/')"V T2STor K
                 return '<';m0[]5zr
             else if(c=='(') o,`VH ~4N"k
                 return '<';
,sInX,u*A              else if(c==')')
)O;T;m-m#x |S~B                  return '=';;o4K\q"JGPR I5]QR
             elsew.G:D.LV7\$k6G+U0a
                 return 'E';
cA6T;s%GX/T$P,J d         case ')':3\C+?-zv ]u`-u7@
             if(c=='+'||c=='-')
0L:{.QI+YN                  return '>';
o'|)U wb*Q2f              else if(c=='*'||c=='/')
n yoO IC                  return '>';{!O6x)|2le nU~~z
             else if(c=='(')
F:k5v3b#dS;c9N                  return 'E';N3EYItp3O,~e
             else if(c==')')1f2}#}6?:Qz Y
                 return '>';
{O4x z&fSJ0hX              else Ym OrH)wi`\w:H
                 return '>';
*G;FBLl a(j.J u         case '#':;g}Z FF
             if(c=='+'||c=='-')
!c)s K"o"`:| _                  return '<';
#V w0vb'qe              else if(c=='*'||c=='/')
_at+Efd                  return '<';j$T+O%i!HpU+B}
             else if(c=='(')/d3X E@:PimC$it
                 return '<';
.P$xQ#Kt              else if(c==')')"Y5V9TDe)bQoI
                 return 'E';
9f(wQ*q grT+M              else
&SR eJID I                  return '=';
U_#\J$Rw ~         default:7rei*fux
             break;/`o.G#q*~/]
    }
j.Ti4}v`Z6P     return 0;    9Ps8IpL
}"dH r~8pi@@4];m%Pu

2d+TP$y o~ P-p int isOpr(char c)dk v8I(G{`1m
{!A}7^,IW&g
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')\H Rhm[+}
        return 0;8k I^&R8R#uT^K
    else
aD:Rp:Z nA u         return 1;@ _ga"Z:L.K6G,r
}
/u AI.t n@ n O2M-TN'W;u4M
float operate(float x, char opr, float y)
D[ bR4FC K ur n(`/D {
*q:\"j? e\Av     float result;%w.tU8hU&Hb
    switch (opr)lneB7tV%p}/i
    {
JvF |`C         case '+':
4e gk K6?8J3qc5Lq4L              result = x + y;l#|N`)v}} j
             break;
S$z NT Q6g;l'f         case '-': +{ Mh:R9o[M
             result = x - y;%c#FUZp(W
             break;
8R |{*h9~         case '*': A8o%Gr;? |)o:G
             result = x * y;
8_r*|]$kI              break;3h7rS0D B!I-z
        case '/':
aRM:A#GE1w3n`              if (y == 0)ZH+Qw-}I#@?;f
             {
d7n1f3q1H\?Op                 printf("Divided by zero!\n");
:R&V}2oz'mXV                 return 0;
(o/y7hY&Qp,I1T!HU              }
h#R`Dn              else
H B^V0y(k.@C              {,ag c\1b5SV&|
                 result = x / y;f0_#ni!vA:@ C9Z
                 break;
4gI@&F UN^ B:D k              }
Y~m&v3@wL)l        default:
4fyS r6F-TNy              printf("Bad Input.\n"); m|`9cHywA*T
             return 0;
6H0Z:g.y;P     }C:Gwe+|C)B
    return result;6yN\0^k(hRG
}   
IY6l c.C(i N
4y0_1DG7A float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/H1vdWe0dJ&lY1XO4D
{
)E-c6d |6VDgo&R     Stack optr,opnd;{dm%E)I%N0O u%S
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
fda"]-uzIr     char c;
.\6``|fD3\ }+Xb     char buf[16];
;h!jm WgL$L.p6l     int i=0;Dr{9kAnB_m
   
#i$Ei2]_~QUh     InitStack(optr); /*用于寄存运算符*/
h6h%U)Wl|2J&o;`     InitStack(opnd); /*用于寄存操作数和计算结果*/X5E8oG^N/h2t
    memset(buf,0,sizeof(buf));
eK0p6vDNX6UpD    
I5\ A9wg](zY     printf("Enter your expression:");
V3H XP_iO         tqrvI [h'n:]g!x8?)?
    opr_in.ch='#';
LJit!IZU5k`     Push(optr,opr_in); /*'#'入栈*/({:WU%F\x.\)S,mY
    GetTop(optr,opr_top);"|u-?:W&u J F4[Z%F t
    c=getchar();\6G/cQnb] [&XIj
    while(c!='='||opr_top.ch!='#')
_0W"C$q)ZXu_&E     {'[.^1Jz)fC{h
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/8k"r(yo@3P0t
        {
5z?M B6wN5t             buf[i]=c;3a)g#i(x*r5c ~
            i++;\5YI xG ah/FR
            c=getchar();
5@\)We{ U         }
0qv9^gh@         else /*是运算符*/9_!F G? G4R M\6c\
        {
k&zx)^2n3D"y"K             buf[i]='\0';v{jw&R2@
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
f/U)yz2SNZ:c,x             {
#Jj.SR$Al$J Sqp                  opn_in.data=(float)atof(buf);
@d'E q9m^O w                  Push(opnd,opn_in);
}#AU-uZQ%W                  printf("opnd入栈:[%f]\n",opn_in.data);#`3j:r{{7d:r4?4o
                 i=0; j0h:CW$V+h
                 memset(buf,0,sizeof(buf));kz"B+lI C4G
            } kZ"f*uMop
            opr_in.ch=c;
"s:A UQa8a             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4rRyp+Ih
            {gJ!H)Q:f4d
                case '<': /*优先级小于栈顶结点,则运算符入栈*/)O"GZ2c kv@|
                     Push(optr,opr_in);Dp(d6bw1Bn3y$m\
                     printf("optr入栈:[%c]\n",opr_in.ch);
d(D:dN bt ]                      c=getchar();
W%\CO ]/}!ve \                      break;W"ppIt&K3y
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
s*l1Y j)WR                      Pop(optr,e);!N"A/jhGy"|y
                     printf("optr出栈:去掉括号\n");
9Xj#~T9_X Rir&w5S                      c=getchar();,m UH&c7[;g A
                     break;;YV#b K4y3?uv
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/&j%C%wq KY{~
                     Pop(optr,opr_t);
4KQ'[[ Dzf                      printf("optr出栈:[%c]\n",opr_t.ch); VG5^G&u$P7O)d
                     if(Pop(opnd,b)<0)
&bV'^X4@|6ko{                      {k9M a4^v-h
                         printf("Bad Input!\n");6]'K|8D]wP
                         fflush(stdin);x'\9i0v#l2_+L-x.ai
                         return -1;
1C a9h]!H1Q,N7u M6f'M                      }bx5ks8I
                     printf("opnd出栈:[%f]\n",b.data);
Y-x\a{pp                      if(Pop(opnd,a)<0)pBCj2_ v7aC0EE
                     {
"p;B3T_B@B                          printf("Bad Input!\n");
D I$yRf w3~4JY                          fflush(stdin); w;F5DJjD0^
                         return -1;
z8~;d6Bm q%~6W Y [s                      }
A3qa~Uy_                      printf("opnd出栈:[%f]\n",a.data);
{JPirW                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1z8B a'EN-]
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/*^`1F/lj#O d2x!S d,Q
                     printf("结果入栈:[%f]\n",opn_tmp.data);
9[9N\8sO                      break;
*z i:~W/e,J|#Z             }~_%AK\ cy
        }'f[*?0iH
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
(Y+? cY$GV0x     }'bD1yc'v4q f
    GetTop(opnd,opn_tmp);w.m'Vf-J7D,z4~
    DestroyStack(optr);
d1OR5Ir_mE.R     DestroyStack(opnd);F8PU{V/S
    return opn_tmp.data;4oh0c F4U
}.`+\e*Q$Y
FYgVE1{c5Y
char *killzero(char *res,float result)P3Q#pUGX
{
N c F:lo^ s"Hf     int i;V nX-AGSO5n5w

D`3R$_d9VQ1FJ     sprintf(res,"%f",result);;R ab$k#[;wE+y
    i=(int)strlen(res)-1;
4t,v6R G |F'F o     while(i&&res[i]=='0')
lERz1cse.o0C     {
zS:P4?1N ig         res[i]='\0';K"k jS Y
        i--;
.z \7D^7} c     }PQ4W*_-g0A @_ c
    if(res[i]=='.')4}1}/V V6i3K
        res[i]='\0';)DAz0g8BW{I"w
    return res;{C\Bm M-T
}U*\u{lU_Fs,on

2ZP7~ Uev$^~:Y$` int main()
&rc TS z+@ bT:W {
{z%]GOI:B2kU     char ch;
~-M)[ w"xL"]     char res[64];
[F%c4o @{ f Q     float result;
e|W X)l rrA     while(1)y9R.Jj1E e"UZw
    {
4Ec Ycm+w0n         result=compute();^ V l"iT.s
        printf("\nThe result is:%s\n",killzero(res,result));#p%H1IW*K'd
        printf("Do you want to continue(y/n)?:") ;ZG,W s0ED+s(| n'GY
        ch=getch();
t+hEc"lq5pA'{(]5A,|         putchar(ch);7`'B[)U[A*P
        if(ch=='n'||ch=='N')
!g TR l)M7u%Y             break; g"Uq?vPV
        else
2Qs M*W7y)fa*| e             system("cls");+o`3O/yv,o!iS
    }
.F QN*sh}8LL     return 0;)bNz$f*P
}[/i][/i][/i][/i][/i][/i]%e,Q2P n7xxG~
E qQ3I5F"l:i
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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