捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.7E9\A7R6?/Om'l4T/W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8zp[+E'OD
/**************表达式计算器************/
!u&MY1j.K1jh4Gs] #include <stdio.h>
3x+l3Z:kj&IcZ/HI #include <stdlib.h>#\~'N4u!dn
#include <string.h>
7Wu%jtNU]!U0A #include <conio.h>
j!Z^)H L3`7f #include <malloc.h>V,W,W3KX/M/F
3zV;qKT
#define STACK_SIZE 100*Urp%\9]~ X wQ2HB ]
#define APPEND_SIZE 10AOrs6b.?
UR{ }%Z4Ag#\i-{/b
struct SNode{ w$y6Yj TK iD
    float data; /*存放操作数或者计算结果*/X$~F'dq)en
    char ch; /*存放运算符*/
"z PP6Q}n}M,^*o };
m:|L ^|o Z[!h:D\:ccS kSd
struct Stack{
]"d+nh?F     SNode *top;
_ {o`6L:]3s     SNode *base;
(Hg~*II_"c0^F     int size;
*j'R LTCcD };
!x7I3gMNf *HVE.y^k$t ~
/*栈操作函数*/
:k(V(BE#u%d int InitStack(Stack &S); /*创建栈*/
EJwj%l{ int DestroyStack(Stack &S); /*销毁栈*/-i*c0X.|^$N v
int ClearStack(Stack &S); /*清空栈*/
I*w];D l P I int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/-[fe/b`?-v
int Push(Stack &S,SNode e); /*将结点e压入栈*/
i6m;BfU){4s int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/_,];Mj&R9z8e:ap0]N
t Ma~$l'yL
/*表达式计算器相关函数*/
|k]{r5u2E/R4O0y V char get_precede(char s,char c); /*判断运算符s和c的优先级*/
6i]8|k^Nf int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0x.e,bo v5R W*cX float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1e+? c] s(o
float compute(); /*表达式结算器主函数*/
p(WHB u;o4dW0r char *killzero(float result); /*去掉结果后面的0*/ 7t{:F/`V,B;J y%kN;Dz

q8x#n9B"j qNb int InitStack(Stack &S)
[7D3H$^6n.Gi {
W9v ?6U#H#Z:bWlI     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
_6uEYE6LN;c     if(S.base==NULL) q-NoO(bv#j
    {
g K|;Q%r4F#\q         printf("动态分配内存失败!");
(C8l9w'RSsl%h         return -1;Y)k,e[WK X&VU
    }|2e9QZt r4Z
    S.top=S.base;&W;x A2ul sjv PYi
    S.size=STACK_SIZE;
SHReb^?     return 0;9P b+L G2Wp!F
}`_l)F:x-`wo9h
SHx m!L)`
int DestroyStack(Stack &S)
&h5OyP;U{ {rk7QC8t? M4D8us Y
    free(S.base);
:_z ` Zw UP     return 0;
C;in#Dn K;Ia)V }$E e8o(lNc-Th
HFU M/e1m
int ClearStack(Stack &S)!j.Mn,x+`)RG"a6U"v
{_p+Tt9t
    S.top=S.base;
^EiPN     return 0;8JK*O l#PHZL
}
/Q^F|K_+` Vu%a7{*NH4v
int GetTop(Stack S,SNode &e)+K2roq3h
{ ?m/RV+tg
    if(S.top==S.base)'YP.I p8H2it ^1o
    {
T z iYE)L.A         printf("栈以为空!");jeKM3^'TE(\ZAg
        return -1;
;{W5wyQV R     }
~0[$lB(v4Rc;f     e=*(S.top-1);(G5{H,e'mR%I-a
    return 0;
E4db,iJ pZ| }
} hGg(? A-c`%i m7h"~ x&]:nX s!J%YEQ:?
int Push(Stack &S,SNode e)
Z(pbLKD {
9dmc d+k|4]D     if(S.top-S.base>=S.size)
s*B+X8_S*F&C!o~     {
Ip8L7IwP;Q#D         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));&fH4DMz$k4\
        if(S.base==NULL)
)t@? [OF         {6t,`;x*Z"wO
            printf("动态分配内存失败!");\r \,kQ
            return -1;
$t9@q6ba(W \ H         }Qs+OnR&G sh
        S.top=S.base+S.size;,{-rP9MLHjl
        S.size+=APPEND_SIZE;
3x8j*|%{m8@:F     }
0lh:J"A#U/{(e q     *S.top=e;adS)B6{
    S.top++;
1U;MQ8z6f~     return 0;
?A/F(v| ESu }N4m'_1DX"@
sF4Zs2`2c&g7P&G
int Pop(Stack &S,SNode &e)
/b0q'g5N b I0E9MAF {'XZ/NX1]8t
    if(S.top==S.base)
1~b2F/]eQ7d-q     {LuvQ$yO9w%ME V[ P
        printf("栈为空!");
$R7]%H%~.c `         return -1;
)n#pf Apb/y     }
4~*T"] N%M0T x     e=*(S.top-1);
NB9Z,LD d     S.top--;
5[aD$v SFb Q     return 0;8DE1z"lkW1p/Lv/r
}
AN'P$w1L#XQ t/A 7j*E$ITQ!V4oQ v
char get_precede(char s,char c)
9eJ)@an,v&n {]~q'AJ$G~ d6j0R[
    switch(s)
7O~:s9o^u1S!w     {n])Zx&e;Y UkdQ^
        case '+':                 
Q1U2S,M2f!x         case '-':,v QT6|k0N4ZvT g
             if(c=='+'||c=='-')
@OKO$]1sW n e                  return '>';
0Or-I9e3H%K^ ~G4N              else if(c=='*'||c=='/')&R G$m6wH c5s g
                 return '<';7L9Mi e4Q"b
             else if(c=='(')
s\E]uA                  return '<';
Sc X:e/v'_"fL,H2i;w              else if(c==')')
(vH$`I*\                  return '>';
n3c7p e rP0y%N@3f              else I2QFq)cQmR$J$A
                 return '>';k2ts ic#h7q
        case '*':b&H{%euW5Xy
        case '/':
l [1I~?              if(c=='+'||c=='-')
3K0D[eU:|9ef1H                  return '>';DQ0[;\ W:k
             else if(c=='*'||c=='/')q'ok[-DT
                 return '>';
V2Tx*d;J0@&P              else if(c=='(')
}$dd8M"{:e"m'Yga                  return '<';3k?b*dP
             else if(c==')')*gmj;EKuR }
                 return '>';
aikTm              else
0I*u%LOxut                  return '>';
#Y2aA&oeu|         case '(':
`;~ m$|#@U              if(c=='+'||c=='-')
H-z4H}L4Q&w isO                  return '<';
G"ILl lz%n*RN              else if(c=='*'||c=='/')
;^'Be1Zib5q `:C \M                  return '<';/i pWI%Kbwc
             else if(c=='(')
g}3j^)T1h BI                  return '<';5N%PXw-A)zDO4J"}p
             else if(c==')')
C5BmL Us uW                  return '=';
SrD uC              else
dH/cs9E0sxP                  return 'E';
p Js!s\$R.b"}9h         case ')':6o2R,G$b!p
             if(c=='+'||c=='-')dk5o,ip#v8e6M
                 return '>';
0O\LEj!{1[P              else if(c=='*'||c=='/')
#W;TywR                  return '>';
^1@gy\"|"i2N              else if(c=='(')
3qM7p,W7TJ g6Y                  return 'E';
X8[mc#H0d              else if(c==')')$DED/^.Nt
                 return '>';
|Q d{TM+_#by2n!hL              else#Di`&hVi-](Q'VM8t
                 return '>';
q$G,e T X h+H~/oy         case '#':9Y#g3LJpc(e$o
             if(c=='+'||c=='-')
ZW? {{$X0b5c+n:e                  return '<';
L5z)~ f Mg [9Q[              else if(c=='*'||c=='/')5ZR!Q*Q;|0J+R
                 return '<';
NI j2W#_L'W!v b$q              else if(c=='(')| C$n c C c5S7P)D
                 return '<';Rd,^ { nNCf^
             else if(c==')')
5y[m1P,X"`                  return 'E';
(pa3c1W?y4tj              else
Y5Hx#~s(nG                  return '=';
.hw!dP VQ,j4{         default:1x9uIo1}HHq(B
             break;
7ype/w%X;l @1JC,k#v     }
5E:^Qx{     return 0;    #\Xv+j0m7Z
}
@ x izm8c`.f{!}D7t
B s dE AaL p|R int isOpr(char c)o%qN,j0prd
{G-n&|+[_`-`.X:x H
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
'_"ha0J t/T|d         return 0;4MXly%Ep"S8FP!E6f
    else 7_d.~vWk%} UjR3d
        return 1;VM`on;D(E
}"m&DsRh N
Z5H`+Y}Y:e0z'D]
float operate(float x, char opr, float y)
_IF]|+~ Q {
RY r1y MN     float result; S)t#[(Gu R
    switch (opr)
D,v4y6wm9Zu     {
-ICl(Q!eM"Yz         case '+': 8i+gP ~'i&o-h#KW,e@
             result = x + y;u h1@K UC]
             break;
:L[!X9i| w%i         case '-':
p` Hx&L,Q              result = x - y;
~v LQGCtD#J Q              break;
pZ7kfW x _,Rc         case '*':
w LvC @_f;i              result = x * y;wb }|A+d
             break;
T0?J5\+CN         case '/': z!G{7?6\#W X
             if (y == 0)&g1G/mMP1\7j~
             {
9F%}3wnegH                 printf("Divided by zero!\n");
8S(|!Ug-E9A5w r4y                 return 0;Z:K1F7Z$Mk/^%h,`Z
             }
N!MpGQ}5d%O*o              elsee/Y8u,a!RA
             {
p I:X1u-P                  result = x / y;
_@T xB                  break;
SONM,[%P9_              }"a}^{AA8J
       default: s%GI\v!N H)n
             printf("Bad Input.\n");
m#^2uF1t^-{&P              return 0;
5N;l N5eg m_['A     }"N a%iq MY4fg
    return result;U!b/^#[WHu|
}    Z,E{%N&hUau6ct
D'O.`9\m w
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ N7xjkT]cZ
{1VL6iAg_MT u7o,_
    Stack optr,opnd;
e.RHJ%W7?6m+EG3P     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;*t!{1q*v9}$j7c#O
    char c;
{:EU/X9T~8NH     char buf[16];#L9_%Ubj.v2Sv%X
    int i=0;FD3P}H4P9t;j
   
@3uC.b5L,KbU     InitStack(optr); /*用于寄存运算符*/+s1o:?$FW W;Z
    InitStack(opnd); /*用于寄存操作数和计算结果*/
fud,nl     memset(buf,0,sizeof(buf));
~ k&Q/f%`$wN:{G     H*l,kf:jE9N
    printf("Enter your expression:");Z*]4wo.[
        
&k c'Y/i%W8p Z     opr_in.ch='#';
-q s"xL_7SE pg     Push(optr,opr_in); /*'#'入栈*/
b_7d2e cLi ?9[&Ux     GetTop(optr,opr_top);&b(w7V^;C{K(|
    c=getchar();"rC P"l w.[n,vu
    while(c!='='||opr_top.ch!='#')#b/vs,V*\mD4V
    {i[_%@`wX~ N
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/-]2k8g*i,Z9qQ
        {
y8{tS8B7zI6?             buf[i]=c;
|2?7JH ]A#z%p7K8^             i++;9q"Q^ s _/|
            c=getchar();#oG,F+C5a1V
        }~.pD4jf&|y?
        else /*是运算符*/
TV!ql-RT]|M'@         {
EYjc,v"Xx0W4AB']             buf[i]='\0';
0fOSM v l d             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/o"]z/^0|1e
            {
8I?x b~s.}2c5v z                  opn_in.data=(float)atof(buf);
!rK(r7Pp                  Push(opnd,opn_in);
-G-KvU w%UJ:f                  printf("opnd入栈:[%f]\n",opn_in.data);
;I%W E(v,[Cr                  i=0;SCp0QE^+k3T
                 memset(buf,0,sizeof(buf));v*@*lp$WYU[
            }\;]-E(h!C/Y/U9O
            opr_in.ch=c;L]{N`2\7H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
7RpK%rbA9A{             {
M/`h!^UE2t9p0xC                 case '<': /*优先级小于栈顶结点,则运算符入栈*/(W7WDe-h[ Z`
                     Push(optr,opr_in);
!\4ZC9?[r                      printf("optr入栈:[%c]\n",opr_in.ch);;b(s%t1DN I
                     c=getchar();`w.p5A Tx \
                     break;i;A:tR/O;n?Q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/n+N Dld
                     Pop(optr,e);
S&e+^T S                      printf("optr出栈:去掉括号\n");
1Lu|h_ t/{                      c=getchar();
3Z iN"S'P3{*MQr&w                      break;
5_U*OY+me+~5Gv e                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/I&~t4XH`~c
                     Pop(optr,opr_t);"e$v ^ju+\3t-[j
                     printf("optr出栈:[%c]\n",opr_t.ch);
3M4z!K&ED q%^ Va                      if(Pop(opnd,b)<0)
#xB8Z%}{ch                      {
)ja^5Q {A                          printf("Bad Input!\n");mT*};Q3Yj%]#h
                         fflush(stdin);
n6R4X(qR(KBJI                          return -1;
D@ Xa*p                      }(Zl,d6FK3P{M
                     printf("opnd出栈:[%f]\n",b.data);
^7|z4j8`'r#`                      if(Pop(opnd,a)<0)
~"t!p p] H OU                      {
1v+F7VJq9VP                          printf("Bad Input!\n"); y*a"@UE$AR)^ o
                         fflush(stdin);
3n'UGwvSr                          return -1;*rK"{2c)C!|
                     }
8Z*J\+\ LM                      printf("opnd出栈:[%f]\n",a.data);/T5r4y+^DW nWT
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0S4B[8gn;~ N _
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
w;S0S9lE9kq$~                      printf("结果入栈:[%f]\n",opn_tmp.data);
:B} f-g$XO                      break;ni!w)^*}
            }b)Deo-jJF
        }
U#yN?aW2|E&E         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                r ?j dX G+[){ j k
    }
5t6\Ve_ W[     GetTop(opnd,opn_tmp);
\| K!f!W     DestroyStack(optr);
Q7~8^ q-OI     DestroyStack(opnd);+E|0J9D%AY
    return opn_tmp.data;
)wYluj,lg+E`W }2{9{:D9Q T-P#b

I8hd'|rSA char *killzero(char *res,float result)
.z+`+\xh$L5YT {
!W,m2e_|"Lm(Z     int i;
8I5JLQ:l'Kx#D W"wX6H3Jk!q&Y0L K~
    sprintf(res,"%f",result);
"G{g({;QF     i=(int)strlen(res)-1;
Pg(i9eJpqb)s,dZ     while(i&&res[i]=='0')mS!S td0e8l` BX
    {
Y%sqHf ut&g         res[i]='\0';
"RF,^JN6Y         i--;`Y2k&l&P2N*M.X|D
    }mIx+ttI
    if(res[i]=='.') Ug;V9Tj#^([
        res[i]='\0';
6L/OF7L4] M5C"T     return res;"@5o!h!U}
}$R#Q.EF6P|,s

Ik4VV m"L`E int main()
/^D,Zi(@#nQ N.Z5|} {'fX G CYR4bu4c
    char ch;KSn/e B)wf:t
    char res[64];
)C3d{:D F9~LKN     float result;
*tH@`1IT`qH!T!d     while(1)&FF-S,t R;XAys
    {a j{ ErZ0k
        result=compute();
MhM}H ] n^         printf("\nThe result is:%s\n",killzero(res,result));7`!H?ADG*ao"R
        printf("Do you want to continue(y/n)?:") ;.P1brmy,u{)f
        ch=getch();
Ac:tS2p7Y#u)GC3X         putchar(ch);;A2~T:XVQ,p*p |
        if(ch=='n'||ch=='N')
JQ7ED8I             break;8~x!{t G8u2V"E
        else
;[Tx6x"O7xcT6n9K,T             system("cls");
f7SZ _J@     }
u)qNFr4a }*D     return 0;8B0k[7}$@8S4w
}[/i][/i][/i][/i][/i][/i]
nqNA B*{
+mK,kzo [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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