捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.H0b)r:j5Z%v ?-}
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=-Z?&U%CsK `
/**************表达式计算器************/
/X a)W1S%^6v${ #include <stdio.h>
2WqPJ1g@Qh-q #include <stdlib.h>
v+O/i6D U[&F0A/n #include <string.h>
&g8an&f%OG*Wj t #include <conio.h>
S0a3uz}*r5ba7a #include <malloc.h>
9nw ^&p;W"{0O Q9{!_/O~
#define STACK_SIZE 100;R"H7qwPl
#define APPEND_SIZE 10 qf+Q@tyA5Gh

p y\f$c struct SNode{v#[3y+^(l[
    float data; /*存放操作数或者计算结果*/
2h TW ~;f `lkt     char ch; /*存放运算符*/&@)JR1gQ{)j@$q
};
N ["Q Ej f
T*q[!`A'Al+J5v @ W)r struct Stack{
q:M)Qm+G.N+_ x"B     SNode *top;@@-D$b;?tLj
    SNode *base;'wEp%F&k8X6^ k+Q:_/R.PG
    int size;]VJ2y6IE&y|:@ U
};
]X9n'XD%B x3FeRs[3}aL
/*栈操作函数*/1piC7g:zN/vV_
int InitStack(Stack &S); /*创建栈*/[rV2nz
int DestroyStack(Stack &S); /*销毁栈*/
d7B.IE%N2pp1c2x8U-p int ClearStack(Stack &S); /*清空栈*/
1ui5pd/@"`\0g8c4Wm int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/SD7dR D
int Push(Stack &S,SNode e); /*将结点e压入栈*/0u V(B&J I@l
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/za;|(w}GX+~

-fr0z1[lUIcG#D{v /*表达式计算器相关函数*/
P)g5T;w$c'hj+B"] char get_precede(char s,char c); /*判断运算符s和c的优先级*/xSA$y/d xo_i H
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ {3u~Fk.\#}.S5R5r9Y.L
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/Q-x)tj C{I)j.Xs8s
float compute(); /*表达式结算器主函数*/!@|4fq\"CO8fa
char *killzero(float result); /*去掉结果后面的0*/ +Ue#FpT+|)}@o

mU2t(_I1n$c'S$~u int InitStack(Stack &S)} c*Zx?+r \U
{I;i*A(b}"w
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
p~2|tA z i     if(S.base==NULL)-K;g ?7`l*w
    {
MPfO7\3ak         printf("动态分配内存失败!");
m1p8i.j7g6?6^ c         return -1;
$Vi$g'h'o`     }8M;wc9^sE
    S.top=S.base;QUhs9O7a.F
    S.size=STACK_SIZE;
c6gBL n}v"h     return 0; R.{-Fq}1V!CH
}
)\+Q2^b7^q4_?
&cuHK;i9T int DestroyStack(Stack &S)Py j!w\sF/df Om
{
q BYd2yN4K!d     free(S.base);
-`3V1h4D'j'h.j[u     return 0;c2W.Cc LO
}k,Q G,O9A8n"u
[xa*FV6p{v/r@
int ClearStack(Stack &S)%V9lSL |
{r,SF/HTz)DX
    S.top=S.base;
f}T0]0u(~2@ O     return 0;
cDQQ W D)SvCe }A^J'n bxl-?"z

OK6U/b*y/mL int GetTop(Stack S,SNode &e)1D1t$JJ [y&X
{)m+O$l~'ufm6}_dn
    if(S.top==S.base)a8s(uW.c$C T
    {$V/?1D:`@:?5V
        printf("栈以为空!");3be{ L)c\
        return -1;{"gqp}Qyg
    }F y2@9l&Y3M Bu4k
    e=*(S.top-1);-l"_&``!x
    return 0;2G"ZQa L+r
}
&JqN4I3F$|2f,G?
6t*Sc;Pk y6W\z1? int Push(Stack &S,SNode e)aw O$Rp
{1Q n#gMK
    if(S.top-S.base>=S.size)
e&p/SY qRU#X     {)Aqg7b:u-fWtz*r1G
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));&UGQ!h"V4f2e)G
        if(S.base==NULL)
q2Tx\fi"t'y&E         {2Jr-I9L&{n&YU
            printf("动态分配内存失败!");
PUk Uy7}:p3CQ+p             return -1;)b3`Eml
        }J O G$zDh3qD
        S.top=S.base+S.size;0iLTl\r0RC
        S.size+=APPEND_SIZE;AI.gO1](m c
    },s(BK a W:ol tJ
    *S.top=e;
n#`MZ&c     S.top++;-X-gc!| vJj8Kj v
    return 0;
UQ s/xOr/b }
g-s}q:UX
E\Q&ip8C T int Pop(Stack &S,SNode &e)
$@;?3^-J Y6pveYVn6Uy {
0m#?q @8|];_Wd Spo     if(S.top==S.base)|]5Z/Ea!_VL
    {$g#e.c K5t0?
        printf("栈为空!");#~g k1\j
        return -1;
5ZFy(y'gRb-Sq\"R     }
,s"V1tK/r].k)F     e=*(S.top-1);
V8MD#g8llG d e     S.top--;u#yx;_lIA
    return 0;
2O/FS@0bsTA3A }.J2u0} d?%q

eWld,s?I char get_precede(char s,char c).W!hB&WU
{M"T*t0m+v\,D1W
    switch(s)5M6v(T8cc
    {8U/xZB&x1hb\
        case '+':                 
]2|i9h;PA*R N6Y         case '-':
kw&I9b*M7P&N;|:Fc              if(c=='+'||c=='-')Ya:FS@M
                 return '>';
7}b}-xK              else if(c=='*'||c=='/')5P@${8?)urX(M/R
                 return '<';
k&RBl0M?              else if(c=='(')
U{p(\U6\X%e5aC                  return '<';Y-^$r5z(mm
             else if(c==')')Q Y W`nE"k(C5Y
                 return '>';#@_*^9fB-X ]
             else H;q8_1R3gPbb?
                 return '>';
[k'Up'@ ~tq'{         case '*':
7~!r*M"U Bqs"j         case '/':
3]9c _O7m$tBS              if(c=='+'||c=='-')
4i)bSS7?t%gV                  return '>';2C!v&E{ O}s3mH
             else if(c=='*'||c=='/')
-l ?"VQ3?#c d4_\                  return '>';gZ{^*w6a
             else if(c=='(') ` S CA#q!k
                 return '<';s&YncuU-QKCE
             else if(c==')')
v s,C%LY9s1HYG*z                  return '>';
\MG }:Vn;{`#b'r              else$cW+E;w:`#nPd
                 return '>';
#U!^6O CN         case '(':YUww]r2j*x$A"e
             if(c=='+'||c=='-')
9E1|6HT{[2j2C                  return '<'; nm$R3p;C,G+Nj!D
             else if(c=='*'||c=='/')"YkHN0L!Z v| j;KX'q
                 return '<';5c6|"H}dKSt`X
             else if(c=='(')o5]%Z A2pJ&w@&@ H
                 return '<';
)B\S j*bf(M-A#V              else if(c==')')
d e#`V)a5J)U;A#n;\                  return '=';
:H+i+XW[hh              else
"g*sQ^ _Fs                  return 'E';3g1C)\(Y9^~"q/fV#{
        case ')':
g+PL}#Fw              if(c=='+'||c=='-')
B q(@C"?I/l                  return '>';
+M Yi-ur]QA9t}              else if(c=='*'||c=='/')_ _.P5R W${;mL wi
                 return '>';
r;u;o G4C:g$V,T$AS%[&Z              else if(c=='(')
9n+M%Nt,O7uTLq                  return 'E';
-B"B6wGu              else if(c==')')g.WGv)B)r,J#Fa
                 return '>';Uv G bu8J3eZq
             else;REZa*CpOfa$s
                 return '>';
Zw-Bj+a%s'n p         case '#':
"FC0l4R$k              if(c=='+'||c=='-')
Uju1vQ*D;f,}+R                  return '<';
?D RUy1a(jN7K              else if(c=='*'||c=='/')\(p Q3~3K
                 return '<';
3w$B:a-qY7f!@              else if(c=='(')
Vz]bo)k4Ou'gu2w                  return '<';5MU{j V"pRKC t
             else if(c==')')
6D:n2XpL-B s5H+[I                  return 'E';
z q2y9_s4];}              else+c"}N"?HmT
                 return '=';
.K#EquE         default:5{S%AI z
             break;
7w+k6\"w(b[Z     }.S/T/}@K#R qM~9?
    return 0;   
"e D!A8^9E&p@ }
.lo&Z%y3I]i6R8t o-} h+z!@'s2Grp(u6[
int isOpr(char c)
a,c!C0gk,NJ8V {0a~\ \ Z,o5c9W0z#s
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') xh P[:e g8p+q`c
        return 0;
#Z2R/B)~~     else
5G^ [6w|.`2GPn         return 1;0?p7b H`
}
4]]1P$wIp"KS'q
],~o*r?B float operate(float x, char opr, float y)
V4I"]+~!^ {
Yn CoF,A5g     float result;
C f-NaqFy3sg xE     switch (opr)
"sMj&|u0F T/c(Y     {7ZF&_ _/@%uX k
        case '+':
aT!I F SBi0G              result = x + y;
B RoXW              break;z9F^K7gA/d
        case '-': P1o5otHl
             result = x - y;2S |S3zCV:P7h4_(iz
             break;@Q)p&iVl!t7| q
        case '*': q/~9xY,e K;alx2^
             result = x * y; W XJ7b2Zo.qC$k
             break;H-o%Tfe
        case '/': *@Rqy x7}6Fc*N
             if (y == 0).IPJn'P{d_
             {8Iz3Xy9MeW^3RU
                printf("Divided by zero!\n");
_ xK&i;U&l@ Y                 return 0;j;S,CG]c4p3V~
             }'X;c%l1P ^+u Dw-o
             else4o+Q1P%Yiw x
             {
%Q?E(b-@                  result = x / y;
k!ibI6LV.Z4c!e                  break;t~y8O*Y^7T
             } ~N:K]p S
       default:
i$^F"e v:A              printf("Bad Input.\n"); &?h"E kQIg s
             return 0;5t!X\sY1T
    }$o9C7|.N.E4u g
    return result;V^kKL#?9G
}   
.[7?J{c)Q B
rB$n.~7Ks!D float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
d3F Bz4M&Q"t3v"o&X&zw {
t+y-Sz^*`Ke     Stack optr,opnd;
8H:r"s C6o     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;9gR4\,o9?+a*y+JQ
    char c;2Zz.`lr'@
    char buf[16];,U fH#Ws9Y o#?
    int i=0;q+K*y7d.{+YD
    [9h*F%TX9Lt
    InitStack(optr); /*用于寄存运算符*//T'w[-I?)c
    InitStack(opnd); /*用于寄存操作数和计算结果*/
Z3D;Jg'z9x1G     memset(buf,0,sizeof(buf));My+[)?E/B9d7tRr
    &U E m#C*cB6? O"szK
    printf("Enter your expression:");
O2NvA&`+])x_         
eZV6H \g&UT:K8t     opr_in.ch='#';
W0B{ N1xX&w3I p+K     Push(optr,opr_in); /*'#'入栈*/
~)s.aPa.^5R     GetTop(optr,opr_top);
xpw c ^w~.P&l%_K     c=getchar();
iL} z)Lv;}(X*|1}+H     while(c!='='||opr_top.ch!='#')
#ho6tZ$qO(\*WC%L)Q     {7r(Z[onx!]mN9R
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
cA8o vx|k         {'Hsf'U`)^5E&W6ca$r
            buf[i]=c;
$cp#Bu9U B             i++;n@3Cxy;_
            c=getchar();0`:^5iVz8zD
        }sbx[QIu8iHC
        else /*是运算符*/:Q8fCB#~T#a
        {
Y*B:cL VI             buf[i]='\0';M7lL'c%`8C[Z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/,i9p~3E*T
            {
U!Fe,T~$r$T                  opn_in.data=(float)atof(buf);4N"fe'{F1[]
                 Push(opnd,opn_in);Q v]i]J;fl4f
                 printf("opnd入栈:[%f]\n",opn_in.data);K(Wl3m_6c[9o@
                 i=0;.N1A1N8Z;]*E
                 memset(buf,0,sizeof(buf));
@*t&[HH             } b)K7]o/f*{s
            opr_in.ch=c;
6G Jhuvn             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/X&N b"?J}r/S
            {aG ^{R/\C
                case '<': /*优先级小于栈顶结点,则运算符入栈*/*z7I*v/L7^1n!Dd
                     Push(optr,opr_in);
o m"r(SBx s6M0eM                      printf("optr入栈:[%c]\n",opr_in.ch);
4Rt\ \5{                      c=getchar();
H9t:xi*r9v_                      break;
Z0J#T*flW'\                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/%o%H;r;H5~ {U
                     Pop(optr,e);3TWFMSlH&r7t
                     printf("optr出栈:去掉括号\n");
X(l'xF&O                      c=getchar();l t ^eG"C4p
                     break;X&n Nx'mk
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
^#}.vUYm:H                      Pop(optr,opr_t);
.s7kv1YV#IB _                      printf("optr出栈:[%c]\n",opr_t.ch);*r9x]o"DF
                     if(Pop(opnd,b)<0)
cf(O`([2a                      {@&C!mu}W,Q'z*rK+t
                         printf("Bad Input!\n");9tU\ ^:By
                         fflush(stdin);|A q^;S
                         return -1;
bZ8k q[0r                      }
&X-|9D8_1Z.L\*M[6M#i                      printf("opnd出栈:[%f]\n",b.data);#}OC.AeK%AL&N
                     if(Pop(opnd,a)<0)/K R*E:vLvL?QtE"i
                     {
dE,Dp#S`6Dwwv                          printf("Bad Input!\n");.`@ R _,X:|sF
                         fflush(stdin);
aK T,S`                          return -1;
i0S0^Da                      }
W ux'{,{/s u                      printf("opnd出栈:[%f]\n",a.data);
9S'Kk fp!P w$l&G)s                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
!uB'F2`P1?-s                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/!AZ v|?%SXU
                     printf("结果入栈:[%f]\n",opn_tmp.data);K-_A(_ U&t1W
                     break;
HX"ZH\1{U L             } kd%q%v6tv
        }
E h'd0y6[2w!R:|;z Z#v1E         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
5J)?.j%X8fb*s,tn~4no     }[U h#_V9RIK
    GetTop(opnd,opn_tmp);:z wm#a1y ]Zy
    DestroyStack(optr);?:j3`B5|%r2D'|
    DestroyStack(opnd);.V!R3rh6Woo#`
    return opn_tmp.data;
PQ,Si(X!m }
Y8l7\+I kaB
Zwyv5r char *killzero(char *res,float result)1p_0d;?W
{ Z#w8}8{1y
    int i; Y(R[B,X O6{'Z@

3{2V.a,A$O/t'g|     sprintf(res,"%f",result);
+[6B0W$Y"a7kn/h"z     i=(int)strlen(res)-1;
bC-K*i0qA%I0I     while(i&&res[i]=='0')
YNv9R%Y8x4W     {
.ek} x-n!SF         res[i]='\0';L:IO/[9})y
        i--;l6OPlJ!n/s
    }
$X.[+v2cAQe7U     if(res[i]=='.') a:Q.C.V\I#?
        res[i]='\0';
JW4|{;y C!h@     return res;
-I;x&P8SQ:O@_ }.`5k"H7G'O Z'}#c;kO
_0K0J+b+N*A;B
int main()5X2@g$Id:?
{i4Zslbd(T
    char ch;m'dt Z0hO4t}$V%| {(T]
    char res[64];$yjPuSP0U
    float result;l-p$l;F W}6p$HM6F
    while(1)&zt:i(T.oL&}4G
    {
}.Z+W&?4PXw.E@         result=compute();y{.XZSk!F*n @tj
        printf("\nThe result is:%s\n",killzero(res,result));1v#{x/c#a1y n5_4|9o.h
        printf("Do you want to continue(y/n)?:") ;9K&bz6c"w9O.D \
        ch=getch();'^hnoh}f#u
        putchar(ch);
m(z:`7U3s`Rx         if(ch=='n'||ch=='N')
[(w ZM"HXSRgB             break;
PS:DTi g         else0Df'sWhSpb{
            system("cls");
EP!tI?~     } M0hw+g|A/B}_N8vU
    return 0;2Q,`;KS|$w)C
}[/i][/i][/i][/i][/i][/i]QcE!P]sS0u
r7s}4p3_II2x'M*k_
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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