捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.$}]iZ5a+K|&m
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5pe`R8m8q3K
/**************表达式计算器************/IN4EQCC
#include <stdio.h>X&W}/CG |G+L:UD
#include <stdlib.h>
E6hx^0H)s:D%l #include <string.h> S4L-[ W sY1Z.]5D
#include <conio.h>5Y!W9Q6N&x6kD6s.z
#include <malloc.h>
(z)k nOT7@9qj;u(q G!L6m$miV
#define STACK_SIZE 100
7v~R$w?YTRx #define APPEND_SIZE 105y8z"h0H,|R+fza

#R N6mB"?*j)H`/N struct SNode{
u\V | [/CU9n$c     float data; /*存放操作数或者计算结果*/8H&x.gZ{
    char ch; /*存放运算符*/"T1xwIL:l
};&ATnWU$o aI ^ v.l
SC1c(ZH2QE2rC
struct Stack{Y)aOKup
    SNode *top;
kg$~rY,FNr     SNode *base;
u(hm wW/QT ES     int size;
)Tkw.^)k,x?3~)o };/xk@Mo'G
7TIg"F smxHV/p
/*栈操作函数*/
bW"OhX int InitStack(Stack &S); /*创建栈*/jZtOb$_S
int DestroyStack(Stack &S); /*销毁栈*/Y\`%Ya:j3R w
int ClearStack(Stack &S); /*清空栈*/
/^v z#^ml int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/%o.ql0I-t Qu8\ B+A
int Push(Stack &S,SNode e); /*将结点e压入栈*/Ag_8bC Xa
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
k4az|!Vj m
X7kZ9XK ^d /*表达式计算器相关函数*/
}|V$}#B.og)g char get_precede(char s,char c); /*判断运算符s和c的优先级*/-jRK v b5~N4?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*//b aIy u
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1k9qHi0yww float compute(); /*表达式结算器主函数*/
0d c{b _8z)a Izg8J char *killzero(float result); /*去掉结果后面的0*/ O MWng4l,g
$A4Q5jL"~.{po
int InitStack(Stack &S)
+w+A*nS:U1Q*x/d {
|4Y!zy8sj     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));'b6OlG SZ-G
    if(S.base==NULL)6G5Q(]l&I3s
    {E[j:bJTwgN
        printf("动态分配内存失败!");$x c4}'H$ReN
        return -1;
n*T)ck} VF$~h8K     }
}%{p m Icu"u7|vTm     S.top=S.base;
2AOc;H P qj6T     S.size=STACK_SIZE; n4B/y4r{ v Kxk
    return 0;
5wm0@2y!?1N.ME&Y }
!L#Bqje N
Y0hZ j5U int DestroyStack(Stack &S)2z6})pXB h1d7A6N;^!V
{
~L#O-Q8\:n,UK     free(S.base);2aCP6Ab/_7x,ni
    return 0;
NsFgDu,T }
#S NXm BP
[} _@xmv1i int ClearStack(Stack &S)
)^a6M y8U\/i){ {
xavR;z]Y     S.top=S.base;
:x1X D8[ aZKt     return 0;
o I+ICtWz }l%c*zP~i(a;?fO

1n/T ksXc yY int GetTop(Stack S,SNode &e)
@Q0I/C"nM7z)a2@ {
.p+w3slDMw J:L     if(S.top==S.base)
&{5Y+C;P$y'Y QW(P     {c5r0L0y]d
        printf("栈以为空!");.zfHnkPZ a&|\
        return -1;
(Kx f!s0].C     }
4i4E _"WE'A[:S     e=*(S.top-1);
@h7MmaP%m     return 0;#b[O1bp
}S~T;RWWe*A
V F1qb\w
int Push(Stack &S,SNode e)
xpb:Qc$T {_%^Wz5uE3M8D-h
    if(S.top-S.base>=S.size)
-TC~H d5AdK+?'d C     {
krk f1Wm         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); H"f&vc j0maFn~.s*r
        if(S.base==NULL)
%r q+Oi _ }+j         {-W r+a1wGMjf]@K
            printf("动态分配内存失败!");
*z f5Z H3N!Rj             return -1;_2X6{jJ'}nr DL
        }sB^Q?BU D9t
        S.top=S.base+S.size;
.B-Z!wA%luJmiU         S.size+=APPEND_SIZE;KK-K|2X8A
    }
7Za;W'Lel4v ~     *S.top=e;
^ T6~5w+cjp     S.top++;
p6dUT3`#o     return 0;
.Zv%Q6A [5Fc@ }caA*R+f YZ
"@;c;YAD2O
int Pop(Stack &S,SNode &e)
J!Td8w;Wk)LVL {
3?Gv!z4Pn3owX/a^     if(S.top==S.base)(`)SxsFp/n&N
    {wa"B~)Ac*{
        printf("栈为空!");
r0Iq"KW)N         return -1;
ON0v l;\     }
,J/z$w)z.WZCm.E#U     e=*(S.top-1);
H[1pZq~\4H     S.top--; _3q L)lK}
    return 0;
JWZ I h6HF1N2h }%i-E(ly-?N*r
.I6H5ojocmZ-^vz?}
char get_precede(char s,char c)]l0t CA6i
{
5k0Rb q#l!rp.X     switch(s)9pCg"Ir
    {
!m Y#PH Ee;G         case '+':                 1t,Gg ^R`*J9mF5d#Xq
        case '-':
Z9rF)XdMf              if(c=='+'||c=='-')@A U F,}h_z
                 return '>';_P#_M;s2w6w
             else if(c=='*'||c=='/')O~+AeCYc/D/M
                 return '<';
B} R \6xo              else if(c=='(')
#{[ m_j*vC!vC                  return '<';9o{{3t |H7\'f
             else if(c==')')9uH!B.d+gU
                 return '>';
?f.?cA2yR              else
0|Z2[hC                  return '>';
-f'kU*l'B         case '*':
A*L{0a(L$E;X+VA%c         case '/':/o+FEce!E)Qm
             if(c=='+'||c=='-')
|%^!\_?@!y]                  return '>';x/QR'v(i%s LP
             else if(c=='*'||c=='/')
bno5`w6F8I-Em                  return '>';
%\QF%q i&tJ t R|              else if(c=='(')
:n\P nDw6IG8mN                  return '<';5i~$tV%h^
             else if(c==')') Tj7UqM.x
                 return '>';
l(f \1u~e              else
,C8\h|N1d                  return '>'; hA9s%HO&I;| ?
        case '(':1b0j/e}Wt#BF
             if(c=='+'||c=='-')2j,}| b#@z`
                 return '<';"m/nShOu(y5{
             else if(c=='*'||c=='/')
oMVL"n&n-i{9|                  return '<'; JA1h+LY{d
             else if(c=='(')
.lyvE_j%n                  return '<';
#W Q6qk5~n              else if(c==')')
`As{w}D q                  return '=';
8e-B0G~'E P%M              else
[*mCfE&S                  return 'E';\X*g%} IH |K4g
        case ')':
i*~-Z8{1RY'C6|g              if(c=='+'||c=='-')O;D)N)?.W}^$^
                 return '>'; s.{"Q?|
             else if(c=='*'||c=='/')6`9y9KN5HfJ;^-Z
                 return '>';y g)D?+b,A.~9Y@2k
             else if(c=='(')
8f6M-G d `~R#X o                  return 'E';
;~5cUx"DL              else if(c==')')
&F"vp0cK d0QA(m                  return '>';
N\5UU {,o5`              elsec5qJTQ$dF
                 return '>'; n(nM3r j
        case '#':d!r@s8E
             if(c=='+'||c=='-').b{w0QC` }dR
                 return '<';:l^,G!@2S ?5X5L)B hp{ d
             else if(c=='*'||c=='/')8].K,~ll"Nm
                 return '<';
e l@"uz nX              else if(c=='('))gCt$U)h4Y Y
                 return '<';
1cI(cL O%[,d              else if(c==')')
0B-F$f(I`g,P2I0M$A                  return 'E';
e)]7gNa0q~3Fl              elseH;rU8k-vd)H;G-XVt
                 return '=';
Y!|$Xmk&xt         default:
C9o:_H'?xK*u              break;wk]2OQey5j I
    }A4i7zh?T
    return 0;    \r3ui,F:A
}
6F%f"ueidA 3Ou{cz5v+W0U
int isOpr(char c)&Xc h7G6@~ f h@
{LS1Q$Y!e{ NQ2k
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/UI#Fvw"W&Pk@
        return 0;
1L0x5]F B5ia     else :~1e,S3Dc'{"@
        return 1;d;mD"ua*lF+p$P
}1~~(L/Z)_ p~

-ip)G0Z zkr"^T float operate(float x, char opr, float y)
'hpc-^[A l {
f"xKayM!eghy7}P*h     float result;
gz;dwD:gwYu     switch (opr)
O J}1VV HDL'QhB     {1p"F ]+u;au5`-qj+vA&F1^ `
        case '+': !l[T5C:l}W
             result = x + y;q0Zaf~l
             break;;Z/F/w t9T)I&g2~R
        case '-': Z@4Zx2P2X
             result = x - y;;CS5u-aM)b!e5C
             break; Eq%v:t {a$Z1l
        case '*': b8B d1A B
             result = x * y;P\-e;]R/`
             break;
6Po;R+_7D7}Y c!JP$Az         case '/': h$oOV+Cg9VYb
             if (y == 0)}_&A2pI8?,Wc%Q G
             {
V`E$SQ/v[ }                 printf("Divided by zero!\n");
X|$rhZ0Nux                 return 0;']4J0vNz-u6} l
             }R?W"K9G@flC
             else
wg5yYd@)O              {
"Ia W`&_d8P,wN                  result = x / y;
;fZ!xm iqc"f                  break;
0N u6l-y:Y v x K'{i              }
ok3m aN        default: Ixq*R#V
             printf("Bad Input.\n"); $n_*v6n ej S4jB)Le
             return 0;qkb~e*\3j7P
    }
/v Ts)xn"S,}&u6{     return result;k_-P:t*np:e?t7z/G
}   
:v'@ YI T6b -H)t5Irbt Is`
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
'keVv9t:M^|oVt4I {
t6LKIA2v     Stack optr,opnd;
/qkQ3fB{_     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;'tqI5VTR&p8vW
    char c;
&|)`:zNC5m I     char buf[16];%U8UW.TR
    int i=0;C_;Zx!XM
    ]CvS ]N
    InitStack(optr); /*用于寄存运算符*/
gD"{1d$u)a9w7~s/h     InitStack(opnd); /*用于寄存操作数和计算结果*/4d6_T(]%r R_4E4y
    memset(buf,0,sizeof(buf));
"J{2S2lo'@    
TW Q{6D'G-X'eZ3iq6OV     printf("Enter your expression:");o YU.BI?c!r*c
        
8~/yI1dx@P9v)IxP     opr_in.ch='#';
iv SLf.Z     Push(optr,opr_in); /*'#'入栈*/
S r;A"Zm0S$CV&H     GetTop(optr,opr_top);
s `Hwu)e^.PTbH     c=getchar();
dh.f6_)W @ko     while(c!='='||opr_top.ch!='#')
s9t3w0^|n     {h1U?R"d
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/)a ] ["^6RM
        {
FeU'R8E0e+]4y0o?Gd             buf[i]=c;
K5vhah t ]0|VZ;u2N6Z             i++;
x]b%S3P,C?"T6c             c=getchar();
V ^ Wiw&N M$M S6d[         }
;}eE,w%FDn4hI g2E         else /*是运算符*/
%e"E0{#C5R         {W]-T zT;N.^w S
            buf[i]='\0'; [x;it R/f4];x^b
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
!Bbq$Rh l-?             {9cz#H:zPj0w
                 opn_in.data=(float)atof(buf);)j3^2Le+V'q!lG
                 Push(opnd,opn_in);
u'|r `+Am                  printf("opnd入栈:[%f]\n",opn_in.data);r7Q5pS8N4}A X
                 i=0;1a IGp_0~ X,q
                 memset(buf,0,sizeof(buf));yj9K#A5GM4p
            }[F1Y K!Ogb
            opr_in.ch=c;
e!_+j(a|;ai X9W8yz             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Or8p'E)uS#L:k D             {
oxD9n FJ                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
4fqI8CF+lA1`                      Push(optr,opr_in);Lo6{J:y$q7x1g
                     printf("optr入栈:[%c]\n",opr_in.ch);o8rE1P)NQ"}
                     c=getchar();u c'S.K8Wf7]m|
                     break;
j.[1U]kx^                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
E"~k_ J2v@:K3{,A                      Pop(optr,e);
SL_s-M*W*}"ynW                      printf("optr出栈:去掉括号\n");(RKuj1GT(I2Z
                     c=getchar();\y4rh5P7E'M.K
                     break;6N_Ke6A$VP
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1thy-w#bBYH                      Pop(optr,opr_t);
8~ FF]5Ttw_%x1X                      printf("optr出栈:[%c]\n",opr_t.ch); oEf8}^ P Sg
                     if(Pop(opnd,b)<0)(Kv7| J6q:G6Nt
                     {7d0aPRB&`#m
                         printf("Bad Input!\n");1A }5@r:@&~z'i'n&R3W
                         fflush(stdin);
w4t)J!R@~f                          return -1;`L6i7Jx2Wq#_ H
                     } O%?:g/BsV
                     printf("opnd出栈:[%f]\n",b.data);
w(W-l6J.rk9I*]bz                      if(Pop(opnd,a)<0)
{ieP$t(pqf \                      {,Z7qWXX*i
                         printf("Bad Input!\n");i1t)ERI1ZGwD/[
                         fflush(stdin);H yD6Q$f/f
                         return -1;.S,\APJ4|
                     }^ U-W U/F m4m
                     printf("opnd出栈:[%f]\n",a.data);j'R |-Nu&O)u
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/G NKObV
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
d)W7o,tc:O.@.U                      printf("结果入栈:[%f]\n",opn_tmp.data);
b^K:xGi*FN                      break;0n{;M ^)M)APC"\[
            }
P"d_r2KN         }S;J7Y0B:L.f1{ I
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
(e ro)dQ!^S     }3]/_9I]4?
    GetTop(opnd,opn_tmp);4?~$J5g)s/U
    DestroyStack(optr);
s _)w[\^k     DestroyStack(opnd);
&[Ty4CNE"g     return opn_tmp.data;
)M7Xfz L1q }GDLl+K N8@%ND

+A%Bp6E mRq.? char *killzero(char *res,float result)
W5F_9x'o/tx-Y5kY {#v7iYFO
    int i;
s2g r5d&o
;?]|U p,Uc(CO/m     sprintf(res,"%f",result);;q},UHEX
    i=(int)strlen(res)-1;XMNJe1|
    while(i&&res[i]=='0')3z3k*a h&kE"}
    {
Kc f QJo@{j.u         res[i]='\0';H:vL9y LP
        i--;
_eFd)\;rz l5j r C     }
e Op/}W7zn     if(res[i]=='.')
k J,{9VDI5ZDF_`         res[i]='\0';}h4NQ+~ o
    return res;aQ4I%CI2a ^
}
F}6@a5m5v|8\H
YDg#m`r int main()+jrJ2P;jj&A~Q7L)_K
{
'P M5T0N$P;?     char ch;
&L\Mg$y7Z$b~W     char res[64];
l]9J'A:]oeJ     float result;8C&H ] a R'k5Ot-if
    while(1)
&j BC!h6b     {{b%C9N\ca Q{
        result=compute();'IJ;E6kf$a }y
        printf("\nThe result is:%s\n",killzero(res,result));
l VZw5[)yZ         printf("Do you want to continue(y/n)?:") ;
fS Yf:Ew9z3wN         ch=getch();
g'n4^ up0A         putchar(ch);
8O`/ytH9A)\D8h&t         if(ch=='n'||ch=='N') ]5G/X;[!u \ a
            break;@ Wmb9nqd
        else
[!mk4Bj^             system("cls");
,_n9B+?,r6eJfZ     }
w v(gVBkj~     return 0;"r$f|}b0b0]
}[/i][/i][/i][/i][/i][/i]
G$q$Xuq5KnkX
0`;ul&m(m!p.M5i } [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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