捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
P(d5[!o/l7^ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6P.R Y9P"m~ r$Z|W
/**************表达式计算器************/
TfTN;}5Xq #include <stdio.h>
/Xqg4z&[$BxG*\"f#I #include <stdlib.h>
1[^ jX7I2|Cf #include <string.h>5AW&h*Z-y9}I
#include <conio.h>-A4KO4C"c2HS _]`"O
#include <malloc.h>
s h7NtuNG
;@q@G3~]n #define STACK_SIZE 100
C4\-g"W3u0~ #define APPEND_SIZE 10
!Kny1We#KF 'moW/WgdU"m/~
struct SNode{$grRfMHSz"KG
    float data; /*存放操作数或者计算结果*/
ESpzb5D D%k _     char ch; /*存放运算符*/
L0CZozW4O4n };XZ7SW[
1f"d%~r8@-uJ
struct Stack{2\]O!UB8Q0`,ve\
    SNode *top;4gF7wFv`
    SNode *base;
T i9H6I z     int size;
4Ry5x{Z_z };
t8iYHJk(i{
@#_$?s9^ /*栈操作函数*/9z-o#v;yH
int InitStack(Stack &S); /*创建栈*/'G'H1z,k0U yL[
int DestroyStack(Stack &S); /*销毁栈*/],qL)q#l&s o.K%rY
int ClearStack(Stack &S); /*清空栈*/YPy1f[{z$@:q8w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
br|i9qdx int Push(Stack &S,SNode e); /*将结点e压入栈*/
UbL:n3a int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ b*]7q8n:A5R4K!d\|
F@9p2{WWz4r
/*表达式计算器相关函数*/
qw@[n char get_precede(char s,char c); /*判断运算符s和c的优先级*/
:TQ A3U? int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/iu0|/|m0@v
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
"g6QW:~;H J&J-kKCg float compute(); /*表达式结算器主函数*/
A${ \T f$i char *killzero(float result); /*去掉结果后面的0*/
5D"s U Zu r9bD_7|3vJ
int InitStack(Stack &S) Uy~8o%P:l;a
{
ZP8c@7Mh     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0gp#^ k]
    if(S.base==NULL)
)[4Uu Ph+F     {
X3X$@7ds s!U,c-S[         printf("动态分配内存失败!");
7b*mQ~!^uW(FQDb         return -1;
5\7o-m:dvi!VsmB     }
p9nO)c g\x6rI     S.top=S.base;4Y I&t}N!lp0G8`q
    S.size=STACK_SIZE;
H9L3R&X O-H5q-@`R%`     return 0;
H9qjC(z%X }
r7j0[P$DI
*`)pyS2}sB int DestroyStack(Stack &S)Y(I S`(Z-f)i\[
{BpIQyy4Jt
    free(S.base);/Z9TJ:n [{
    return 0;["d:W.dc+G;{r
};f;uO$M/q.f n|uY
1H[SB6N/z
int ClearStack(Stack &S)
[}?V T1o0o {.\"LL8jn
    S.top=S.base;
4viy0q6rU T v     return 0;g8o!M2D jk
}
6O3h*J&s,e X'SG.ac&rE8g
int GetTop(Stack S,SNode &e):B.W-u'~p/Q6W:Ln
{'F+R v!^]wm
    if(S.top==S.base)
eR1W^H H-G     {
%a m9M"z-Py} K_XC         printf("栈以为空!");
(Y2[&}']*U B8L         return -1;m)g`k:c$sG%g
    }
K`m4Ao7P7^     e=*(S.top-1);
:k(e5MFUI8V/_'O     return 0;]5V z;tq8@ \
}
+YoD1O3Kj0{ 2f&iauT0LA%[v]#j
int Push(Stack &S,SNode e)
ax!T2_0}(~m3ty {8zX{5qUY
    if(S.top-S.base>=S.size) n#aI c:d8}'k
    {5p0~,C/dg
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));b i4L5\o3A lv
        if(S.base==NULL)
'f6mex&I;J4d;{i         {YzHy3y3W
            printf("动态分配内存失败!");
kb9XH@             return -1;
Z8D%zTz9UH1P s(M         }oq wrQ ~"bD
        S.top=S.base+S.size;;t-s[a7qlL1v-n:s
        S.size+=APPEND_SIZE;Y,v+A6j9x L$l
    }
2K;@MBU1I     *S.top=e;2_%bo?-v0vKY
    S.top++;M$rB&^Px3j:C+h
    return 0;
w lk(~8E*^|!E_ }
7X;j]"^E7f
-umUt|7Y!~ int Pop(Stack &S,SNode &e)
#J?0mEU R0j"q {
I$Q9[hf     if(S.top==S.base)
)M({.K/]I-a     { ^ dRL"X N
        printf("栈为空!");
.k2pV`&o NoK         return -1; vx Q fz:G
    }6Fov~r C)R` Y
    e=*(S.top-1);
c sFX#i     S.top--;
^/Nc'Lv7mz     return 0;:u%l y)hc"LX3M:QV
},ZAR$c]:k_(`:T

:piX3u/[E)TbJ char get_precede(char s,char c)
hw6j7V,e}V:q!MN {
,{5Lw9vx0YK#bG     switch(s)
\VK}kb'IQ"~     {/K~f"_U&qd;`2v
        case '+':                 /\ CK+m8HS
        case '-':7a^rl u5XAP
             if(c=='+'||c=='-')
CBk&Q+^"gWW:eF*rA                  return '>';
$C1dK!{@UH8A              else if(c=='*'||c=='/')
L Si5HvY#C2W,H                  return '<';
4A(u Dmw7D#V              else if(c=='(')
(g,}9Tf0h xT Ne;TT$h J                  return '<';
2_!qUh-htcV              else if(c==')')
ctI3od                  return '>';
I{"bT(Zck              else
zY4fw$y                  return '>';aiO2}$o3P%J
        case '*':
i5O(BA3Z4{         case '/':`6m&h @RxT`"A
             if(c=='+'||c=='-')7Ya |dy6O)Ke|4x
                 return '>';? S?~Gw
             else if(c=='*'||c=='/')
{B,D-F6r MF!} X                  return '>';&^tDP,B8t
             else if(c=='(')
]S A!_F~                  return '<';
!G,S/{5L]:K5}0t              else if(c==')')
,T Q^M/c pq                  return '>';
udUA e^m              elseQ t ~{U0cm_?As
                 return '>';V'@k)t ~e.ptm
        case '(':
^v)v0n0b-m3Q              if(c=='+'||c=='-')RSV}E `!?h
                 return '<';kJ^(s O}f(Z
             else if(c=='*'||c=='/')z1A_l-b3FC@w
                 return '<';
O)l9n F.e              else if(c=='(')
1v:^3R,iE)c;]yF+G                  return '<';
,D[ ?Ml              else if(c==')')
4b(Yn*^N*@                  return '=';
t+T0BK QJ              elseC;f*vQb.pZ
                 return 'E';
'I:J-I-Bz;_[         case ')':
!n:p1ZN AeIp5hE              if(c=='+'||c=='-'),L"A$J'gGO$r
                 return '>';L\f~/xvJ8~3h1D
             else if(c=='*'||c=='/')
n x!u`9d ux5rh,@&y                  return '>';X:S@$O*W?AHVL
             else if(c=='(')l0T%I`O'@
                 return 'E';tk;DZ#OD
             else if(c==')'))x$P{A&I
                 return '>'; X w3w.\`3f)S
             else
jU;K3X8L9k6qU(S;D+F                  return '>';
._7x"}2Y/}4k7x3t         case '#':
x{]*Ic0UEr.q#LR3F              if(c=='+'||c=='-')
HbBlE/f$Na                  return '<';
:ddL ex-u2]J              else if(c=='*'||c=='/')K LZ KR"}
                 return '<'; W%|7O,J!_'a.A
             else if(c=='(')
rb)j)Z+RkM _(a-G                  return '<';1J(@dAb%Cv,Ux.S]%GV$Q
             else if(c==')')sa;x`v
                 return 'E';RU0~O)b;`
             else
*O&E;Y[9`X&d-PEV8X                  return '=';
0V0?)jQ/`g\ }         default:
7d_)|0v aj4j              break;G!F^1h0H HPo
    }
%P9@Lv$Jk/?QJ~     return 0;   
C_rz{mW.x%c} }*w:B Q5w{)S
z['S(CJ U.Q#X
int isOpr(char c)
n GBoagnO {
U0L z%ql+A     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
\BNvHgB}C9G         return 0;
aC o4r{Mi_c     else #f2tt-O H7Y S
        return 1;
v-Z Tpw;d D NZQ:kh(K }
)^V\XvT f*U7i Q
O b#P^bA float operate(float x, char opr, float y)Bv0mvc-K"vj(Iu
{
UT)jSCh V4|     float result;BcNO lFa
    switch (opr) k%\4V!DP*F6| [[
    {
%wpP|l;WZ         case '+': T*C?p)Q#Fwz"X
             result = x + y;oa tKv!Dj/b i
             break;x{%}3I0V*H1Y
        case '-':
7x/N{Ou$t              result = x - y;
:?b1xr.La [              break;
s7p(Usn:f         case '*':
6VY4{9j:e/Q?5y              result = x * y;6E$m%F3Lg
             break;!`)rd8B-Il
        case '/':
;E;_n$x'|              if (y == 0)-wJa5Q `/}
             {K ulO4d'a~
                printf("Divided by zero!\n");c%e(u8LX8n.T C
                return 0;(hh k']d)y1u+S
             }\/Als#tf.a(i
             else_n)x$e%_8\l0e
             {fN Fdhh"B*w
                 result = x / y;;g,u"n1vk
                 break;2?x}@x0v
             }T]z1p&M
       default:
pnV;sj              printf("Bad Input.\n"); #Hfjl/d)D'i
             return 0;%QQ3Ny_ FK&D
    }7j%@z#jZ0i5P9_ v sL
    return result;L1_s9WU~
}   
E T)@t-WUi,I 4wi'I F?A mvZ
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
;xeU ftY%@ {,q-qdp g$_x$JH
    Stack optr,opnd;
:uv CHhzB.\_&KD     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2ma$Ll7|h~3n
    char c;
F N Wy+{7z     char buf[16];9r2E*o0z mr Bc}
    int i=0;
e$a(H"Rj     wy\+PQrq.d6U
    InitStack(optr); /*用于寄存运算符*/
z7C0dm%F*m5kM8A     InitStack(opnd); /*用于寄存操作数和计算结果*/
I1C^)B;N)l'v&z;Iqb     memset(buf,0,sizeof(buf));
J F^7m[SJ"j     `3Kk"Y)T5J
    printf("Enter your expression:");'_?G.A*F'D
        t+w4zG&i`l1O$G?
    opr_in.ch='#';
?{%W0p8Wf@     Push(optr,opr_in); /*'#'入栈*/1u!YMi:c1I N V-v:]
    GetTop(optr,opr_top);
"Krs~|` i     c=getchar();r*u#C4A'y n
    while(c!='='||opr_top.ch!='#')kD/j%b&a ]h
    {
/e Qc:\v"Q         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
O@@G;|         {` l5\iT
            buf[i]=c;
mW8M%h,R;X             i++;c/e_M!o;B$|c
            c=getchar();
-c l O*_[^         }
r:o S}/T         else /*是运算符*/7\mH.Y!L5JK
        {(m {(|&|)Ze-lyh
            buf[i]='\0';6t i0~E*@
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4Z G/et&_'O*b+M
            {
!}^"z ^8ty OC                  opn_in.data=(float)atof(buf);I QSxW8kv
                 Push(opnd,opn_in);
\m(o3e$e4P1t!h                  printf("opnd入栈:[%f]\n",opn_in.data);%qr/[$n^ {9^,@ W8w
                 i=0;
"NF)es8Ns                  memset(buf,0,sizeof(buf));
^C+~)Lw$MJ Y'nX             })VE^;[1GFG{
            opr_in.ch=c;
&j H#v4A a             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Y,N6Npz1m?%M#Zf|
            {
qP$]'_nW_1l,Sao                 case '<': /*优先级小于栈顶结点,则运算符入栈*/9k,O1X]+y-}
                     Push(optr,opr_in);2UE)W `8z$]?Z
                     printf("optr入栈:[%c]\n",opr_in.ch);
9n&O(s.Ci                      c=getchar();
]uS6I:H&h3gV \                      break;
5@O:jug'lW                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/h-Y8WCIg/S}c
                     Pop(optr,e);G,^Y|Etc OV(u3^
                     printf("optr出栈:去掉括号\n");"f(ceLm l/T{
                     c=getchar();
'u:Zz mO7a                      break;*U)s0X/qgzH
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8n;| u5WV!p$i:w                      Pop(optr,opr_t); C.^_wl&j
                     printf("optr出栈:[%c]\n",opr_t.ch);#I;v v$d.e {m"jI
                     if(Pop(opnd,b)<0)*RQ(ll#y9xemO
                     {
qCe J#ng[9I                          printf("Bad Input!\n");
m~-y0bA                          fflush(stdin);
&l2@_'Eh9W@-aHX                          return -1;1x7M.Ur]&M#a(EZS
                     }b+z L T'dMk.nCZ}
                     printf("opnd出栈:[%f]\n",b.data);
w2z!prC)B8Mc L                      if(Pop(opnd,a)<0)
~6p i5J._@Cd@                      {S'z-R+a;UY
                         printf("Bad Input!\n");
zvrC-w)SF                          fflush(stdin);W5O9D4z,n CxWvu
                         return -1;
e,Nob,_ r                      }
S,TlK7G*m:X                      printf("opnd出栈:[%f]\n",a.data);|5Dj,Qmt"b i.J+k
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Uc,c4og3Q                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/&{i3H l[8buL
                     printf("结果入栈:[%f]\n",opn_tmp.data);
oq$e-FJR                      break;:]4z C5Z[k5S7{:mjU'D
            }
4h'j;D)FM+N D0t2ss         }
9MRsO)A7Ynd Q'Y         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                iK4_Vw5S
    }v;@-s,G@
    GetTop(opnd,opn_tmp);k2rnbl0r5}5w9` iG
    DestroyStack(optr);
cPR1mM%w,E2t     DestroyStack(opnd);
-V/SA%vsH&[${     return opn_tmp.data;
7N*? Ycn5]!S`;e4~ }:_D\'Dz%nk4b
:L4i;l7k YHi
char *killzero(char *res,float result)
3SP"S;_J#@e {5Ru0\8[5G,@^6D*uA^/S
    int i;(n+\v3H6e
a#b T7R@j t2N+\
    sprintf(res,"%f",result);
U:x&S7Vp$J2d/AK     i=(int)strlen(res)-1;%d6VX/c~t[
    while(i&&res[i]=='0')
zu6hZ,g     {
.lS(D(}R l)xu!c         res[i]='\0';
C%l;|T/Q E-?fP:Vd         i--;Q+y9tL M
    }
Z,`(oI'{rgo"d[     if(res[i]=='.')
;S-w!K#~3](UsQg ^.s         res[i]='\0';
+F"_-Zl&\m4q7H     return res;
#E \"Q9o2f;A3o }
|8XU_| UT !XiE0D|@i}rZ
int main()
~t i,tE'b,[ {pqIC%g'];Q
    char ch;kgjLj8s
    char res[64];
M Q^i3{b~g     float result; sJ a(o?#{(J;ng
    while(1)dm D4W|&]
    {
_1n1gT u,LH         result=compute();
Y/s ~3r c'[ j         printf("\nThe result is:%s\n",killzero(res,result));"Pxl#r?6n.]-K
        printf("Do you want to continue(y/n)?:") ;
&]gajwUk         ch=getch();
C2R_;F['r3kV         putchar(ch);K@ Qo+R5Q^
        if(ch=='n'||ch=='N')a6U8tv]"E(P
            break;KD}Uwg
        else9J$N9Wj3zT$P
            system("cls");
f3ng9a%T y5n1fc3E     }
na ~!tkl     return 0;
.[nI#kK'Y G }[/i][/i][/i][/i][/i][/i]e!G2S`*Gkyd I O

W RQb`L^0W P [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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