捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
m\.k'Qi(mY 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/\(\ ew)G Q)h /**************表达式计算器************/q9HeeVa,CJ
#include <stdio.h>zz__G0_Pt/`
#include <stdlib.h>
l:v2?QcI #include <string.h>!a0]"[%K eK A~QR
#include <conio.h>|~Xw}R`
#include <malloc.h>
lt#K6~3N h_fk
(aQz,k`$D6BKa #define STACK_SIZE 100
`2S&T;|Izg #define APPEND_SIZE 10
-R*W1a Q$`%x k5R
r ]t:n VjBx7o struct SNode{
-mQ pn9u     float data; /*存放操作数或者计算结果*/"ll,S(F_ [?s/L
    char ch; /*存放运算符*/`B(@ [k Y i U@_
};I\6Zt.LC~

CP vl"E%L(aaA%Sv struct Stack{ hc%N,teN\6c5J;W
    SNode *top;
W'Y#Y*joHax+e.LD     SNode *base;a*B.l*G8x T#D
    int size;-ahU.pg@Gp
};.M:Y8tzOF!Bd |
.lw,X^ d kp
/*栈操作函数*/U.K2~;i4c:~0Ja
int InitStack(Stack &S); /*创建栈*/~/C;m"|&Vp%j4aY
int DestroyStack(Stack &S); /*销毁栈*/
O[|"E+f${/bvwI int ClearStack(Stack &S); /*清空栈*/*KGpO Ix ^5R
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/{!W;f)LWP Y6QT6~
int Push(Stack &S,SNode e); /*将结点e压入栈*/
8W%oPLa K Y ur_l{ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2[!D#Y"b3mDC #Kw Ma-ma
/*表达式计算器相关函数*/%Mt aPb'\2~
char get_precede(char s,char c); /*判断运算符s和c的优先级*/|,nMv!eE)O6}P
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
J'@&Yo W+P|/Y float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
k1k.n*hx0j}| J)@ float compute(); /*表达式结算器主函数*/
Gt.|8tN r p char *killzero(float result); /*去掉结果后面的0*/ 3nR&cSt|

*WN!U9c+a?$Y E int InitStack(Stack &S)
8nZ7T} X"U6x9z n {?.])F rS i3P
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));3D~.a$I%H&Iz
    if(S.base==NULL)8gxi(mO
    {!e4HS}kx(z~c GS
        printf("动态分配内存失败!");\*k-d,l.[O*I
        return -1;4r4~.]~;?K
    }
J A5ZD{(V_     S.top=S.base;
$H f.k SSo1m u     S.size=STACK_SIZE;P&DST5j^ m
    return 0;
@"z+N n;]|-O }
g.]0g;t,Bfx`;~ |;i
#w}`.Ysx+k int DestroyStack(Stack &S)R4Xw3mD`Xb,W I x0\?
{_^/\+o/~O%`9Z
    free(S.base);7UU%bn7d.EnxG%w
    return 0;
P-w"XlP}8iL0n }
5[UI8j[0SPZ
g-Ia+AhK5^ N U int ClearStack(Stack &S)
9W5RNK9e {
:M4|2H:~{0x)tNBR     S.top=S.base;,x V5v |jzM
    return 0;u k J9o'c&F't?
}
+v)g] x4u+xZ
pN i%f] int GetTop(Stack S,SNode &e)zT5A`.PRs6b)Zqw)u
{
&z"G?@D!EJ,YI     if(S.top==S.base))s5T7P(q/j.t.H'u
    {
6lu$XS7q3^         printf("栈以为空!");
/Q P0Eu/c2_`$PKb         return -1;3ItNr |(l
    }
O'WF)jr+PP O8I7V     e=*(S.top-1);
N-I~%R*B     return 0;
^(BncX"f } _,SeYPT;Nr,R8fEL
q?NT#i)c
int Push(Stack &S,SNode e)i9` h'x)@/lDQ
{
L N2w;s%ErL     if(S.top-S.base>=S.size)
6MT?/? PF     {4l])^v'V(m;z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+a\;vC)F         if(S.base==NULL)zEW9es"c9[%g
        {
"z],T#fkYS             printf("动态分配内存失败!");
~A Hh ] cvV C}             return -1;
f mUb6~n         }
5p/[E%k J_aJy         S.top=S.base+S.size;
;k,B _I:O[         S.size+=APPEND_SIZE;"M8}&n5[)[N,U
    }
d1{(q|(q%R~{$k+b     *S.top=e;5S)xVOL B+v
    S.top++;uXB p!ES;Fd
    return 0;
K{'u.RCE7w{1q }
aqu9m(H9k)zoS +z+xLu\o,D
int Pop(Stack &S,SNode &e)
${^tl*s.]){rE {
*^__-TXD`1K     if(S.top==S.base)
~a8ra\5o+W}J g}     {
Abk+x(t8w         printf("栈为空!");IC5A9v*U5qV
        return -1;wVvh!@}*L"S
    }s5bF$C0G9KZ!q!Z`m
    e=*(S.top-1);w*Cub9c{f
    S.top--;a)d4_s0](\;m
    return 0;?@ O l:Z)M
} g:J,?\u\
"cH0mt:Qr*k
char get_precede(char s,char c)
[1]a4k2` {y!e Hp:K
    switch(s)
`+xXK{ c:D     {
'fb$OPM?         case '+':                 
@%[$EwuC.V%c#h/T4W         case '-':
z8K)p.LYk.w              if(c=='+'||c=='-')
IrC"p)r cr2@&u                  return '>';
%P7F&Fy)a'O/I]              else if(c=='*'||c=='/')$eX@.W!kOa[1D
                 return '<';
5aG#M's Z7Iy(v              else if(c=='(')
.|d BC2E                  return '<';GpG4MaH
             else if(c==')')%WY5s0ck/fjmg/e$R
                 return '>';0@(rNvf @&u!r9v
             else
1Oa x{P-Nil o                  return '>';3a]p)?CV
        case '*':CN;@3J}W5E.]^,A
        case '/': |L:@ Ok ] k}
             if(c=='+'||c=='-') a"PjT]8E8Ygp
                 return '>';]Z.tl;x:f
             else if(c=='*'||c=='/'),bN8L m d_[L
                 return '>';;W R7J:BL2`r)c:G&N
             else if(c=='(')
Y|LY#q W                  return '<';
w/_7lnf:M*W)U/i              else if(c==')')%AE]{ f,Zc'a!Pr P
                 return '>';
Ax&wD6xi d2gH              elsea#h d*T?B{"P a/i
                 return '>';r/g'V.V"lrL
        case '(': Z,n c;s6I@
             if(c=='+'||c=='-')5T;L.z"|Ih
                 return '<';W+L AoFj^M-C
             else if(c=='*'||c=='/')
0WV8\jB                  return '<';
s1S AZ'I(e              else if(c=='(')
j#u {nW p B t                  return '<';
%w_m_{a*~              else if(c==')')
GI0h8R KO#p                  return '=';
/R,Z!t8Vi ]/W+J              else
#~JI0~2S                  return 'E';2y:z0X-z5xNs
        case ')':#`,ww$b s/q2}4_e
             if(c=='+'||c=='-')}9h&w!E2Yf5`{g
                 return '>';
wEeN#X.P              else if(c=='*'||c=='/')V*j2K8@1h z5Y
                 return '>';0T d'j0a H7fc%k
             else if(c=='(')3lb(JrF'H? {
                 return 'E';
{Na8n3Ek&\#ExiE              else if(c==')')u(V(t^.Bq@Y
                 return '>';:pBYUdXoc
             elseJ+a4r [ m
                 return '>';
j!{/M[LPY;d[y         case '#':
&J)K!{M0^U [?*E              if(c=='+'||c=='-')
,j n1OP w6da~I                  return '<';:K%E?N3q"z"{0Pv
             else if(c=='*'||c=='/')
/g"B,EW$x                  return '<';0G6~&_#m(O4X q g
             else if(c=='(')
)I\Rd!^%T                  return '<';h2?;o?{
             else if(c==')')
4{1E6K~dM]O&G&N:ek                  return 'E';+R3k6qlX,OI1u:k
             else{,BW M#m`5C:F
                 return '=';JJ ?4be|"f%U1U
        default:
La }QotK~^g              break;d-Y:mS)t}M
    }1Kl`vx(T
    return 0;    6N_4]@G2]Tq
}q@.l5tbLX.K

n}+hP7jR?~]a int isOpr(char c)ruB7zJ;a,V#J s
{
(Fc Z5T*K;c?     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
V[/N/^4qq4s#|{~         return 0;
F_E @#}FF @ ~     else
i)j ] b6W)g"_i3t         return 1;
}"f-s7Bk^4ve.o }
I}m9YFRw `*Gc)ti
pp}|)yb"YeM float operate(float x, char opr, float y)
dF%T$?!y}B~ vn4W8u {"MdbT r
    float result;
DkscX/o     switch (opr)
3\w*No2z/l T     {*q8] r wf
        case '+':
5C0^L*|KL              result = x + y;,f#A3UVu
             break;*P4E5ws,P|i3i
        case '-': (Z,z8zg/HfT m
             result = x - y;
o-G_3h[*l              break; FL7D'aaw!}4G
        case '*':
;EO2^*?w              result = x * y;1rO8H DNG#{V:H,Ed
             break;5K:?#m$d5w ]
        case '/': "W8xC$}Q F+x
             if (y == 0)1mP(M3r*O
             {
{P`K \[&]'C                 printf("Divided by zero!\n");bhl-S0Cp0A n7dd-O0F
                return 0;
tE1y!BFT5S              }
@xegH*Q jMj:T              else+Fs B0o9]$\@h_
             {
GP!Or"^ uv?$D3d8Q                  result = x / y;
(Z%^6}w5k*G9n                  break;$ZEyMGa
             }N'g eo5^
       default:
+Hl;coMM              printf("Bad Input.\n");
k#I@u9_0I              return 0;7cxH7o1Cjf` R
    }E.xr"c Vp
    return result;
|x:`.^J-caZ2L }   
!r'\8Y2ME7K
,f\b%| H,Fq float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/'gC#EHU,_i
{
x7Z/Ma'c_D;fp.I     Stack optr,opnd;RLh:f PeF;Ev
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
pb(_x6li I#n2R     char c;
4S&}@&CM*i%GFo~     char buf[16];f!xK&M3gYg
    int i=0; z]'OXk-x,M
    qOIH |w5Ruy4~
    InitStack(optr); /*用于寄存运算符*/\)]n j.p3Lh%nHR
    InitStack(opnd); /*用于寄存操作数和计算结果*/
_ `l p7x     memset(buf,0,sizeof(buf));
a(`9W Qqf^q!{     ]6X/\4]!O:G;H|8R
    printf("Enter your expression:");
N'A| D*U&A         !HH"j3iIy
    opr_in.ch='#';
LbL U8i$G     Push(optr,opr_in); /*'#'入栈*/
6oAw"W_j`     GetTop(optr,opr_top);
;S R3`2s7W)LJ$M     c=getchar();h|n/DQ\bQ1WB
    while(c!='='||opr_top.ch!='#')7lz7DD,C$x{
    {%J A(]f*V6E*} o9z
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ hPd$g&V,Z+A
        {
E*wbuj HPE             buf[i]=c;
EX_2G*_6c             i++;!kA%nW*eSK P0T ^o
            c=getchar(); p#i!c2L!h+a]-yu)s|
        }e@ O1pa h*V!Gy
        else /*是运算符*/](vL M-B[9gz
        { dU1F7y7] Zz
            buf[i]='\0';v4^[[&M1m.uq y9z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ d ["qrH4gc_
            {
H Mv i-wR@                  opn_in.data=(float)atof(buf);B] } g]H
                 Push(opnd,opn_in);
n J4]7v(B*^N]                  printf("opnd入栈:[%f]\n",opn_in.data);p QvVgw!G$}
                 i=0; W x;w!qmZ5Y
                 memset(buf,0,sizeof(buf));I1EADK(a6{\x*k
            }n6h4k D]S HMo8B
            opr_in.ch=c;mEfK|'J
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
9E*U6y;B J6PI1D D             {!c I'W#J9K2m
                case '<': /*优先级小于栈顶结点,则运算符入栈*/b(h%a-~6^4b%l{%HX
                     Push(optr,opr_in);
;a%L7H@D2R,e1T*z)E0n                      printf("optr入栈:[%c]\n",opr_in.ch); H$D/iB\ ha
                     c=getchar();
Hp bm!r*t                      break;
xV-SN&os                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ Z:[6JsufB{-R
                     Pop(optr,e);B"o4V }N9cs#]X ]:?
                     printf("optr出栈:去掉括号\n");7[%QRf A+D x
                     c=getchar();
;`U:`%W,{6J.S7L%T                      break;E&xg F([v/R
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/Vrz8h:K1k
                     Pop(optr,opr_t);
-H TzsSt&SO                      printf("optr出栈:[%c]\n",opr_t.ch);
9A'Y/y:A4C#KL5zY7y                      if(Pop(opnd,b)<0)
0`Qb7S]X&A"X"D                      {
UU:{v/b,I                          printf("Bad Input!\n");V P[7q)\z;~2z
                         fflush(stdin);
9M.ns.Y6[{NVt6q#e!\                          return -1;e m(];Bz6BT D4J
                     }nsYY+S
                     printf("opnd出栈:[%f]\n",b.data);7L#Gs+N,tUt_MD
                     if(Pop(opnd,a)<0)
SnO0uNS                      {
4k,C3~b.[9~Q                          printf("Bad Input!\n");
%tIw/\4~BN                          fflush(stdin);
/RA]9D1G!S4PV                          return -1;
W-T[d/oe9e                      }
Mzs E \y h Vh                      printf("opnd出栈:[%f]\n",a.data);5tV_jd3mM
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/w(qe9?/h/P7T2G*Iki
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
9WqNg0F?                      printf("结果入栈:[%f]\n",opn_tmp.data);Y&|F|6T3iC
                     break;
&|E-oK,P'K#X             }
h4va%Bc7^|/D:V4C         }%?&Q4Y1X7A](W4G#`S
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2mw#p!g;y?:v:A     }
~)p_#[;D1I7Ls     GetTop(opnd,opn_tmp);MTv3]}{:m{qJQ
    DestroyStack(optr);:HW#` o*I
    DestroyStack(opnd);
hDLi,h4] k)P \F     return opn_tmp.data;
w2g Qd1Wj;vy }
0N [ qX8fB `9yH C+b#i-_7M,@x%`(}i
char *killzero(char *res,float result)])a;R0DI$Y8v9q~
{Y[ m IGLgz
    int i;D;N}xW

v{7woUX(C1O\T     sprintf(res,"%f",result);
;\Y$} b;L&pE-H;N     i=(int)strlen(res)-1;
rb XK7f0aMm     while(i&&res[i]=='0')
p#p0a @ p8N     { WFS,j/aC
        res[i]='\0';;m9kNb*[&M)l-`
        i--;E}5m`:g;W
    }%Qmh.PC'}W'o6B_U
    if(res[i]=='.')a(xR+n!]Dn|au
        res[i]='\0';QV q O mu yg
    return res;X1D6EJ+q
}
Sm`i _ O2J2S6{R;UL['Y Q[
int main()'T/uU3phP
{
1nZZV;FX.K a     char ch;
"k.U*a.R+b b     char res[64];,e7P)J:@8NO.f
    float result;V&I {~8JlV
    while(1)P D%s?h g h%y8y
    {&Xh.R? u`w#m{
        result=compute();
]Pm:E0^CA         printf("\nThe result is:%s\n",killzero(res,result));
B/gVx.{h;d c1\         printf("Do you want to continue(y/n)?:") ;g(f"|uuW5T
        ch=getch();
k3Gcqhzg sP C         putchar(ch); w8v3Kd`5\
        if(ch=='n'||ch=='N')
5R rfg X#~s"_0G             break; Wh;XIG'@&Q,N
        else(hN4V]4|I e
            system("cls");
#aH1BypjtY     }GO"VO`dz5F8v7@
    return 0;8AS5{,@{\"T$\&[
}[/i][/i][/i][/i][/i][/i] A6HYu%R)qQR*\E%Z
!mGw!as,x
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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