捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
#a(jHU4X c!D 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=N(_$zzX7A7h;F i B h
/**************表达式计算器************/6a+WT%OJ~4O
#include <stdio.h>
JkLNb R #include <stdlib.h>
,c7B^YL{]E #include <string.h>
k-^'j-c#|o #include <conio.h>
A.q"R8k;v #include <malloc.h>
Vy$T.@ O,p;d[
wt s9Nl j0w;Uw1\ #define STACK_SIZE 100
3a7B]%[&]MT #define APPEND_SIZE 10q:h@-l u5^D$|2mk

qn#rxML d+B struct SNode{Xxkh[
    float data; /*存放操作数或者计算结果*/XV3r%Nyd
    char ch; /*存放运算符*/
f'b!e-lN_7{ };
[Q e q[0O vpD EJ8q9wh!Py
struct Stack{
-V;?P#bX o2V't     SNode *top;
(GT0M@!c(XV%S#q4_     SNode *base;
.i;\"q(L-T?     int size;0i*a#dM\Oh
};hI/y7K]
(pF-@4~C+HoI@k
/*栈操作函数*//u2G:|"rux
int InitStack(Stack &S); /*创建栈*/+P9vC[4q#et9kE b
int DestroyStack(Stack &S); /*销毁栈*/
-A6U~1}0t s2uk,M$U int ClearStack(Stack &S); /*清空栈*/
,Gsm4id"S/\ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
{-u$st-OB[M%|;O int Push(Stack &S,SNode e); /*将结点e压入栈*/4{2R/k/QQ H)Q T7K
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5uLv4}q\ bb:C

7jL+N|zNfx5ycV'` /*表达式计算器相关函数*/
!QR bMf)E char get_precede(char s,char c); /*判断运算符s和c的优先级*/
(oc%P#T$B.suO9J)fG_ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/!^#OP#W[ X*I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/t'I XZ)e&i~Zxq
float compute(); /*表达式结算器主函数*/&iv\#U,J%Y(vIc
char *killzero(float result); /*去掉结果后面的0*/ 8O(X.DM3V-Vq
'A bP{t/~
int InitStack(Stack &S)
7Db.q#L_ aB%Q {
x$kn B$N,W#?8J     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));3E |H~"@2Z
    if(S.base==NULL)k4y4s"\"k
    {Qn sP7F|5v(B
        printf("动态分配内存失败!");
9l.JE c3\         return -1;
Y{e fx     }
sA/g{-gPh#jSO     S.top=S.base;
E'_z9J:f%BJC     S.size=STACK_SIZE;:`$C8[])Y!n+eU
    return 0;
&f!TF+wM4C%k9r }.Z5@#rV!H3~R
)p]o%cg
int DestroyStack(Stack &S)
] NP vQS+hiVi#v {#L)uee)~ V$k B
    free(S.base);
0Krxn7wT     return 0;6k*}4E`8[4qX
}9Ke D(iq:q)gZ
"drk b\JrB jxD
int ClearStack(Stack &S):i6UCh| bZ
{
C;W2z2}8Gtjp     S.top=S.base;
C!b `!B!] m$o7~n     return 0;
7\YG)jJD;o }%N$R8` }
a[+w(y V 7Iu*A ]|y?
int GetTop(Stack S,SNode &e) G+ux!q(gc w!D3h
{f `Fhy9w7T I
    if(S.top==S.base)
/q,C-D(K}W     {/A? {?9R1^
        printf("栈以为空!");
/Bn'oJv         return -1; GDo z![i |Vb
    }l'e+o XW!SIV
    e=*(S.top-1);
(~i&ZE"j/V\     return 0;
ES/B%ua L Dc](l }2z1CX qK-|GQ
MJ9RhA
int Push(Stack &S,SNode e)
s9ys,y2P"@/I0A F {
E"rF"U+M'Wk:^\_     if(S.top-S.base>=S.size)7C)iB~Z_
    {#z%Yl]5a^-_E f
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); L;Jo&A ~oI
        if(S.base==NULL) a1t3`.g9O'_~
        {9t'_8{~:g#FG
            printf("动态分配内存失败!");%F5hVP#sPx
            return -1;
W8OgupfpD#l5|         }
4mV ADMdl9WCx         S.top=S.base+S.size;5d@J A&WvI v
        S.size+=APPEND_SIZE;
0Yt&~1fE6K ^/]     }
;Z;@g$m ]$p\     *S.top=e;M1lkd`#zg
    S.top++;.{^o"j3kO kx
    return 0;
2\)_"m2MZiXk5|wR;if }HI EY6P8\{|

G0Y-v*U(g int Pop(Stack &S,SNode &e)t p uIm b
{
XJ#|$?4D     if(S.top==S.base)
w8RE5Hd(g     {
;oBk:th#m9Bc         printf("栈为空!"); hT1BE:zXA q.GN H
        return -1;X9Yd'J!C2n
    }
i2Bpq!a2[.[ nK r^     e=*(S.top-1);
*`;W0AhVV6O     S.top--;\+zpZ!TL0U(dZI z
    return 0;
q.`G4xK \q }nw!P1BGBn
'~r?;i1@N?9e
char get_precede(char s,char c)
'Mw7\c4Y[E]dQ {Ri-cLt)c
    switch(s)d Y*W2mdI
    {J9C5E:D&\/g h#hj2C
        case '+':                 p5dOI ^6`#t-E"ikT
        case '-':lOrAtK@
             if(c=='+'||c=='-')(lMl9[6~?-Ea
                 return '>';
\-dn.Y,N&Lu)x+f&_              else if(c=='*'||c=='/')+Z:fbgDIU
                 return '<';
0F7TK;S'\Xdb              else if(c=='(')
'\2ie(f0CFQ                  return '<';%{!k9wIRj4j'{/X}5Jg*tx
             else if(c==')')
p G'far-S3i-U}9V                  return '>';%c#O)X$rI
             else /w\(m"lIl4d oE
                 return '>';W`*@[kf
        case '*':-zA'D$C#U"rdAss$`
        case '/':
|)Y5M6d2L F3]              if(c=='+'||c=='-')
Sg+s6G yO]                  return '>';
.A M%Jv.y;n.]}t@              else if(c=='*'||c=='/')M]G;U({#J;N6e
                 return '>';
8R L9o0n"h dj              else if(c=='(')
IeDV9l)D _                  return '<';
.N*P0eW"~U6sQ0\a              else if(c==')')g#POG_ij]
                 return '>';
,~ WmmZ;`              else
;|(n3Ba+T;a                  return '>';1[ Wnr~-B
        case '(':`i~1F'^Z6?^H
             if(c=='+'||c=='-')
R8[ P.k){g$JT                  return '<';
#B3x`E*L0T nXY&r              else if(c=='*'||c=='/')
qvH5UJ:I;hCQ                  return '<';
0}+c E|.Qo)ew!EF              else if(c=='(')
p:E"q{*^*P                  return '<';%SZ7["\\2M$C"`7R
             else if(c==')')
@E+h]/l2f                  return '=';
tDN\*h(H*t3B)o/V              else
[\gP ` ^Y"z{$l                  return 'E';e Bh ]L1["_
        case ')':E&\1c&U7k*j K]
             if(c=='+'||c=='-')aZLDOJc
                 return '>';
]h_T'GN}M              else if(c=='*'||c=='/');C'J3g A&y9V@
                 return '>';5U'L5VaD e [
             else if(c=='(')
(oR/iHB|r~                  return 'E';
;YL9N1?NF/Mq              else if(c==')')
j$k+B)YCct5|                  return '>';\"}z,Yq f
             else
K3`}U O(SOPu3{+f                  return '>';M5y/Cc:G2Bn-q7I
        case '#':
j/M+M [8~7Ny!\              if(c=='+'||c=='-') ~$W:M2b swe8}&]$g
                 return '<';
K$ff ?u:]$y7LZ              else if(c=='*'||c=='/')
0X rL/`9O I7@`                  return '<';7}5Oq@AW4[
             else if(c=='(')/wk{;u P&z5f;Kb
                 return '<';*C/JDYUj
             else if(c==')'))Ea3Y(|3a_ Y gT
                 return 'E';
&Tb5AOCw o              else&t:rx d0o?;kt|
                 return '=';
-W;x,k$n1l:j         default:hmOY*L
             break;
iw;T]1B HYw n     }XIA.WB]['h
    return 0;   
ES'E*FpG }}U:c!x8UQX0i

T kE t!Nf2W&Q} int isOpr(char c) JTc#x+QN1h
{
;mL$vLdH {     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
o Y7r*g-nf#U         return 0; w{Y,B'gG
    else m.v? Qk!V_ ZH
        return 1;#u9e*@:L7\y)h
}
OX"w"U Oo nn
]#Igm2PR float operate(float x, char opr, float y)5]^2p@@F?9pt\
{X%kbge _
    float result;
$t ^#q|sT hF3~     switch (opr)}`['k2`
    {
,z/|!nORrN         case '+':
U.j6}r-E }7t/E*R              result = x + y;&[9m.^,E9f^.K }}:g
             break;/G m(K/F8C
        case '-': %d9{;]T#i a|e
             result = x - y;
$U,We7| d q              break;
~SK^!g#H6Z         case '*':
,E;C/}&^&s              result = x * y;;k-R[ P*q$Qy
             break;
2I(\b0cU&y zU~         case '/':
\tTq0a4V6c              if (y == 0)#j:|+UI x`
             {&J K3P1X Pt%Z
                printf("Divided by zero!\n");
B.Kk(T.p                 return 0;$f a*g/v_x2{l
             } T MnV^
             else-o,h8DP*M:c
             {
uL(m+}(rPae                  result = x / y;
:tDZ#g,l                  break;X/z:FMNb1kR3@ w{
             }$l0Xn D~5o^%u
       default: ,E.y:C3F9t!ZJ'me
             printf("Bad Input.\n"); 7K1|$xLac,l
             return 0;n4PCa-P%y pG
    } K%R|p {@ z
    return result;
cgbPxs }   
}/hI:f-md'eX*?
t5fn!W$s float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/}Uh Kx\ O
{"J7O$d,LUmp
    Stack optr,opnd; QtG s4p,D&P3M3k"s/K
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
8Ab8X;zN`+hp#EU     char c;!@,`a-Z9Q
    char buf[16];M7BM,A%E9sHq5a
    int i=0;.s/l*Fz*E"Ee5z
    yr(H/O-?.U1i,_
    InitStack(optr); /*用于寄存运算符*/
_eEn]S4WR _ JK     InitStack(opnd); /*用于寄存操作数和计算结果*/
ds-N.| N3S     memset(buf,0,sizeof(buf));t.g+b6wJ|f.GI M
    ,WcI(`#hA)S
    printf("Enter your expression:");T\"z'@&H^7J
        
]-gL K%e0q)f     opr_in.ch='#';$w.F8Z6E&} ~#x
    Push(optr,opr_in); /*'#'入栈*/;D2gZQV Nu.N%u
    GetTop(optr,opr_top);
@?/I$Op1z     c=getchar();
aQ5r*PW5C6w["i&?     while(c!='='||opr_top.ch!='#')#N:IrwQ1X'J_/['r zQ
    {
4@c/kh+\AS"Uv M3}         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
|AN] \ V:j Wt         {amI,E+D:m)_
            buf[i]=c;+~$v _GxW)r!V
            i++;
\({Z2NH:e H| D d)C             c=getchar();(N6KT+\ u[9b
        }
H_,q w)l)b L!QQ:rW         else /*是运算符*/"u o L-f3{
        {K)^G!n*jB3~\R[
            buf[i]='\0';EXf'l"Bo
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/Z)Jc6Et+x7|R Xy
            {`[z M+p2X5Q
                 opn_in.data=(float)atof(buf);OD)uE0nz0g4Qt
                 Push(opnd,opn_in);-F#uZ3n.r:ax9~
                 printf("opnd入栈:[%f]\n",opn_in.data);'Ad!Zm{M,w,kU
                 i=0;
x3u~d I-s9F}                  memset(buf,0,sizeof(buf));Ovx]O5N
            }
H{:q6_ \0bl&|?             opr_in.ch=c;*Vj'Lv0w[n7E%`$G6o
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/CA0I(n5MYZ"C:jn!R
            {
ze F3{` Y_:\G                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Z _c `*tF6k&~u }!o4Zi                      Push(optr,opr_in);
z"r Y4L/bc                      printf("optr入栈:[%c]\n",opr_in.ch);U4H]yfxD
                     c=getchar();
sRd m2?*H1^qP:V                      break;
oA&o5`5jR5g                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
h\B;Px:@:K?                      Pop(optr,e);E`*YBI~)e Ld
                     printf("optr出栈:去掉括号\n");;V4^3J K\3Xe#\
                     c=getchar();
b Ff N(V&i2d                      break;
Ek"Z(Fc                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/.~5Bw ^#? NkA
                     Pop(optr,opr_t);
lt$I8e N.M5L0^                      printf("optr出栈:[%c]\n",opr_t.ch);
f#_7@&ap?8|K!pO                      if(Pop(opnd,b)<0)*UW:T_'\.bV-qD'y
                     {
b8SaH I%b                          printf("Bad Input!\n"); \uS(B:Y5T
                         fflush(stdin);'K t X Y H^E)h
                         return -1;
JK` Lw s-k                      }
HIS+Z v,V h8cz A                      printf("opnd出栈:[%f]\n",b.data);2P*n }-D!Kx7U-B K
                     if(Pop(opnd,a)<0)@#l/P~7fn
                     {
f/U-AlK$Z!k A;Q[B                          printf("Bad Input!\n");.i^C3b;Zg5QY
                         fflush(stdin);#tGo-Il7H
                         return -1;
B9Ul.vbL q*rC(Q U                      }
s9Ju\.g:han z4{-K                      printf("opnd出栈:[%f]\n",a.data);
#E^j#x9f1Q6zO7ZW1q(e                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0w#@&~#]kh4Sq                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
x(C/D#~+A2Y5L#v:B(K                      printf("结果入栈:[%f]\n",opn_tmp.data);
bw!d wC6Z4ZU0|                      break;OaHd9GFk.{
            }
n9f[,e FxDe         }
%Qe?gN,B'w$v'V,C         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                `chX6b
    } J$q.w V9B
    GetTop(opnd,opn_tmp);aZRx O'AZ
    DestroyStack(optr);
'a6\"M z,^M     DestroyStack(opnd);1m"?pm\8}Bj)t3Q*@
    return opn_tmp.data;
R D^ z&? E{&D }
V} {`M
Q]e:Wd;W-p"^ char *killzero(char *res,float result)
Nb3g8yp.E?)m {
3i%y.cgHm![     int i;
*LZFWY"q&I#k
.q j8O`-P_$Bz     sprintf(res,"%f",result);
/Iae%t+F@a O)Z     i=(int)strlen(res)-1;6PDts:I5lW^
    while(i&&res[i]=='0')(iw ?o4L7D,?8?^m(Ti
    {
'@,{8mW$K ]tB         res[i]='\0';
p jmHEQ)\*An'u         i--;H@x'v&E!e5|
    }
,c,IrjW+s;{BJm     if(res[i]=='.')
%Q u9F `8C;Y6x bQ         res[i]='\0';
%Db(c3{0` jYB*m     return res;
X$qiA } }
Uk8|!y@[ IySw :MqOk+we X0^5s
int main()DB#YOX`9M;J
{ K p%CRf!~rH
    char ch;
B }yu,}2B.YlE     char res[64];2}9@z~\0h*h
    float result;:Y+t)D;UF&H M
    while(1) C1Fq|0z+XC
    {x.b\;H+V
        result=compute();
ss9Z [&c3n3P[wf6V         printf("\nThe result is:%s\n",killzero(res,result));+OgiyI-\k'b q"? z
        printf("Do you want to continue(y/n)?:") ;`RSC:\
        ch=getch(); n| Bq@P
        putchar(ch);!A#s\2Mo4V3j6Pq8f
        if(ch=='n'||ch=='N')
)U,T2L)Q$p             break;
}0hF.yPf }&k         else
3|(j2]hY+uJ+eW             system("cls");
Wy3i7r&k%i     } JhvX8h1g||#hX
    return 0;4@6lO0i1~u R6K
}[/i][/i][/i][/i][/i][/i]c.tE(x ~~4sawz#@
MWHD_pA?
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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