捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.ur*ji(S/|?G"Ub'rU
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=O.ZAL%C4n { Y^4{w
/**************表达式计算器************/2H[+H,P/M!r:E
#include <stdio.h>
|$Y c|4X6Q+iM #include <stdlib.h>
^h"tX:W,E #include <string.h>
8Y2SVl(gFx4Dp #include <conio.h>W `FR3S
#include <malloc.h>3JYl2h8M
j ^9r,RN(SR
#define STACK_SIZE 100
!T/Xn |g #define APPEND_SIZE 10
G+p"g z-N|oz .Zdfp;}-x8[P!?
struct SNode{
j1j?ZE@     float data; /*存放操作数或者计算结果*/
j&du&q&AV     char ch; /*存放运算符*/3P%N`8P*{[
}; L IL2fF
B/].Qdv
struct Stack{F MTcQZZ
    SNode *top;8`0LGs3w'b/w+l'c
    SNode *base;|t~ ~0O&X d
    int size;V$T0]SJRd.N
};
#kwE_RV UE ]E,_y
/*栈操作函数*/B;aT)K2U
int InitStack(Stack &S); /*创建栈*/$kH'i2SJC6j
int DestroyStack(Stack &S); /*销毁栈*/-a9gZ$F+Ih
int ClearStack(Stack &S); /*清空栈*/^5j0bi e3a2g}&L5M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/^s ~J z"E(^ X
int Push(Stack &S,SNode e); /*将结点e压入栈*/
:W"}VER2} int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/aqu!Y5} M5b']
b6g ?2sqD&EQ
/*表达式计算器相关函数*/,V J*nC;X*|YE
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7N!f8P.JOZ
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
b)h8lq{\ X YU float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
ak"{ui-p float compute(); /*表达式结算器主函数*/5rAj)X Ry
char *killzero(float result); /*去掉结果后面的0*/ 5}O;x2tGj+J

Dn1r|:H int InitStack(Stack &S)Zq7uf/dAy
{
!n T)~n;bLXO1R     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
nG7_/D+a     if(S.base==NULL)(\/G+y%]\ tD_)F
    {
~l,U#X?)\         printf("动态分配内存失败!");
V4|G?i         return -1;
,I:i7{@$G'nJ     } V4@/{1L2H)l)@:xw
    S.top=S.base;q~ Z ]6H"^
    S.size=STACK_SIZE;&i5N.}a5l?
    return 0;U~s.bi#\ O6?^
}
-BV.^qG._9ksQ
%`R"aQqo ctH int DestroyStack(Stack &S)9v"Y_f&u7v6q
{4VMsGNr
    free(S.base);|8~.[_:Y5a(Mh%b
    return 0;
#MRr6r5|h R }
:])M4i8Qg5N
g:h,^*U3[ int ClearStack(Stack &S)
:p7~si ~ D-G { F0~!qTEM
    S.top=S.base;3~2X.[#[ygO(Fm
    return 0;
lo ?m+_:_/_%W8B }
.kZ'LcsVL
kpI[Jp int GetTop(Stack S,SNode &e)
_}_!L!K-b.? {
}5MJ`h4PS     if(S.top==S.base)E1}EW*mUO
    {Ca4XO:z
        printf("栈以为空!");
z;kc{l#r V$u         return -1;
&r8Mp \ O g!y)R     }
Rb/B/~._ |3O!v,k-B     e=*(S.top-1);2o |*p8J/_
    return 0;,n Sb@ |x B
}
jnp5c3]'\!{`\R 6K/L5?krj2W
int Push(Stack &S,SNode e)
!P?3DO!{d {4kq2YHe dO {
1wvp}*`"h t#O     if(S.top-S.base>=S.size)
Wi,IXFrr0x}     {
(v8d@6^/[         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
N h\7MY&pFR         if(S.base==NULL)^,f.c)^w
        {QRnxm'H~O ~7[0U
            printf("动态分配内存失败!"); yN Rh*AN }k
            return -1;%Q m4O)I,?
        }
:OB-@p z4p4jC         S.top=S.base+S.size;I1vi(P(N:j(M7H] YJ
        S.size+=APPEND_SIZE;
qq2j{H)B a*O     }
g${,HC az ]     *S.top=e;b4_;Z Go-~h-L
    S.top++;H|(ir S!\&i"h
    return 0;X]/T'U)lra
}
.fnk E K )z)PhSq"L"`k'c
int Pop(Stack &S,SNode &e)
_ _Fs g2e0~ wC {:i%s8bGQAH6c#K[#N-_
    if(S.top==S.base))nR1R^^8x
    { { qpmg%uHs
        printf("栈为空!");
i|(?U\8ai&{h3U         return -1;
btq6vi#dY     }
)K2b}-|8a^~ kc     e=*(S.top-1);Ek;Z;P!Vt-b9b2A
    S.top--;3pn7Y)l$o;ND
    return 0;
1[bnS2eFe#?\H y } c|?Yu6nmWh!B

C Gj R)F&M{y t char get_precede(char s,char c)
8Anx'`9S {#cb}"i!L2`|
    switch(s)
Z^v?Pb9[H&B     {
#A.czaR0xl         case '+':                 
QQ.}u(n         case '-':
STF,nAZFEF6s              if(c=='+'||c=='-')8Rb[ P"j3Zs$M
                 return '>';6I:G hu b
             else if(c=='*'||c=='/')
vD(iM @}-D h p                  return '<';*}W_"Dq7Os
             else if(c=='(')
ss ^U~f])e                  return '<';
A`7w,I:qxZ7t |8M              else if(c==')')5i E,f zF/Q9j4H^7H
                 return '>';#f4k&BV WRb
             else
#B`:\!Ip0g7W%a!J&C(u/~                  return '>';t5Q'n4YD4^ Bl
        case '*':#] R-z-r:W)?1FP"k
        case '/':
| ]}+v ^];]$U;a              if(c=='+'||c=='-')s LV i.[(j!Um%Q6f
                 return '>';
-Vp6la%td&DX-O              else if(c=='*'||c=='/') SDF;RQ@
                 return '>';
H#Bw9?KF5T5|              else if(c=='(')|c hkk#mzi
                 return '<';
I6m] aw]k l[t1G              else if(c==')')
9o8Vf|H.b4iI+f,L,l                  return '>';
1w5E`Gh8^[              else
| G` a0{II3U                  return '>';&|!`o7W:^q2p [
        case '(':
hc/KhjL.?*Kp              if(c=='+'||c=='-')
LwAQ$p&[P1ee                  return '<';
dEztH'B5g"s sB              else if(c=='*'||c=='/')v'Fr:kj
                 return '<';z,|,AK Tmi@
             else if(c=='(')
A"gy7i h&OKD&X                  return '<';FA,[c:L(L!@;s
             else if(c==')')5n XUU{8I I
                 return '=';
Q8i*urTrvvq#y              else
7Od4~0M f,SB                  return 'E';$fdL\ ]3tR
        case ')':?Kv9K(H0QP'e@
             if(c=='+'||c=='-'))S-_)D Q%J)R3m
                 return '>';
FDG hsmk$K"OU              else if(c=='*'||c=='/')
+X8Ud3KG,A                  return '>';
K2]nu6T)j              else if(c=='(')
m`NJx.^                  return 'E';L.HvdH n{G
             else if(c==')')1w!S)W*xlIz*sV
                 return '>';!Y/S2_0O?8A O^:fsm
             else w#r n,K M"f&E
                 return '>';;O3_0Z7Ol
        case '#':
'm%Z#\ W$H/J7|#Md              if(c=='+'||c=='-')X B#g {[H
                 return '<';
+C1p8Yd~ xZUlYK              else if(c=='*'||c=='/')
.[ N,K'p"p/wd                  return '<';
4W o*n3DC'`;~]              else if(c=='(')oV*E&~~E!h(^r%Y
                 return '<';
EW{6y5S:ARR              else if(c==')') {kU6AT-H/C
                 return 'E';
mi:{Q/k Z,Z              else6rM*x eY_t
                 return '=';
9b;E{0HF4dbM g         default:
D'^U-_:HVWd6i              break;"u0{S4?(`9?'UP
    }h"d0hb2V-B
    return 0;    ;U&m(pZ\U~9Z)F;m-IO
}
t@u Q)S a4d0I zK%I6HP%aM ]
int isOpr(char c)1]1Y%q*^]-s
{"W [&FbRN m
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')zVv6{+{U1Vd"hl
        return 0;s%V h-h#D W o
    else y [LC`
        return 1;0a&d6S{7gd)p
}JZb.DOj!X;j!c(c

4e}Kw w4O+P(P float operate(float x, char opr, float y)
p[L'[/P t [Q {
}N}_#d'Pc p#o     float result;
`S+eL e SPF     switch (opr)oL])R4Q
    { c$E-d]g${$t!DV
        case '+':
,hU j$Y}p3W)RP7\q {              result = x + y;
fS uBXA7m              break;
G i y)L/Ux"S"Mo         case '-': #b{ez;fJzP4D
             result = x - y;
I~/mLp,g*e*RXP#f              break;
;g%RI(Fy#x         case '*':
w'J"Fjy@_J#}j6f              result = x * y;
5Rl&l \ QC_ e              break;
%t yIj2dyh         case '/': [|(f'_0b3{
             if (y == 0)*U U]/p E
             {
I/uTqI                 printf("Divided by zero!\n");
1rls"gV {S)`                 return 0;#V})tgp;V4pV#X [
             }
:\!Z k"WYE Y ~ d              else
2K#J"X0|%EX              { ^U;kw.@ C xj.R(V]
                 result = x / y;3P}6K'W `,y O
                 break;
~*s/ZM y5xCk              }
ex4r|S!V.i        default:
g'Mi hMuT              printf("Bad Input.\n");
rF/Wso}              return 0;(Xmg3kt)V i
    }
U-b3v3TbavC5`     return result;
{s4hq7@O{ }    C3})X a/D?Le

+s9z4ElrTD5O float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6] A{tlk\m"P7h_ {
4^n9l[)X9j4Dp @3mi     Stack optr,opnd;
7LZ:ssvAN     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;&A QfqW&O~w
    char c;
YbipbY `i     char buf[16];!L_{;R }0KRP
    int i=0;:}-i&g2N(w
    Q8V1{z6@[ FE
    InitStack(optr); /*用于寄存运算符*/
0nv:}K oj4y(L ~L     InitStack(opnd); /*用于寄存操作数和计算结果*/
9tzF|h`$}     memset(buf,0,sizeof(buf));p r3n8]Y&N]z+zY
    v S3a0[,u%@/Y(U B
    printf("Enter your expression:");
;xL I.P@_l {)a([F         
Y oF2rI%m6uQ.v     opr_in.ch='#';&U?'J(V$M4Eq#i
    Push(optr,opr_in); /*'#'入栈*/
G~H} O5F     GetTop(optr,opr_top);
O+[n ^i9n T}     c=getchar();
$C2\fC(_&J+K)f/\H     while(c!='='||opr_top.ch!='#')
bDN;T0B%@)H     { l$[7M,V8e$x7qG
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/} r1H/QDA
        {\a+K7O{
            buf[i]=c;
,M6T+~,f~.d3B             i++;VBB.V t B:v5S
            c=getchar();.oy4}M5\C/XC/q7Y([0U
        }
fp2^8@y8H-u         else /*是运算符*/eK#P+S;ONa}
        {kQ#] n3Z @z
            buf[i]='\0';
UT6X7Dj{;dW             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
TgX`.Q&Y             {~F,QN/[2K'iz
                 opn_in.data=(float)atof(buf);7s:`_)] Fi*Y{B9~vj
                 Push(opnd,opn_in);N,Syoe0O]6E
                 printf("opnd入栈:[%f]\n",opn_in.data);v z4sy,[Uu?
                 i=0;5t)@.gO*\0Sg~)C
                 memset(buf,0,sizeof(buf));
/lqK?GBW\%~             }
){m;W2hL             opr_in.ch=c;
]4M)A9o3M%yR(|9b-s             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
umraV7yjh,w#F             {pImz9d?
                case '<': /*优先级小于栈顶结点,则运算符入栈*/:Z3h8l;F,^z[
                     Push(optr,opr_in); |]s3~ab
                     printf("optr入栈:[%c]\n",opr_in.ch);
(\#w+pk&Gw                      c=getchar(); I nDe J:R#@
                     break;.A~q#rnY
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
w2S}/vpaG                      Pop(optr,e);
IH.n6n&S0w                      printf("optr出栈:去掉括号\n");
QWz lT V:z"f-c}                      c=getchar();
l'qs WzS                      break;
Z5u9c3G,I?R1NN                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/mSg]$s
                     Pop(optr,opr_t);qG][ LaB ^ L
                     printf("optr出栈:[%c]\n",opr_t.ch);KJ k;J3F
                     if(Pop(opnd,b)<0)Z{n]c;h"][i
                     {*J|,` H;~4NpD9Y3o
                         printf("Bad Input!\n");
4Tj*oV"W N%g*v/{.i                          fflush(stdin);
bz.RnG:^ H!z#JF                          return -1;
&we*?N5B f te|                      }
m{#g;bW&K I                      printf("opnd出栈:[%f]\n",b.data);!Y_ { bNT7R
                     if(Pop(opnd,a)<0) t!D*J0vRs1y|
                     {5H3[0m0R9^~D3z%k3D
                         printf("Bad Input!\n");0Ro@f'AIY4OD'b
                         fflush(stdin);
]+ie {f/t_                          return -1;
+?H7B1jE                      }!P'y w C9Qk&t
                     printf("opnd出栈:[%f]\n",a.data);
D(tU^~~)a M K)B                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9rQ5S(V:Plw^c                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/d K Aph$N[-r
                     printf("结果入栈:[%f]\n",opn_tmp.data);
:QvD6~] w M;ht                      break;,Sl'U-q^-l
            } IaA%h)]&IL
        }
_~,soF1^$F         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:Ihc*zz e     }
bm6sws:UV     GetTop(opnd,opn_tmp);$E,N4i8`[
    DestroyStack(optr);5xg![ b~-LJ*BE[np4B
    DestroyStack(opnd);
5a"]2di3oB T7Tt     return opn_tmp.data;
cSO8KI }
*[2|5H n&F Msc)F h["nv2`^
char *killzero(char *res,float result),T:s@HdSS8ye
{
4N|$}J3l5Y6Yt     int i;/L}8LH\^
s d'K;_0k E8L4I)[xx
    sprintf(res,"%f",result);
bsyM!\$OE ?9BBMw     i=(int)strlen(res)-1;y_,G _M^O
    while(i&&res[i]=='0')t&QF3aJ~ xv0]
    {)WU/WiR)g {_
        res[i]='\0';
fheA-P D._         i--;
ZMYAJ6B     }%F'uL'Lf
    if(res[i]=='.')/t0ys k*F7\*`
        res[i]='\0';
4dhya"u,M:JP6_     return res;
@M)m['c^;Y1Y7@ }6n$Km j"{@hK
){4j6I ^De+Xz
int main()
iQ\_(Yq$o {&?o0vp%i8l%P c*h5A
    char ch;'I5No"v3rY
    char res[64];
|$o z%~Sm     float result;^-c6B k Fs5q'R)@3Q
    while(1)
4f.F9G4v1u     {*T s-{ea n4~*KXu
        result=compute();
,zC.{ZCt:ko^h         printf("\nThe result is:%s\n",killzero(res,result));
9P'Sx&C A@D T%K         printf("Do you want to continue(y/n)?:") ;1P(S;}d)c
        ch=getch();
6G;lc1y0hIL/aur         putchar(ch);
|0`i2p|C         if(ch=='n'||ch=='N')
-y+V ](X5iF!N             break;
m @'OT6U.jk         elsexwx1P.{kj(|0S
            system("cls");
dt u/Fx.Z3w     }
&\.W6f Y]&|:v/t     return 0;
o.I dm;yw$w }[/i][/i][/i][/i][/i][/i]
6XFrssi:U euyE[\~.m
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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