捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
-h RFq a{ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=NWzC] {S
/**************表达式计算器************/
+} b%zpzu #include <stdio.h>
,? ]q9U,jF m #include <stdlib.h>
)M:C+WP&~b&l&`y #include <string.h>T(y5P"T/Y ZT^~+F
#include <conio.h>4W oO;c3jP4g
#include <malloc.h>
k4jT D)i2D$s9\
C?#Vi'T*l:x,}} #define STACK_SIZE 100Xa4Q#\P7BRS7kCkr
#define APPEND_SIZE 10(K#Ro f9R*r8t"l
2Q*pY+N6C5R&rO
struct SNode{
$pS_&o~V9H     float data; /*存放操作数或者计算结果*/
h!KY%EX     char ch; /*存放运算符*/0`Xgx+q1h
};
:dst#Ph#J5q2f
FZ,d|0m struct Stack{
;v:|'A;at9C];W~UD     SNode *top;
%D)v+ruP#s1j:i7T^1i     SNode *base;Ssd!wf$f
    int size;
[y@m_Ol@i };"]|b6Y-r} x"V
4u7\ X/H"o$jiP
/*栈操作函数*/'cu#O3Y(Q&z7H(Y
int InitStack(Stack &S); /*创建栈*/4^\ |0L9kh.V9v
int DestroyStack(Stack &S); /*销毁栈*/.D-ch9L Dl+w
int ClearStack(Stack &S); /*清空栈*/
7j0AF9sB*oc `~!Y"` int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/%A-n~1Z,zA;GJ(D
int Push(Stack &S,SNode e); /*将结点e压入栈*/N&R8}!K8vWx
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/e!c(Mp$^)h:[

.Q\P'B+N2} /*表达式计算器相关函数*/4`H X!Kp
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
TM+Q-J }3~O int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/8`t$|7d)m#~+f2@8`
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
-T1OI/J5G1A"T/}o"f8R float compute(); /*表达式结算器主函数*/
Jxw|K? deI char *killzero(float result); /*去掉结果后面的0*/ P[5Z}#A zKF6_%i

k%pq4LDZC2Tr!S int InitStack(Stack &S)
N$n8z8g%f:_0V? {
P/kW,|1E     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
jWI5J!\@8dRi     if(S.base==NULL) @U4Hc%[0?3k C
    {
%FP ^xqJ or         printf("动态分配内存失败!");-e!g4^.P2F~l&J
        return -1;4Q7kz(ysr
    }
/}*Z4I:f"x4[5AK     S.top=S.base;
m&D%y A~p_2d     S.size=STACK_SIZE;-?d:ipK`"\f/iY
    return 0;
!v%Z@*G#B)r }
j#SW'W}']Y
7U#W9]S d$|9{| int DestroyStack(Stack &S)/ly#R(hgE2y,ft
{9J`a6d,bxA o R
    free(S.base);,N;Pv%k!p a+G} P
    return 0;
K ktm?#_)@ } g[5XX0{U;i%wc
L|/uXl9Rz
int ClearStack(Stack &S)
W!Qu/l.j {
*{ Nsu?C/g]C     S.top=S.base;
2E;`6h!O5^ktN     return 0;j~+s,Ya
}
8S:g4`L-S? L{
{)^N Y:Pe(Ee int GetTop(Stack S,SNode &e)
Ll7Y r:Bren |b5S {F ?7TL9Ik&qQq
    if(S.top==S.base)
-?qF8K Y Q0]/G V"X     {
EL"u/u?gj6h({5H w         printf("栈以为空!");RyU,R(toR
        return -1;
zt`1B?     }
Y1oS7J.k     e=*(S.top-1);X&F ZQ jY"G L!~
    return 0;ZAa@Y ek
}
%N.x UN KFa t9Y `s:M^k
int Push(Stack &S,SNode e)y pt\7bW}
{3XpU+G6A&}ys l
    if(S.top-S.base>=S.size)
s z3U7F1QU     {(n,~?aM`3iW
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));Yb.b@"oX7|}6n9~
        if(S.base==NULL)
E)u,Vx3{+MU4K2{Y         {,t-g-q;`I
            printf("动态分配内存失败!");
`DP(wb&x&_             return -1;a,i ss#b7K[ HQ
        }
qpv h~A'[         S.top=S.base+S.size;
y%[z1C{9]         S.size+=APPEND_SIZE;
7I!~Vq'hv Uv     }
V&m&gbm)NYxkJ     *S.top=e;
f"\g f'j8~q!V     S.top++;
i4U;h-Z/[-|Y7}|#n;G     return 0;
7|Qo;fsV G3d }4}7SG6d)q z ]

,a-g#F7m1^t)mC$Mu int Pop(Stack &S,SNode &e)a T4^I/YLr6M
{
WFI#Ao)vf     if(S.top==S.base)$` ]"]~`
    {
W(D$A8O)qMb$i         printf("栈为空!");
K#f\nJ!B;iI         return -1;*z*}Zw D+aa
    }^?F0g8w(e;| A
    e=*(S.top-1);LS%zb4q2g/m
    S.top--;
kE2O q |VT     return 0;"hY)^ [H
}
MOT%? T U!X'a\.KQ
*M7zM@Ck`!^ Zr char get_precede(char s,char c)
B;w z)j x Y QU {
q6b?9|I     switch(s)
q0D{(tk;Y k9m     {
Vb2u@hegt0`         case '+':                 E O~!lL7| u*\6X
        case '-':]@ o-Y's ~ P&s1\|Q
             if(c=='+'||c=='-')
$v3h'A+S`rb2z                  return '>';8O0j)s S$wr D
             else if(c=='*'||c=='/')
m)J5~K0k)s5J`0l                  return '<';#gMz?|+oW
             else if(c=='(')CY*a'M"J9?%R] Z
                 return '<';
O OoGCT k4HK-u              else if(c==')')&v#k:[ t9o!efq
                 return '>';b)D-K7]?c3K PD|
             else 'LugGT5u.HW
                 return '>';
@h&{:x7p,PW+o)zZ         case '*':
7|a ]bhs2zbv&Cn         case '/':
W8uK]+d%kl;QdE              if(c=='+'||c=='-')
-Dy(b,]3A                  return '>'; eg*o TS&I:[
             else if(c=='*'||c=='/')$UVc#VeLH{F
                 return '>';
9ln!hp.i o2X              else if(c=='(')d y }6k e"S)S!gV }
                 return '<';m+e%OY4}S,Q$V
             else if(c==')')
S*kAwI|Q#A5P                  return '>';&P7|;bn1UX+z!Z/K
             elseb1U_r` o)T?
                 return '>';s7P7O3g!C^h wS
        case '(':
hk ? g2aqs8\xY!D9F              if(c=='+'||c=='-')0d4R7N2k J0Bx
                 return '<';6Yi"b ]}S X5U
             else if(c=='*'||c=='/')
Nd-?+k ]&B"N                  return '<';
%_]5P3P*x1Ec              else if(c=='(')
bG!y%A e!E8Hvw*T                  return '<';
t;Lb vy              else if(c==')')
lY_:`N:[5V                  return '=';
9h+G n-Q6h5`Y-m              elseB/~'lZ1W l8QE o5NR!Z-[
                 return 'E';qe d+b.\1c
        case ')':
!ADwe"x-|0n              if(c=='+'||c=='-')*gw%q9WBq"q
                 return '>';-w"E.HiSfL
             else if(c=='*'||c=='/')eyu)@xd/\
                 return '>'; zv6{,p"ps6Q d
             else if(c=='(')
v8Z?K?^ MvW)|g                  return 'E';&T;_'mwr6pP
             else if(c==')')3}uHZ^o%x
                 return '>';'e|L&I3~9|@
             else9|F&DdyGm
                 return '>';B5rT[&bL
        case '#':
fV} \&mwNL}              if(c=='+'||c=='-')b:bQ AIHA:IB
                 return '<';-V*v"D PZ|$v
             else if(c=='*'||c=='/')[Y(pB!j]7b2A
                 return '<';
CY7A1T~0E              else if(c=='(') lf*t#e[u3[(] x
                 return '<';
!ts]@)p!CO*n              else if(c==')')K%k"Nj;RD5oP1^)j
                 return 'E';JK At!VV ZE-p
             else5g'Y9s|Ym n~
                 return '=';
MflE E"y         default:
$\n z ^r&h'{"|&b}'p3g)f              break; m(Y3DK)a
    }3z6k#^#^!r
    return 0;   
ez pJ M5DJ }pE(?.ie?Z s
&rV J/a:Q\%G6vw
int isOpr(char c)O5z`/m5_ f*uj p
{
3_(rIp"J;\@OC     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=').t Al'j.k8cGn
        return 0;
ofMP.c}*g     else
v!JT G*l.b         return 1;
-j2z3M@r x9t }
^ dO YBKU i1@ x5}Rq9P6R$jp p
float operate(float x, char opr, float y) Kv6Fo!d!i$\F}
{
3a}y-vg7MJ     float result;
7IyA&R-{"a!pt N     switch (opr)
#Z dQVd     {
y)qqh'{8U&v7{2j         case '+': 8{*y;U0LIL@ [,o4V
             result = x + y;
V TfeQ              break;
L/r!AU9Z8b         case '-': )wm&mp*T!s}#R
             result = x - y;
$D7M:Q&E:m8HB&D              break;:}Nw.T\S
        case '*': s g2|[/Noe
             result = x * y;
b[cx0e)H_              break;*f'RO Ia'wf%zW
        case '/':
ZzMyu'I,B              if (y == 0)
%Z lnV%{Z              {Z9R0pal~
                printf("Divided by zero!\n");
GU0_E8X~ e                 return 0; ZA v%Aw.I,_r
             }#VSju7]&ZE
             else)J%I/T:h ?3[,Zq
             {
l5@S1c q3H                  result = x / y;/A @ F` lc
                 break;
)~.N1nRSWex              }
(A\D'_#g+R]9~        default:
|:d'Y*\*k d3j q              printf("Bad Input.\n"); av/v M:gq}b-F
             return 0;"Pv Wn8T/I,VUiBK
    }Q o.{$OJ'F@)N
    return result;
K$E!D?JDG*QzVu }    %W5`p{s1SDx|_%K

6m9}5T8m\)R*U@+z float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
(WV mr_0z j!dv5_ p {
#ft/Ec:x:` wy     Stack optr,opnd;9@7_X({,h%|y'T
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Gc.qb hp$R     char c;
%y@f;^0j iN     char buf[16];b4M!_ f/KM V
    int i=0;4u4o Sr5ed
    wDS2}]{ W
    InitStack(optr); /*用于寄存运算符*/4q#w+S { jK F0\
    InitStack(opnd); /*用于寄存操作数和计算结果*/6]/B6^|*jE/KZ)B(}3?$Y s
    memset(buf,0,sizeof(buf));
`+?Bro/@!h+o_     l)P D/{~A sv&G
    printf("Enter your expression:");#o({Wl(C Z
        (u0rRO+C/O9DH
    opr_in.ch='#';.m)pp0^;| _D W\
    Push(optr,opr_in); /*'#'入栈*/
N]W mq7KH     GetTop(optr,opr_top);
/E yj0aP5O P     c=getchar();'g(tE Bf!y4]E-q,^
    while(c!='='||opr_top.ch!='#')X_&mR|g!ay6}Q;Tm s
    {
#cN+x:t2F         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*//y;p*^[0G5W
        {
9M.h"WEH4PpnEc(Z             buf[i]=c;GU| E`I&{&P
            i++;4V-q xA_Z Y
            c=getchar();
|(@j[7QaOt t         }m1dK+N$r A'kn8GR
        else /*是运算符*/+^(} W*J0BL_
        {n&Y yz@)n5sl
            buf[i]='\0';4iR ~2wb;v
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
0PTu$K8cY*g}             {
esC(E%S6s@N:Xb                  opn_in.data=(float)atof(buf);
'Q8MIw$V                  Push(opnd,opn_in);tl Sr"u P!_
                 printf("opnd入栈:[%f]\n",opn_in.data);
_4b*O+F M'j EA                  i=0;
R8P&sRG                  memset(buf,0,sizeof(buf));5{"L h@o P
            }8M.Px$T/F
            opr_in.ch=c;^a Am1N2Z9{
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ U/l(pTA'I7D]El
            {sxE mL Q
                case '<': /*优先级小于栈顶结点,则运算符入栈*/2Z*x_ b sa+]L
                     Push(optr,opr_in);e-NH!`'c%m.z7CA-v
                     printf("optr入栈:[%c]\n",opr_in.ch);
I S3T/k$|X                      c=getchar();N/L|%J?k:TVL
                     break;:le'ph-bv}|[A
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
:[)kH J+X&e                      Pop(optr,e);pH.p i*O\m
                     printf("optr出栈:去掉括号\n");
I-P_'Cw                      c=getchar();
`*w}'wzm[.cip                      break;-^L M#Vy mJ}t
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
`Q5i'\v#Y"D1C                      Pop(optr,opr_t);U)@*pN Q,h5i
                     printf("optr出栈:[%c]\n",opr_t.ch);
5P^1qV&[T`)e oMx"S                      if(Pop(opnd,b)<0)j(^:y/w1TM9}^&R
                     {
.w5P`/n4ii c;j                          printf("Bad Input!\n");?9]+CD V
                         fflush(stdin);+NkI oV)HX B
                         return -1;
4z(|!~6f*r2n                      }9Z/pE"E\iw{b
                     printf("opnd出栈:[%f]\n",b.data);
/I(T8]y1c1e/fZ                      if(Pop(opnd,a)<0)
F9|tglzw                      {Q#C3O#w-~ u*c}'_
                         printf("Bad Input!\n");;@8q1qf3ex.}d
                         fflush(stdin);
$Bm5D9bd'j                          return -1;
@(v'UrdmL                      };j/EAsv4T0M(|
                     printf("opnd出栈:[%f]\n",a.data);MO)u4ov(y
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ I f Q"@JIQO
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0vJ XRU)BN
                     printf("结果入栈:[%f]\n",opn_tmp.data);#PCL,ts(]+|5R X
                     break; [,[v\I!Dz&[
            }7{`-k+bC1B ]
        } e,[*IS*XR*lI Ua
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
D_7K5b#D/\A;Z*Z     }
A'z.O*yH*x,f'n     GetTop(opnd,opn_tmp);/w3C9s-{M5F&q*o6j&M[
    DestroyStack(optr);+Efr.hz
    DestroyStack(opnd);|L]9`!z~9w ^
    return opn_tmp.data;z(I4znq ^ O
}
5w5}|1Xue9xsAyN
Zv2s%}m6T char *killzero(char *res,float result)
0FP4g0G8BL {
LbKl-p@Z8j     int i;&dP*J R+f s^-m
t!ExW Jyq!PK
    sprintf(res,"%f",result);
1y&Y7c4^4U E _a     i=(int)strlen(res)-1;l4|}{-c)w
    while(i&&res[i]=='0')
PY%w#@.Rx4ltlt2jGP     {
^v3k9u9?/T+Y!J         res[i]='\0';#nJ-Z1?4K5W3cc
        i--;
+? i]+_u+Sy%O,eP$K     }
s,m$B|1M.A^V D#S     if(res[i]=='.')
+X'V#T2?Ec"_1LW         res[i]='\0';)MPK9uN j%W
    return res;
N6I0T6c-K%t }
W B,T2nGM!^NC2w S
1s v^ Z;Fk int main()
2F)V utsQ+q Q} {0ABN8wHi)~
    char ch;L(}/MN&|)H
    char res[64];8pn(G1U$ods
    float result;aZ p0n/]-s
    while(1)8Fa%{c7iZ^
    {)b(Y(v0g!YoAK%`F
        result=compute();1t1Z E4\t+D(B-j a1p,Xo"`
        printf("\nThe result is:%s\n",killzero(res,result));{QxZB2F*oB_
        printf("Do you want to continue(y/n)?:") ;
9el6Xw%{r'B         ch=getch();
1BzII-T~         putchar(ch);
T3qN YW*DA0~l#K         if(ch=='n'||ch=='N')
:|wwP ~             break;
x D6h0]w6?V:]}         else^|:y { Gp-d z
            system("cls"); G+zD/m[
    }];|}AS'd#Y'r
    return 0;J5R]Ux8m
}[/i][/i][/i][/i][/i][/i]8M+o!h&vz0@jm K`E;HK
(IQK,jT M9xu#~
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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