捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.)N5VC^5SN#cV%b)C
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
`kHVt Y /**************表达式计算器************/[4B J,jkg}2O2D
#include <stdio.h>&lW1Et0ol YPm
#include <stdlib.h>{+JR:m#q2L$Mv8\6a
#include <string.h>
/[z'|LI'S$` #include <conio.h>(C%m ?t R ]W
#include <malloc.h>
c&~t)bM1Rz q:F Dj5KD"H
#define STACK_SIZE 100ab kdLl2r
#define APPEND_SIZE 10Q {V:gT SA:h8P-`

^F/b)V ?&c struct SNode{Lv!A g-r L0~|)`r{
    float data; /*存放操作数或者计算结果*/;b(Qjvj o.n b
    char ch; /*存放运算符*/;fGZ"wb
}; d;FW"\ g7W,|0Zr"\
GR0c9RC*OSy
struct Stack{A!aq\1fF|
    SNode *top;
x?6ji5Ii:E     SNode *base;H5sFHa}I
    int size;aUc(J5sT
};)e h Z:h6C(e4V FeH

4s.RW:\$w /*栈操作函数*/Fij*tV
int InitStack(Stack &S); /*创建栈*/fV1do0R"|g
int DestroyStack(Stack &S); /*销毁栈*/
$xb*v'X$O*B |D` int ClearStack(Stack &S); /*清空栈*/+Hk7w'z2O h2Du!_,P
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
l m7p&m9d t:} int Push(Stack &S,SNode e); /*将结点e压入栈*/-i;[ E/`,Ti G
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
%A%A(d0ok,`7wP(M)h
!eK:T8T4xrcmN-S /*表达式计算器相关函数*/H#toqt)a
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
0t_Z g.d8?HR U N.G int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/&s&B+z2D,`&t
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/nG!q;ZT
float compute(); /*表达式结算器主函数*/)o(^y!hmy
char *killzero(float result); /*去掉结果后面的0*/
Z_(H#I$[2S _
T~;zw uE.o9s int InitStack(Stack &S)
7s d,`i8M?'R;B {HAm7ef
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); fYlar9\
    if(S.base==NULL)
(E9`Az;D$I     {|l:k8W6`C
        printf("动态分配内存失败!");I5s}y+zx T qX
        return -1;
mC$\j j)Y8~m     }5N,Z-S1fK8d fG
    S.top=S.base;
]#t~ q$R     S.size=STACK_SIZE;~#~h2])s*zOp
    return 0;k"G'S-\XM
}2E3fl,U`L(nT(yp,Q
J([c/Te(I
int DestroyStack(Stack &S)
9U(y|m5^d*O {
ARvgW1qV     free(S.base);
S^(m ` s     return 0;*fOB`.@1Wi?y
}R5{rw J

+DNa!T[ n int ClearStack(Stack &S)"`*SNX$E:T
{C M@D c!O-C
    S.top=S.base;"s']:C/`$[ TR3Qw5y
    return 0;&?0OMu`
}
8V(y8bD `z4U ?8v1L'F:i%B!E
int GetTop(Stack S,SNode &e)
N7Z ehS5R {
i#eC Ui     if(S.top==S.base)P-Jf"r6m#u*F]
    {:Si$v8@t8iq'l-a-R
        printf("栈以为空!"); g;c!s2{)u \
        return -1;t\P!eBfyVk
    }
9AyC;~?'Ls r     e=*(S.top-1);
8pd3uZ DUN'UuH     return 0;
_net!wOr-HM#A }u(^N;_vH
HF{V8f m3_N
int Push(Stack &S,SNode e)
#?6C+t8G2E2e(A~~a {Z P?9hm-_]`'o
    if(S.top-S.base>=S.size)
#l3mm4YO2`M4d"gk,Q     {)AveFyb
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));"w1D~-x!vk_OAj K
        if(S.base==NULL)
&To2orEn;p         {
/aM0j$W!II@6YG             printf("动态分配内存失败!");6mv]B rm
            return -1;6G8{"F6rY}"Q#w
        }
0r J])r1y ItM         S.top=S.base+S.size;? {:K_i6v$b)v
        S.size+=APPEND_SIZE;Ng G!Y'B u'?d*l
    }%ynH%Tx
    *S.top=e;
Qmci Yu/U4t6k     S.top++;G5iIK.v(z0`8c:fR
    return 0;
S)gbe7E;fV.]!q p C }
W}%F2T }
#]| e*i0^ ?4t int Pop(Stack &S,SNode &e)
.d0VH}^KY {
q*p6v&xrTUyX     if(S.top==S.base)){A(V3Z#Z``
    {
Q R}Sj"j%nX         printf("栈为空!");
Z3tj&gq8u(_%S         return -1;
3M[ y#e7@ zI     }"Lo:E)`Fhc
    e=*(S.top-1); I4F K:\m,p8We:^
    S.top--;
%k!| {I9I|%O     return 0;T^)D;P7w9rE
}OFm%@'T&m/z
FJX,F9].h
char get_precede(char s,char c)?t2ck{e!Z
{*Z q7z.ae @dO${f
    switch(s)
$LRV{s3u/LVd     {
R!MhE\t:L9_mI         case '+':                 1l(O e GVRYAS
        case '-': EUSHL$dCg] F
             if(c=='+'||c=='-')
~%BA+Dk7K\"F |                  return '>';
5dnZlr+s\(g A7_.c-`#k              else if(c=='*'||c=='/')Z;G4f:_\;eu/Z
                 return '<';fs-Cw zP
             else if(c=='(')6`:s9^%y C3L(])g
                 return '<';
9|D6NG;nA              else if(c==')')
5u`T*\sy                  return '>';[!mh-y9T%AR&Z
             else r0rQ%Xf,o6@4n
                 return '>';?2d e!c q'OY,_
        case '*':
:p*qjD!`2[;z         case '/':
G&kDFh$T,H `$W              if(c=='+'||c=='-')1l)sO {,}E!S_z)l
                 return '>';
DlIIMj@^              else if(c=='*'||c=='/')
4Nc3yiih                  return '>';
5HW3T_|"C bS              else if(c=='(')
r3Sg,vk[1F.wHK                  return '<';[E+Sv;`S
             else if(c==')')1Km,hD2L9p?]
                 return '>';6y;aR+mg.L*A2C
             else)g&`[,B0S!fT ?k
                 return '>';
3G7y#y(?!DTB\(z9M         case '(':2j4VH/j9T'y
             if(c=='+'||c=='-'),GTtnOi3vU%Y1S
                 return '<';w/g%s"d-R#r1w
             else if(c=='*'||c=='/')
C,vi#xld6A|                  return '<';7C{-J RU| y9S
             else if(c=='(')
#t)@7B`xW.J6c W |                  return '<';rou ? N
             else if(c==')')Tsy"\3O
                 return '=';
mA"B?u#N:bK)L"Yt              else
K0~5A aPe1Z1b                  return 'E';
I%W{z E3R9P0Z         case ')':
5GsoR5s              if(c=='+'||c=='-')
8W1q;B!Db&aE3k                  return '>';
UY)it-n[0o B              else if(c=='*'||c=='/')*sk`N;iI@p
                 return '>';
4N:X;O/`.R              else if(c=='(')9x0lAI'R!_5n(W
                 return 'E';p,CV8X$qs*H4B
             else if(c==')')
/CG B]{2n uY                  return '>';
Zx`P'i5ry;a s              else
qb9\$aXh:NoJ                  return '>';_v5EY~*L
        case '#':
#f5XH@{2J              if(c=='+'||c=='-')
xLj5lq)m                  return '<';
A/O E5Qd!oKeN              else if(c=='*'||c=='/')&SS6x&ee V-w)m b
                 return '<';
E sVM-Yid              else if(c=='(')
4T vT8p$c                  return '<';-m.mV+f3e ySr
             else if(c==')') y}x4J9PGm)E9x'YR
                 return 'E';/}n~-~'M?Q+o
             else
a*et{y6L                  return '=';X Os,f;q@@ ^
        default:
:\jf,B7z ia-wb              break;
X1X&{/R3{     }A,D&~$F^T!P
    return 0;    8H^e] `t6H'}5Ka
}
(W1p8k&oE -]/cHT`1c(E3r;SZx
int isOpr(char c) z+uJN(eU
{
#p,L'VY7_ S     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='),cJW;~3T(L
        return 0;
K%tyLq     else
/pg.BZ&|fu MqZ6n         return 1;
}o]'mF }
wC0Z T,m|b/r+m
;d#di@'M"gtX M float operate(float x, char opr, float y)
Nl qNt5Ay1v$]r {
A6PFE:V\@M1zC     float result;
a(ULi;V/@l"E}     switch (opr)
%ZE^ik1y     {
!F6^ |AEs a?v         case '+':
1EM-H1Ea f:CK/W              result = x + y;8D'i\)x2M4q$B
             break;W0F*\.c)PK m
        case '-':
`0b#? t,k-~,f              result = x - y;z%]m4A Dr
             break;
|#TD-Q7F"s         case '*': 8G9HOL.bp:qd.^
             result = x * y;
XqyrC+[r              break;0uP(G/egW
        case '/': F{"U| `*rE#@)ds
             if (y == 0)*D&@3B(DwX+F2G
             {
YiE+x$T#sh                 printf("Divided by zero!\n");zu Ki7R
                return 0;i"z$F0SS/h
             }
+INp7R1l              else
p)`L%tWhQ              {I3La|BR
                 result = x / y;
+HfP uQhD                  break;d6@ nD,@/K` B
             }
gp(o^6X8PV8}([        default: l7?x {O"f_w
             printf("Bad Input.\n");
j+R'D VR^              return 0;
o&a MzfAnS.Hw     }4fk|I!\%R
    return result;
B,^g^Sg)e }    Qj7@kz-nHs6k

,Da?.JJ[)z[L float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/vn6S,sd9{ ~ h$Ss
{Vr I\JJa
    Stack optr,opnd;E2i&LXp T z
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;V%aN!c.\I}2U*nPf
    char c;)vQM&C.y&J
    char buf[16];3g6c} K!P3pk$kI
    int i=0;Hv3si l/h'@
    X.|sWO"y-a:D
    InitStack(optr); /*用于寄存运算符*/
|]2^a4m1iQrn     InitStack(opnd); /*用于寄存操作数和计算结果*/
;}2J-G{8z6ojpG7J     memset(buf,0,sizeof(buf));F7qE%|9q0N%cV)q?
   
-@@zG#K&Bwd~fD     printf("Enter your expression:");^yv{+If ? sG
        
{K2W`4g$d:k     opr_in.ch='#';-m{jZD M
    Push(optr,opr_in); /*'#'入栈*/sit7Ld^,N
    GetTop(optr,opr_top);
M&Q-@\TW     c=getchar();g Dw jMW/QTM P
    while(c!='='||opr_top.ch!='#')+sqQ x1lB"o8U)\
    {0hC\3H'}k^'Y$y:vM,M
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/en{6p"i g:_l:?.D7R
        {0Dx(vZ0nB K.n%F!x[
            buf[i]=c;.~"lYI6ojC0I/v&D'G
            i++;uWgBV Y x7v
            c=getchar(); ~%q%? y4I;[e
        }
6k+?3o0J$D&[;R         else /*是运算符*/
s-GV[ m3v.dy/mcZ         {
1N D,un\]{             buf[i]='\0';
~ S ?6N"j;EKB%R ~             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
!z&Qd9R`             {
*e*Emi-\ m!Z QH                  opn_in.data=(float)atof(buf);3`Ib"Qny,N[QR8v
                 Push(opnd,opn_in);2uxX.qPms `
                 printf("opnd入栈:[%f]\n",opn_in.data);
3?H$Hgzvu$T                  i=0;z?9xOAFFQ\]
                 memset(buf,0,sizeof(buf));#L#q$SHL2i`
            }
(M4ay,e}             opr_in.ch=c; [A-[v ^ {tq
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
)NY,V(L Ta7]a             {tNA!j$D8y!G z
                case '<': /*优先级小于栈顶结点,则运算符入栈*/vgvO?]u[
                     Push(optr,opr_in);7|]:W&R3p
                     printf("optr入栈:[%c]\n",opr_in.ch);
1A [*w(Hk+O!k0v                      c=getchar();
-]2W'w5P+}t                      break;
$A ?%n?Wfx+n                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/|X t^#O
                     Pop(optr,e);G t e:Z)r/}d
                     printf("optr出栈:去掉括号\n");7doH1`:R:Y
                     c=getchar();
S"f9n6q*S v(s:F                      break;%KO EP*v {'N'tV(J
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
e:W9\-ch/Ro;SR                      Pop(optr,opr_t);
+?.gBa*G`3Pu|                      printf("optr出栈:[%c]\n",opr_t.ch);
hU zZ ur1D#J8Q                      if(Pop(opnd,b)<0)
edq#`7d8F&P0?8Aob                      {0D8BiF ^ BH'x
                         printf("Bad Input!\n");
Y9_ m7`J.w*K)X&V                          fflush(stdin);cH R5@jNwU
                         return -1;
a*Ulp/[q                      }
F0f#O$iIz'w6Z                      printf("opnd出栈:[%f]\n",b.data);
~S1M;[.?-Ao ]                      if(Pop(opnd,a)<0)W?e'F*h3I j*^
                     { dR/ohJ(\bN9RN
                         printf("Bad Input!\n");
@}/O.`S |8f IU                          fflush(stdin);
O#_qPk*y                          return -1;
6n4Uu'vr                      }${0PA1CFU},N
                     printf("opnd出栈:[%f]\n",a.data);
4h#~7O {%LY                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
"wwXoW                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/mZj2UZ ]vX
                     printf("结果入栈:[%f]\n",opn_tmp.data);ew wi3{[7I@ ?:N\
                     break;7bG7?*z4p
            }
/Fa7~&[\x)i I         }JT*Dk$[%kadDJF
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                9Sj'TO5? B
    }7A]5Y2m(ZU
    GetTop(opnd,opn_tmp);~$L:y6{ D
    DestroyStack(optr);!`7xyN/W7z8F qP
    DestroyStack(opnd);5_#Jq$G&HL{
    return opn_tmp.data;
u){2z:c!M+NY }4N8L-VfK?5^m

X3^H?x O char *killzero(char *res,float result)
`TiK? s {
0qi+M&p"K{     int i;&F:Y6SXn's!Xr[
[r2t,lGu @T/S0l:`o
    sprintf(res,"%f",result);$Uy[!P2Q+j]1y#B
    i=(int)strlen(res)-1;rcH6PqT
    while(i&&res[i]=='0')M9Z-hAZ$|:x(nn
    {
N7HS(`5X6p)i6}         res[i]='\0';
8{+C%z#@xf         i--;
0RF0Zc"ni#v rX     } }_@ E/dDu6w2?r
    if(res[i]=='.')
yF2Y:T"Yn3zr         res[i]='\0';!K7_ EFIa}b5cG
    return res;{4vS.?n|f/j o+f
}
l w,V*n"]fS
w rG |9Zz;O"mp int main()
Cx3KB6hW {
$_|K{*a1v!LU]Gq     char ch;
9b&qU?8{f6OciLF     char res[64];8?g EORjx
    float result;
;A$kT TUkW9?A     while(1)
K}WR$D$l     {b |/w1sk\(_Gc
        result=compute();
N Dz@8z^ b R*K         printf("\nThe result is:%s\n",killzero(res,result));
0v&L_aRx         printf("Do you want to continue(y/n)?:") ;F ]R9El
        ch=getch();}[rjm w5Cfr
        putchar(ch);^_\g&Y^
        if(ch=='n'||ch=='N')
8L B8F3K&km             break;x B`1h Mc
        else
$T;n Yt{*`8N n2zc             system("cls");
,p-zU[ZdS     }
4P[1H r9Q0N.p&aB     return 0;K{|!C ]u+L
}[/i][/i][/i][/i][/i][/i]
8q2f3CB'_:l[.Qt1I
&|2\vv M*S3i [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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