捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的._ o/Z@P6wm/xX
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=E:|6d$kc\,t&y
/**************表达式计算器************/
_$Q vC)f[IF #include <stdio.h>
GH%U8_lq1y #include <stdlib.h>K0gG7whO `'C Q
#include <string.h>
*B&I:^w0R|3] #include <conio.h>u/q&Tw-x.k1y+? ^R;L
#include <malloc.h>
"[)oqUr j_r:a
;[E7^ H |:g9[^2x #define STACK_SIZE 100
*h+ic+C DU #define APPEND_SIZE 10[)n,^jQ

R*~B5izm struct SNode{S_6Bf;qOB1[zI
    float data; /*存放操作数或者计算结果*/8yf\;p T5G|
    char ch; /*存放运算符*/
@"COTs:PY8NE };!m;YtD#W9H uV
/Q#wAZf8H'[
struct Stack{
6u*Y/]c1LBsP     SNode *top;
e9?.zAba0u     SNode *base;
V5p!~s'l     int size;
:pK/e;\ y RyU0J+O };r^^~4jU\YIc

fX8_+HI /*栈操作函数*/ G7@)~5k*]i)gq x
int InitStack(Stack &S); /*创建栈*/*pp*T.^r4qz
int DestroyStack(Stack &S); /*销毁栈*/-Q4B+F"}9F3S"r
int ClearStack(Stack &S); /*清空栈*/
*Jx#}y-zN#R SI9W int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ed"xNHBZ] {5B
int Push(Stack &S,SNode e); /*将结点e压入栈*/
7\ Jw.OO int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/(@PP#y+N|2L

(F8P?~"_.|Z ^5w%c\ /*表达式计算器相关函数*/!? v!`lU/cH Lmv;F?
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
LE%TS~D rY int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
} \z2@} KT float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8l3yb;a.`+z(reR!_.l float compute(); /*表达式结算器主函数*/
r*d&?&nb"P` char *killzero(float result); /*去掉结果后面的0*/
!K%A WSp]"O &o y d3Y(y'x5A~
int InitStack(Stack &S)Z\5Z#s2S rxv1e9E
{,])b!O1LZd:W
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
B l*f4Z4VI"v1h     if(S.base==NULL)k ^0a u!C\5Yw4[
    {1] d*X'`Q q1["~
        printf("动态分配内存失败!");
)RF0nE|.i         return -1;;E` \H}nq
    }
!v;u2h6f/H     S.top=S.base;
cQ^wZ,_[:M5r     S.size=STACK_SIZE;6N\S`6VsK L:O1H
    return 0;P wI0c}'R
}
v_C^L} +i'd*y3F*~2k3s3LT
int DestroyStack(Stack &S)/lsjDJ-a
{:~t,}7`ciV,K5sw
    free(S.base);U$rEN!S$s;B
    return 0;
~ h0PZd#IQ6@t }
x/M#fK2@\e(|.B3CR%b B%]b!Y%VEUw3^H
int ClearStack(Stack &S)_%K dnG:Uqy
{ S;k TGN2b;w
    S.top=S.base;
M6J3F'Z-B     return 0;B8|/a%wr_?K?
}
S%s0|)gbZ%q8AYe Y7B p1r7t
int GetTop(Stack S,SNode &e)m P'z3RtU,h:U
{
n[+Z5?-\     if(S.top==S.base)
t:b$q&C nram/z#q     {
K x/D.C7? B^e's         printf("栈以为空!");
i*`)?%C6[ f,qp.[G         return -1;
#dg'`tN q&h W     }
8R H#CQjEZ     e=*(S.top-1);E]g+N7P5ilrfe3U
    return 0;
jy;i S/qGdOU }
|%AmWb^9J p/[)Gkkd&K H U
int Push(Stack &S,SNode e)
/uCZ.CV_;]5g {
t1X*M3d5`     if(S.top-S.base>=S.size)
1w8t pNuK/P8rJ/c     {
l|1U9|N"A.x!X Q y         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
o[Z2l'b7c2B y%QL         if(S.base==NULL)
-C!Y%uczJ9_         {g W:yC;c{ PY)U
            printf("动态分配内存失败!");-n2I#c G}{2d$r&f1~ C
            return -1;
XDLM'l8z         }
vU8[$j"y2vg         S.top=S.base+S.size;
-]R brP&A&ke         S.size+=APPEND_SIZE;`&iTb'u*k(M
    }V!o1W%Z(~3o/F}
    *S.top=e;
o?5d h(m     S.top++;I.@ Aq A(gt ]0?se
    return 0;
JnC&H*{E"Y/MrGI }
0j1\? TCq_0DR G F+O[8~6o:|!c8|
int Pop(Stack &S,SNode &e)8\9|5Y/bdh+^m#P
{
Jb ul:\O P ?     if(S.top==S.base)s0r5o2nn~g
    {t b+R-[W;b]
        printf("栈为空!");
\Le"Y E`n c/v         return -1;
,v+U.}"T+M_Aed:z     }
0Z6g/m`2[n L:J     e=*(S.top-1);'CX&T nF5?o+^
    S.top--;
pzl [K9c-yTG0jL:L     return 0;6OV2B*c| c.^;\?
}
$[;n bY-I4up'J4r
p J P"Cv;kJ char get_precede(char s,char c)&X V tGX
{
J!^Hy~ YM     switch(s)kha:Nqh
    {
Q0ih w!@ a*a,j)_b^5JR         case '+':                  \-u8`?#Tap^
        case '-':(mu3K9J,Rh-K;m
             if(c=='+'||c=='-')&`,U ct V/W
                 return '>';#tU!y}&r,^)n'G(O&yW
             else if(c=='*'||c=='/') s8gp4t@#E
                 return '<';|P@3}s
             else if(c=='(')
%Q4BY7n-td.x D                  return '<';e;UV e^1JVV%wc
             else if(c==')')2I2pg HM-m
                 return '>';
+@sFl3JC%L              else
@C1ko9`W                  return '>';,`Kt Ptt5p
        case '*':@%a;yV(_~
        case '/':&ca1J0r7d)A
             if(c=='+'||c=='-')
d`#`x v?@                  return '>';
a!p6}"d7A%G&]!Iq              else if(c=='*'||c=='/')
.l3Zt4W!g#k                  return '>';
S;X6g#AOL)Z              else if(c=='(')F F B!t_-G!R/q8t
                 return '<'; xdg^S7g0p e
             else if(c==')')
+cSM"Kv QyN                  return '>';
F&n&Mb5g Z Q/Re~              else
-]Pf0A#IU                  return '>';.vp+X1l"?7M
        case '(':(B y+b\ Zs#_
             if(c=='+'||c=='-')
7b"d9Rg9A^4Mx7qe!N                  return '<';2xDr!P:^
             else if(c=='*'||c=='/')8I,j8a;w*?w pM
                 return '<';)_.B MPD0F.BKFpb
             else if(c=='(')
@oS(g z-z                  return '<';
1g}s1n&@              else if(c==')')
mI#u!Z|n)X                  return '=';
cJW#V/S4x {              else5Bmf*b{W{ H
                 return 'E';
]$HR7a ZU2P[         case ')':ds0X6QE*Y]l9}
             if(c=='+'||c=='-')
@J.z?ed                  return '>';-Jp9MI0x"}.D'nM`&^
             else if(c=='*'||c=='/')
/V#?VSBe                  return '>';*]tr ol
             else if(c=='(')
D Y)}O U                  return 'E';
Wf;h)bUM Z%Lw?              else if(c==')')
)z,]&J$DMBP _-^F2k9i                  return '>';:ZtH0C"q5jC{
             elsebA-@7EY9^e0s
                 return '>';F/q ~3RG)EfM
        case '#':
F-O&ga pB              if(c=='+'||c=='-')Rm*M o+U$?(jW
                 return '<';
2HnC5I&a5@ ]~kD              else if(c=='*'||c=='/')
^0cV#eD1LG                  return '<';
P j |-Y:P/PEo              else if(c=='(')z2w&t8n%p
                 return '<';5Js-E1~Q
             else if(c==')')
E6s`+fbE*@};[                  return 'E'; oDkC|k(S?\
             elseT3|s `7Q
                 return '=';
t'B*u Fc j         default:
Ye_V?#r              break;+s`Vwst(I
    },n%S.\g%L l
    return 0;   
z#g%g:v;q&H s'e7x }
,j;w/l.i1a4E2\ 3^?LW tF3v{?
int isOpr(char c)R K1n&T"_I3R zKK/R@"m
{3}_.y%M\2rw
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
r k;iy gO7}0X         return 0;G%rhsgu
    else P7wV'F wo;x
        return 1;&x{IHu3l ^%[8c
}1c"@,f1A"X3k%Wq

4P4nz1B/T Wl;d1A float operate(float x, char opr, float y)
d0K \Ya@3l]:E {
T:Rl~*g)]._TY     float result;
Jt&w}agCa ]c     switch (opr)6`yQ+D@*Y e-u$X7T
    {
p[)g*t#@'_As(A-d"R         case '+': 'D_r%sXB
             result = x + y;
p(U];|'ha              break;&LvHB'{ fCj9a
        case '-': !It*CU}1feR
             result = x - y;sUR"l'`#M
             break;u5a q"C4UV'B v`
        case '*':
|/m!t a"WT-{5o`              result = x * y;^Kk+H:W;Yu
             break;;I6O9M;? V'X2o;~[o^o
        case '/': -Uf0T.T6aG`o
             if (y == 0){5L2{:_%Kld
             {QO'eb8g
                printf("Divided by zero!\n");t;EDL%qTA
                return 0;
%_M+eqY:z              }/X2]:xe)J+^W \:s
             else$P^`YY-P:\H}6l&P
             {
1K?v]%t4a                  result = x / y;/D2cr8]b[b
                 break;
h/[N[ a"XUp              }3X$^%ge(D'T$q"}
       default: F As,u z N!RX,O"X B
             printf("Bad Input.\n"); S:eE5K}}
             return 0;
6L$d h$bZK     }
'Mr S+Bjafr     return result;
y5Y?Yag }   
#OS q\5w-r^T Q $Huv"\iL
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9uE\Xkb,}E0K"{/g
{
D\0Out     Stack optr,opnd;|X9| zj3NT.e k0a
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
"b-T? Xv;C0CVR     char c;0M'K]~!s.F"c
    char buf[16];'cX~P"q&b3pR
    int i=0;
0{?!c rMJW"FQ    
1w3N k!h6M4L     InitStack(optr); /*用于寄存运算符*/
'l tt@ s MF.})LW     InitStack(opnd); /*用于寄存操作数和计算结果*/'z![(kH#k pp DPc/e
    memset(buf,0,sizeof(buf));AdT}a/Q*o
   
-xVthIL ]Q     printf("Enter your expression:");+dGN4Bp\^
        
4?gY3M x&[s3M%nK     opr_in.ch='#';0gy @*XWfIG
    Push(optr,opr_in); /*'#'入栈*/
B*pXk t     GetTop(optr,opr_top);
6p7{*pksQ4w     c=getchar();
*\'URt0?#[-J4V     while(c!='='||opr_top.ch!='#')
;[MnTQZo:A3nT$L     {`E$CR0Z$Q/Mkh*UA
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/t@7\V2N\
        {
I q6XI,a             buf[i]=c;
R^F(cq1ax%R0h             i++;
)tv9XyY`+qz"f%?[J             c=getchar();
*?n;O5a'a ?F         }
9\9| n#_U1{]RDI0m"J         else /*是运算符*/f(Fx!FCz1Tfv
        {V[;M}p
            buf[i]='\0';
^(^YW N             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+}X$Ja7L
            {
nrUp0~4\MP'XH                  opn_in.data=(float)atof(buf);1TogN%f(j;J
                 Push(opnd,opn_in);
2`H Y2je                  printf("opnd入栈:[%f]\n",opn_in.data);M+EY#cT-Y.P m4l
                 i=0;
+U(k[$u1g                  memset(buf,0,sizeof(buf));
G!Tix5o*m2`             }
"w0c r R             opr_in.ch=c;v%FOGkL/y
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9y x q@.m9l1v:D'xL
            {
z8F Y,}c!w;O                 case '<': /*优先级小于栈顶结点,则运算符入栈*/$zG R3E;P8VQr-p h
                     Push(optr,opr_in);K?4U$J7C2?:Oc\
                     printf("optr入栈:[%c]\n",opr_in.ch);
!e ],s_6g~]!y0W                      c=getchar();x8V|\Y0C
                     break; hp&E6Y$Z
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/n3p9H7LZ'W.sU3?;X
                     Pop(optr,e);
b qY(z}5^+K [7m0e)Q                      printf("optr出栈:去掉括号\n");(X6A(J+P8N
                     c=getchar(); V9ee)l7fu
                     break;!xr+WCK7iq6u"pY!P
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
Cxs I%A"~9dO%xn                      Pop(optr,opr_t);6u+XUlQ QCw6_
                     printf("optr出栈:[%c]\n",opr_t.ch);
\,P#O8x u ]:W t0IT                      if(Pop(opnd,b)<0)
j&K{7l$n m                      {
'K^ l\.@J&^:OKC*i                          printf("Bad Input!\n");#_B$b+Rzr
                         fflush(stdin);3W.UM+~)X
                         return -1;-Y2VYe4B%bl
                     }
6\BhT+H?`                      printf("opnd出栈:[%f]\n",b.data);(yL:B,~:mW
                     if(Pop(opnd,a)<0)
)`Ff1[$B9g_DM                      {\,G]%D0z
                         printf("Bad Input!\n");
;w DKk(g:E                          fflush(stdin);'kNh!bL\
                         return -1;
o:D+f8}y                      }KqQSQ;r
                     printf("opnd出栈:[%f]\n",a.data);w C K'Y-|4DXK/h@
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/H9~l$H.e3Y/L&nt8h
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
3L$R5P/x f                      printf("结果入栈:[%f]\n",opn_tmp.data);
8\h[4]#I)?                      break;
'P4][r@\             } m]3V%`3^v&\
        }
#R7pn#m#A%_]         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                8IFUgD`
    }
fFTRL)r)VL     GetTop(opnd,opn_tmp);
)V1S%b.T*L+n _+R     DestroyStack(optr);
[4G)XZ#c gi*]7g     DestroyStack(opnd);
)k#S w,NNP}2co V     return opn_tmp.data;JuNJ8UP:iGWT
}1I;{QBl ~'W^
#e)U;u#Tl#DC/^L1K
char *killzero(char *res,float result)
Mlm9P;}%Aj+eC)f {
Df+k.K9BvQX     int i;R*r/f)CoJ FW

yz0F!S%ce     sprintf(res,"%f",result);
$A%E6hS"J0R f     i=(int)strlen(res)-1;
_Lv9[9o S,^2j!]\(M     while(i&&res[i]=='0')
X-LTs.xLM(G     {
2esj;C"[8E         res[i]='\0';
7]o+Bm n Fw&\         i--;|p(w~w@U/L
    }
O#f`)V.^$HH8S c_     if(res[i]=='.')[Cc"n3B,d
        res[i]='\0';XQ:F%fE#kT N G-Q.l
    return res;u2m0{+M bd%Cw6d:Q e
}
{7u4j^uv*g #q+Xbm#y1~p
int main()
.x@T%Af {
T9s v*g.j mU[     char ch;f5ak)mxj?z?E
    char res[64]; W/V,RGe `)E@OIZV2TCx
    float result;]S}ObX$yS
    while(1)
4H#if}7W Y)g     {?n ^&X4lL\
        result=compute();*P_*H1|i#wG5B*M.O
        printf("\nThe result is:%s\n",killzero(res,result));
W0y-hv8f7dy         printf("Do you want to continue(y/n)?:") ;
_0LA&r6i{B!g         ch=getch();8x S,xM1yj;aco
        putchar(ch);
o;F$}1o;L6k6@4j         if(ch=='n'||ch=='N')
}p&JSU;I             break;8G ['S C5Da`:nEM
        else(o\_RA4} oK x(?
            system("cls");
:F!k8u"M;e^M `     }
5RS6oV$E/F+_ WyuR     return 0;
0tQ/XpX P$f L }[/i][/i][/i][/i][/i][/i]
,o6{3Icg CH#[&V g_U`r
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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