捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
j0k~U?x{ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
:W dx7kU:U /**************表达式计算器************/
}#^ q3Iu #include <stdio.h>8s%}2PB9`e(xT
#include <stdlib.h>xL/jvRO.H b
#include <string.h>
\j;F/k'['?` #include <conio.h>g~/G6Hr1r4Q V
#include <malloc.h>
[z"a.UBC H
S/B4^i7h_g #define STACK_SIZE 100i-k7CS%@oF
#define APPEND_SIZE 10V5B5dJ w){0wxGZ

"h8^e4Q9[8W@ struct SNode{
p'h*a C(C     float data; /*存放操作数或者计算结果*/
3P]q)I@rISY     char ch; /*存放运算符*/]-W8Iogh
};$@'\2h2j5Z{9z#I
`y}bG#hT&Z
struct Stack{
.Zbr_0x/u     SNode *top;:M$_a.y0Cf'w$BaS
    SNode *base;
1H$uI+d]     int size;
V:^(B9nI"m:J };
\$RTt;q w$v4c7at vf lT(o@.Q4^
/*栈操作函数*/Xx#kXDID;G R
int InitStack(Stack &S); /*创建栈*/
kMH$n/q|1X7J int DestroyStack(Stack &S); /*销毁栈*/
%g_4[eyh int ClearStack(Stack &S); /*清空栈*/M*R(fziS
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/{Yp'dI:o L/YJ3p
int Push(Stack &S,SNode e); /*将结点e压入栈*/;h_7d;P a6C lR
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*//XWA YL2Asa
X0i,Hq C8?,X
/*表达式计算器相关函数*/
LT YC6l}B2M;` char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Tggps {5Fk0opr int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
F3f4G.]y"n float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
6z\3D;]k R1Z-z float compute(); /*表达式结算器主函数*/1R%H}@&_X#j!OJg
char *killzero(float result); /*去掉结果后面的0*/ Y1FVofHdl

0ZIYq I1H}Rv int InitStack(Stack &S)
C(YW9j9l-[B {
qk"\2ZN6o.[K     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
!b.mX\9iLSkH7^     if(S.base==NULL)
3[BtB,bS     {
2jKU|+?1D/yOAW%L         printf("动态分配内存失败!");
VB|7u7t         return -1;R mr6zY$@{
    }
PHx5_\,[W"n/D     S.top=S.base;5{E~G*L,I W.yjK
    S.size=STACK_SIZE;
]!t}K4^H[D     return 0;
jv S-l3_,]5| }9nU4M W3Y Y?"]r
0^!hw3J/Nl
int DestroyStack(Stack &S)tTxp/P:u5elZ]
{8F%xK9]q k
    free(S.base);P9~'`Pu fku4]
    return 0;
qx d4BkwIf }zcaYt"Oay

*^ _Y/m%c:\ w5U#S9i*F int ClearStack(Stack &S)
:WMK)c,a h;t p#G {I*m J VY$|`!r
    S.top=S.base;
vq!a Phb^     return 0;
]#K6q A"T }3h?[ n7x_{:XL
3jAp*W7os
int GetTop(Stack S,SNode &e) s:U*fs {YI*S6D c;l
{
z;x&C g5]     if(S.top==S.base)
KA{AghSU@#j     {
3^:N1i/`%|         printf("栈以为空!");
j6L c ~ J8jJ.si1n         return -1;W^0n,w e-NY
    }9U Ui~,@WQ3v~
    e=*(S.top-1);
;J"_FhVF.^     return 0;*sv9T:c8E\\Z{\
}.^&x:o^$J(_Ty
0g1W;|I6J+pF
int Push(Stack &S,SNode e)Nbz[DD P&p
{N/~+S7Y8u \
    if(S.top-S.base>=S.size)
kk#S#s \W#j hf[ a'o     {
C B.A\cO~6h0k         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
F}W.J\?.ZD,uv         if(S.base==NULL)mC$B\cxF%nBX
        {2DF { ~ B~-k7{
            printf("动态分配内存失败!");
~E/\ jWg$E&uu             return -1;
@nv$F:H         }*~i0n q(vf4Yo
        S.top=S.base+S.size;bU V N)l5P
        S.size+=APPEND_SIZE;
dL5n:[3_J])E     }
7j(G i+SQA     *S.top=e;
|3D5GEK"S)|N?t     S.top++;A8\[.nZ#Nd
    return 0;
*U|m wQ&~+X3NE }!]*kq J$Y)S`
\8F'e/n/I jv
int Pop(Stack &S,SNode &e)
~S8Jt"h sw^ t {!Q5N*L j"V/NP6v
    if(S.top==S.base)1n/\(Ig-KQ$^slA
    {
6i%E/j-_H ]         printf("栈为空!");
|1D%[9S)a!Nc@z         return -1;
t;D8f k{ e-P \:@2`5K     } } lY8m'v{Qm,H
    e=*(S.top-1);
*q1ygaS2X!h     S.top--;/]+`G)j b u*S
    return 0; L!y(Z;}Gp
}
@6x u }}\(?p$\/oGM n8mM8FUT5N$y p
char get_precede(char s,char c).P6I0N]H;Z q!`"v T m
{
)\(yHL Oj%l8{     switch(s)
y x4Ek3s3_     {
"t7M j\y8|r+?;|         case '+':                 %Z u4XH gB%a
        case '-':MWKf:`1cg!O|
             if(c=='+'||c=='-'):`&R\;yB;^
                 return '>';
!T yp.MZp              else if(c=='*'||c=='/')H8[7y-K W
                 return '<';&i9S5dJ Z(C't)v
             else if(c=='(')
&?3uO7U7^"[                  return '<';
~Qjy i/S)RS:oZc q ~              else if(c==')')
*MO;@,]-wA                  return '>';
7hA"x#U_a              else jg0aA8w DUi
                 return '>';
\de#uV&z,e^D A6x         case '*':w%AV4R^l]
        case '/':1qW3]"oWx$I ]
             if(c=='+'||c=='-')
xLDgl@;Ki/JC                  return '>';
'V%t |;d8K1dp              else if(c=='*'||c=='/')
2JVOoj$f.R                  return '>';
'@v1xy%CX              else if(c=='(')K$ya^9k%DK%Rv
                 return '<';^9F7iEpY%^
             else if(c==')')
+G6l\:~5ht                  return '>';2or4t9JP:`-dV k Z
             else,BC?9H-N
                 return '>';
6o3eDB1@ mE-L         case '(':
H|Q#X5SSJ              if(c=='+'||c=='-')]?uP~%~~2\
                 return '<';
:A*y5SS-K\"L!|7IJ$HC              else if(c=='*'||c=='/')
V _H#rGfG:R'N                  return '<';
wQ1lnchwK              else if(c=='(')
7?8b%h2[6C_L)Fp6D                  return '<';
xD$t K,^m              else if(c==')')
d Y} Q;p FV9^(wCV                  return '=';\L?/J mC
             else5E1c"Ym!q%} mNy0Rpn
                 return 'E';_mv{^j"T!rUT
        case ')':XPIH^
             if(c=='+'||c=='-')
~)X(W9s3|6S                  return '>';
&l}qaX:C              else if(c=='*'||c=='/')0[ K1f)^*B5dGp
                 return '>';swUM? {6a#W"g'y R
             else if(c=='(')-Y(qi Lt4G%rK
                 return 'E';U4n1L OJ{7A'^
             else if(c==')')
5f5V,ie3Ie7K                  return '>';
7P;Qb-NT}k              else(IZ3qp|7n;VN;M
                 return '>';
\y8^`GJAL         case '#':w-q(@ @.h0K;T
             if(c=='+'||c=='-')o2u,w/A5iF e\Gl
                 return '<';_6wSEcrT H
             else if(c=='*'||c=='/'):Dl9|3s&j~
                 return '<';
;M`z6Y$K^ Y              else if(c=='(')
5SJGP9e5z-hHx s?F                  return '<';'Ez@:w%awfa'j d8k5u
             else if(c==')'){??;e|E-|'[
                 return 'E';
6|M&b3Bd`5X^-M              else
R.Qs1J,d G4} j s                  return '=';RH4Zv+GQ'@
        default:
6S L$NyI)ql              break;
+{]Lmmf8O     }
5p E~!_!Z N     return 0;    5W9uh nk4an-S5ZL
}
(j tbd`"wM0tz$m
z:G9\d{ OvA} int isOpr(char c)
8{TRRL6h0|-KU {
5D H n N-L}     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')gy oxb5Z*^ E
        return 0;9a"?!aX1Ht.P'u9p
    else
J[$@RyLM         return 1;
1yxN&Hp*s8b-Q"\ }
Z7x+F be,YiH+t2m^+E
t hO3_H float operate(float x, char opr, float y)
B;P7JsT {
t.e-faE     float result;
#eN%StJ)gc)w}     switch (opr)
Z%q6f;y3F)V     {
N r;nN8u|9|A/D/yTI         case '+': 6~S*mFp!?]
             result = x + y;$u!@7_5@%ud W^ipBk
             break;
O9\ x;TcN#?]'h.Y         case '-': ,ZLU]7@1`R@T
             result = x - y;
7G0k&W*I,is-l|              break;
9h\$r"g*p{n!z!k         case '*':
a)Q/u2Yjg~              result = x * y;dnjDr3n{d f,?7{
             break;L}3M9HCRNs
        case '/': P Xs/mgyn
             if (y == 0)
,xJ ?^^,Q              {
0wE{ |@w@U                 printf("Divided by zero!\n");sPd(cl\
                return 0;
L!B6YI|-?z/G'Gd              } `-b:r w2u{
             else5jE@ a'rU
             {
vG5H`W#F| jn L                  result = x / y;0uP~4` A{ i^
                 break;O?HM2mQoQo6X
             }
#M,G3h_ K Ij        default: NujXnFjvH
             printf("Bad Input.\n"); zI;x&nzes
             return 0;HK1pDw%ue
    }
!ccmwCR     return result;lo L:{5L]3[2] yku
}    *K:]h3rgOju gF7Vu

4x6s [(eP1Wd4o float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6U![_+eO
{
E t'})b.cB:]O0f1f     Stack optr,opnd; icNU2c:uf1d6k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
_V2n} j1Qm     char c;1m\3t,V+~| n
    char buf[16];
#Un Z@ KE8k9]     int i=0;
(|"G'MOej?7k A     a]vpo_ \x!A
    InitStack(optr); /*用于寄存运算符*/,B3l+|-vnT7kG#d ^A
    InitStack(opnd); /*用于寄存操作数和计算结果*/b:{8d_6[5Z0g5T1K
    memset(buf,0,sizeof(buf));
:fO0d C4xc9aD O    
l]#~b7?     printf("Enter your expression:");
"n A;k1v`(Rn8G YsY         F^]qQ1se![
    opr_in.ch='#';2w;J@a)IW8I ~%tQ
    Push(optr,opr_in); /*'#'入栈*/
A1OK TK#o     GetTop(optr,opr_top);Vr`7hX
    c=getchar();
FbJ6AEm&N     while(c!='='||opr_top.ch!='#')p.q#L Zy,N&Up U"r3O'TY
    {GN7p%^`C,nU E
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
:C \? si VkO         { _FR W,d,Sbl%Wl
            buf[i]=c;%]I"WY)R
            i++;k P kE A/ywO?
            c=getchar();
8y fk8FN#E'U         }
-W^{}+e+[U#r;n         else /*是运算符*/1ssXb+a
        {I2D/ZQ aV
            buf[i]='\0';+S2Uktt
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
!}n,N8k3M.us             {\&uD#`O7F
                 opn_in.data=(float)atof(buf); u6V(cA{d#W"p
                 Push(opnd,opn_in);
M1MG(ZA.}A-O;K Dx:g                  printf("opnd入栈:[%f]\n",opn_in.data);
,zq$y8W9S-SG#zT                  i=0;
2_;}g@`"SU                  memset(buf,0,sizeof(buf));
nJ@k{3x(c X;g#J             }
#aQ$FUi E mD             opr_in.ch=c;
4_+X{z,N-Hm             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
f)}2mo!qo X             {
T3d9o w Nv`^                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Gy,P"~'{@n                      Push(optr,opr_in);
.R(Q4uGTS&T zM                      printf("optr入栈:[%c]\n",opr_in.ch);
@{&V/{4V                      c=getchar();2m)A\ F:j5S)cya} L
                     break;
pdth L5C                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
LHe9U\:V h-}e/L W                      Pop(optr,e);!pJ:wt Z5u0u4]
                     printf("optr出栈:去掉括号\n");
hbx,Qs)t(|;c                      c=getchar();
$R pv%\eVr|                      break;
,Q| gE[(?                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
#`f TF3FucB/rm3d c                      Pop(optr,opr_t);
1UZ*\R8irE                      printf("optr出栈:[%c]\n",opr_t.ch);,|B Q!gI1Qn
                     if(Pop(opnd,b)<0)
O-|q1`-QE/D5t                      {
9p7`'a5R6BjR@(O                          printf("Bad Input!\n");[5{6x [3}/Ud7Q0?t
                         fflush(stdin);e*@Yp%|V9N zTa
                         return -1;
i4a)Z$Y o\ E Vm                      }
0VI+V(NH|rL                      printf("opnd出栈:[%f]\n",b.data);&`m:Oir s&e4c
                     if(Pop(opnd,a)<0)
'm+O};G h                      {
_:\e Sp(i\                          printf("Bad Input!\n");7U.L_ G^W0y
                         fflush(stdin);/h0~,a.hHD P oc
                         return -1;6fI5M w w]F
                     }/kIAe.[1\;il
                     printf("opnd出栈:[%f]\n",a.data);
zEl x-Q [*c                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
@_j|&C1Zx"bS F                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
#o(}/_0C)s*ei                      printf("结果入栈:[%f]\n",opn_tmp.data);
W?&\ vFP6U2r'n                      break;
Zk9?^w             }
U6L$x m(h B         }Au-ecr:`
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7k9S/t.N5I ~ k g2o     }
Y$X(fs'fm"l     GetTop(opnd,opn_tmp);{6KLo(c&\5nDn#a
    DestroyStack(optr);
~0I;g F\Rh*Q`     DestroyStack(opnd);V,HB WR
    return opn_tmp.data;2k I&xo/]%d-}1d jZ
}#Ak;~o6F M9B

n rF4iG G6~ char *killzero(char *res,float result)8`x t z;fI\}
{L"xMz8{9G?_/p
    int i;'m$]f7] Co1o
U,dP aJO
    sprintf(res,"%f",result);
8M C`#k${#Y6Xi0^     i=(int)strlen(res)-1;-K'j)h3Dmt
    while(i&&res[i]=='0') @1j%_1SN*t
    {1X!pK7_ h1{g a
        res[i]='\0';
%_b t(f qsGc!l         i--;
!fFGd^8U|7j.Jk     }J-Y O/k%d c
    if(res[i]=='.')
0k d:J&}|L6jt#l6w9gf         res[i]='\0';
*F+t7T:M},\KH x0s     return res;
"xA{|Chw h }
9Z|#T*IN3@|$[5c_x&x 5u5Kqw O;u S
int main()
*[)?@-`*I1H {
zUWsf |U     char ch;8~&V|~&R)k-tk"L'L)t
    char res[64];lIA$oI$nd M
    float result;
^6f0G)J!D.goT7z     while(1) i9V|1\8[K#U
    {
+Nr-U)f_         result=compute();0pf3VFvW/}!\
        printf("\nThe result is:%s\n",killzero(res,result));
y-OE8@Q.z ]1w'a         printf("Do you want to continue(y/n)?:") ;'s"es(L \
        ch=getch();
X9[wzY0`b[+Z         putchar(ch);f,_L7o:V.C
        if(ch=='n'||ch=='N')jD$zkY5GD
            break;;~7{'Hd'SWA@
        else!p]`!@;P[u @
            system("cls");
GF8]0qV I     }8@]ZgV
    return 0;B\2H.l Em ["A \r
}[/i][/i][/i][/i][/i][/i]
-F.UT%J9u#w`t
o'Y I[*E!Ra+v [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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