捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.GV*YqP,@3X.f5Q
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=,H;@#s DI e @v
/**************表达式计算器************/
z c Hh X/@ #include <stdio.h>
F k.l,j+ud0V+X #include <stdlib.h>O%~$AQ&[;W0b
#include <string.h>
-V ^/UID9sT^ #include <conio.h>Q^*v:e~
#include <malloc.h>
iWDL$}BB O e/qRyS(s
#define STACK_SIZE 1000YhB7^U
#define APPEND_SIZE 10qF2{;Q*\#S_X(S
C1~ma2A+T(n^!sp
struct SNode{h W:@z3i*F
    float data; /*存放操作数或者计算结果*/
`+h'vMI5s-E!m     char ch; /*存放运算符*/
7F@k,Lz` };fx;P]c
K Jr.T.D WB
struct Stack{D+b.]w.`HJ
    SNode *top;
;AXI jF5M\k|)t m     SNode *base;
%A Z*Dn[,j&wY     int size;0m;c0Z6^4|]
};
4Y4r&Fshr [%hy"Y"ON0h*},Y
/*栈操作函数*/
a ?2Y"jW!P1xW int InitStack(Stack &S); /*创建栈*/
g2C(dd.u~7[ int DestroyStack(Stack &S); /*销毁栈*/!m|~}I \c0b
int ClearStack(Stack &S); /*清空栈*/
!G#s$Lv3o:X int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ h Cu(r?Wg `
int Push(Stack &S,SNode e); /*将结点e压入栈*/8i1Q@,G i`'a%H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/!\0_k%[:W1E!Bv0e j
O*U wX]0C VK
/*表达式计算器相关函数*/%BN#Sxan
char get_precede(char s,char c); /*判断运算符s和c的优先级*/2oy%m7Q4vjXOObV
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/&dP9AyhI
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/@1u DY S/` float compute(); /*表达式结算器主函数*/
G"lK-?'lO*A(d:x!e char *killzero(float result); /*去掉结果后面的0*/ T}9c ?9wJAv

Br dL2K int InitStack(Stack &S))P[M)H{4_6|
{
5gkf E+xY3{W|6x     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$S0fG5|-{qk1~     if(S.base==NULL)B)N)G'k?
    {
FcFS6k#C         printf("动态分配内存失败!");
@FK1i9zu/|/Xb"\         return -1;
{8|FBeAt'`;r     }
O8|"FBw     S.top=S.base;NrK2F U
    S.size=STACK_SIZE;,m)R,u/uL k
    return 0;
E s K3a"j7t }
;]j"f-fls!X 9oO?^a AG F}?~`7a
int DestroyStack(Stack &S)
3C,p4\ z9QTW8j {
~Bz:\ S0GZ     free(S.base);
)lFqJ8k A5T{ CA&]     return 0;/^ e,FP&X/I"n
}1SSa?6`"Fg

M(_*nK c&Db F int ClearStack(Stack &S)
MO9{9`5D {
_c t3Yb;_9F     S.top=S.base;
+f:wQ6Th7jn     return 0;)e5F!X7n Ue
}G[l$zS3FH p

V#g \2YpJ.Y+L$g4X int GetTop(Stack S,SNode &e)
-}p5F2[p {z`5M0K!y3A4qn9]
    if(S.top==S.base)h? A&t?
    {
z-v1U6@z'g:pwu         printf("栈以为空!"); v!l*h9C(O@$r@
        return -1;(M(T"rgZaH4ly%b5I*wh
    }
C}(t?m     e=*(S.top-1);
7UN%d_ g0J,DrfO     return 0;
K%\$ok bi:DZs })|1^g+b,B

J,Z7e|j:p5[ int Push(Stack &S,SNode e)
7Z.s3i,Q7P? {
cWp6S$\0[%R/~'f2Ya     if(S.top-S.base>=S.size)Hz$Pmb
    {
j:C4MXK9g;XNHEg         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));tQe)RQ Mqd
        if(S.base==NULL)
gm"u%gM.Z\d         {
1g"Q,FY}R9MXg+c             printf("动态分配内存失败!");
e:hJGmU+S             return -1;
t,d/Zj1r%D         }%^/z*G5tc'f K&gZY3A
        S.top=S.base+S.size;
9XZ`Hr         S.size+=APPEND_SIZE;$@o)E+x E j(x
    }qN)C H;uO/Pk
    *S.top=e;
3JR@2r Vf_L     S.top++;
3w6t6Ngd Pr     return 0;+U'Q+g lp @6q;q
}ne v JvH
2g*ca4Tw5]
int Pop(Stack &S,SNode &e)
0Du8_7{sJ@ {AI {m+f,z
    if(S.top==S.base)T-Xk*@!g S%M6H
    {*FdF2XHv@B
        printf("栈为空!");r }-N+r/S"~Sy?_
        return -1;
B[e/a}#w     }
(Q!`'u[v     e=*(S.top-1);
9zj/^A Z1q6t P5M}     S.top--;
*X6A s+T@aZ     return 0;
QXqjp B }s}~3A/h9TMy

r-~$se%[l j f%\ char get_precede(char s,char c)'R,D+n^U s2@nz
{
(d BrQ1J1v I     switch(s)
+o{/\h1PnUF     {
J+u Y+L I]8} H x         case '+':                 
WUo;JD6l H6?t         case '-':
H],?&p#`              if(c=='+'||c=='-')o W!ba'C.X
                 return '>'; rM jr-D&fKxF
             else if(c=='*'||c=='/') ? D7M:G+EQ
                 return '<';-f@3d?`lz
             else if(c=='(')
cA:A7D}C8N^N                  return '<';
9{ ?'DSPi9@'yH2G4z,Q              else if(c==')')
p(P#oBO s){1Q5i!C                  return '>';
S*`B!oO+QrH              else
j~Pf5K                  return '>';'[q[;g1e6h-T3eV
        case '*':
T.E8z^,\y yH         case '/':YN0PX ~7g n
             if(c=='+'||c=='-')6N7O S*e;T"t
                 return '>';!tzA})r6O9dO^
             else if(c=='*'||c=='/')
n`N?Xk;j2O0W                  return '>';&H A ym |6P
             else if(c=='(')
{DBC x:Z3F                  return '<';VNUkF-Dw8w B
             else if(c==')')+zgm$]3[\
                 return '>';
+sM.|7MMm ?*k3x^              else6V&mLGR+D0Q
                 return '>';W[3wZ/qS1CHk!s
        case '(':
`t"WGqa              if(c=='+'||c=='-')p%dc z-} _%J,W{
                 return '<';
2y!C Q~R RA$l              else if(c=='*'||c=='/')#h^)oQHx|
                 return '<';h/s,e$^ [ [ C7\
             else if(c=='(')
|n:i-[h Xm x/R @                  return '<';xE_jMx!W
             else if(c==')')
-^(~9r2|/A|"Xy                  return '=';
i,] v&c r~h B              else.? w\M#f2@*~/[ O
                 return 'E'; ?}'b2GQ(k5s
        case ')':-Nn#IOK
             if(c=='+'||c=='-')4j @|\pQ7w8hrv
                 return '>';\1SN zZ,[
             else if(c=='*'||c=='/')
P Q!P3r:{#y5itP                  return '>';V_-S"Vo%z1Ove
             else if(c=='(')
sG.gT"P#EB9e                  return 'E';
7^%\0}ez2Q.p              else if(c==')')
J$`9v}!YC                  return '>';
+L!@Y{xMN              else
mw/E^6~ANFa                  return '>';)wP9JH(US"T@O
        case '#':4^:QR1CpU;mL5i[
             if(c=='+'||c=='-')
$Fuk'U{.Eke$p                  return '<';
L2q0EF4[[              else if(c=='*'||c=='/')
#E8m"gq _ oj!p:X#p                  return '<';
(KwI j0Wr              else if(c=='(')1@+QU3u:r8Xy
                 return '<';H4WX.E/`k'a:]|
             else if(c==')')
IM%DB,k4]p                  return 'E';Q:Jk9sl8wO0W
             else
e^cFv;q(O                  return '=';9I ],g2zr)t%fR+O b
        default:
G-X {lc^vNC~1s              break;/gG+F,lE6m)u
    }
PB3tSp}0l2y     return 0;   
Fqy3S3JW{7lic }4b8kW$P@ D g:EP
$Q$t!g,Z(@&l
int isOpr(char c)
*NP.H kPws{]1H+S {
T!X%BKx(aW a8d$U     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
h~6@I }-ld         return 0;
.V3aek/IQ-k     else
1Tlh JQ4s         return 1;
c(GH6fJ }
$t.ZG/@t 0Y0uj$[6K
float operate(float x, char opr, float y)
:r#k|2vLrz0i@ { C5Mt`2y Y^]]
    float result; wv1Q h9PXY z|.E
    switch (opr)
F@F K%BKA'e k)Z     {8W2s-k ]2rB6}h
        case '+':
0ukx)f`d6Y5@ ~-g2RIu              result = x + y;
(L*h+b'RP,W!E              break;O'V5O8IU-T9r#x
        case '-':
5J/U,T+p2J6z f.ce              result = x - y; KPK)G:v PI-_X
             break;4Zb1[ kw I^0jC8ZR
        case '*': p(`Us&E8xx1}
             result = x * y;
%PJ3|sSH              break;
h0`O8a?d,c(iL         case '/':
ryFS1~`)C7_y&Q)L              if (y == 0)
[#l3R^9j0]@Y              {
"`6h%o$|A(uz0`#pC                 printf("Divided by zero!\n");h C7}Mb k;l
                return 0;"[)[!HQQ2o0U1E-D
             }
5c a _&q#[jO              else
s3Ej5Kb              {
q#A2nW#w;R9~3i?                  result = x / y;
z)`wQX nI:t                  break;$KP.F/N2q8yZ
             }_&}tFhB\u
       default: s'ND-H0cVD+{M
             printf("Bad Input.\n");
5f8|$l s"I              return 0;1iB+xPNv
    }
apj&U l&s'z+_3g     return result;-~p(j Zy%L$s
}    :o7M$YLm_*R,m O/r
F[3P1]4m;t'M1l
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/!ErH'H#?*eTCB
{zz+\3g$~6X}g
    Stack optr,opnd;{4H b7^7wwL4^8w
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
;] s'q ts,m!DC     char c;$kh.t D1o#\Uon,Q
    char buf[16];2U(zQbr{$G9W
    int i=0;?6ed9?9[?3hi'[
   
2ID\p` S\2n4q     InitStack(optr); /*用于寄存运算符*/
6wjbZ2K@&H+a0f!C     InitStack(opnd); /*用于寄存操作数和计算结果*/*L x J;u8jEnz5[
    memset(buf,0,sizeof(buf));0g!K.BG/u,z6e
    wC _&^ J%c7v!o
    printf("Enter your expression:");
I+fvpTPR         }4pNCz8U@REH:k
    opr_in.ch='#';
OMlll#Kg?p5R     Push(optr,opr_in); /*'#'入栈*/*kbHCs}G[
    GetTop(optr,opr_top); I%|0X._,D } G'T"E+r
    c=getchar();+Z L$tSi J6L%Yz
    while(c!='='||opr_top.ch!='#')
i/eAQ0E/j     {
5X?Z ^ukx         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
r#A??Up8jvv         {
_j0h exDCn             buf[i]=c;[;CZZk@[
            i++;)a4xA"u5~
            c=getchar();!Q8cO/Jb8?
        }v+O$LB0z$uQ
        else /*是运算符*/
?N@ u'AP5]         {
6u3f*u(| g'o:k9zY             buf[i]='\0';N)?Thl7Y
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/wL%?6cZ-[d }
            {/lA]z*f;M2n
                 opn_in.data=(float)atof(buf);b;]2j9_ O6fn
                 Push(opnd,opn_in);
)~hf7n {8HHP                  printf("opnd入栈:[%f]\n",opn_in.data);q.`["G E.fC
                 i=0; aA;].RZ`8A o/?8B
                 memset(buf,0,sizeof(buf));b fW7o}.B0l
            }
L;bLP5@             opr_in.ch=c;}"Tc%Z}ra
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ uy8\nA9D g$PX
            {&]8H]et6ut2J
                case '<': /*优先级小于栈顶结点,则运算符入栈*/n|VK-@!{vi
                     Push(optr,opr_in);
iEOo#v0C                      printf("optr入栈:[%c]\n",opr_in.ch);@ Bj;H_M
                     c=getchar();
w'Q+N.D8jC1Z3kE                      break;
`-Zb?6V"d                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2x6N(B4A` Df                      Pop(optr,e);
7zJ AY;@/D5`B0x                      printf("optr出栈:去掉括号\n");
F](w'h&W7t                      c=getchar();3^TnPp
                     break;
o A f)G(SvmWH                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
.@@T,c[#E:j)Ul                      Pop(optr,opr_t);4twIx[`
                     printf("optr出栈:[%c]\n",opr_t.ch);;V et~Pse,t
                     if(Pop(opnd,b)<0)
r eE)Ada                      {(k;\"Y:u:nD
                         printf("Bad Input!\n");Z3AA0Wt X_l
                         fflush(stdin);
xd X wt7E Iosw#F                          return -1;
(D`$TP/A P`$SRm                      }
WbC7^sI                      printf("opnd出栈:[%f]\n",b.data);0{5P"us} z%S
                     if(Pop(opnd,a)<0)1D%@%r?g
                     {"Gi#m&v,VI
                         printf("Bad Input!\n");b ^8m7@Z@v4n!}![\
                         fflush(stdin);
7YS-X#{:Xx:D                          return -1;5UXfR7pt3a k
                     }vX8Sx{
                     printf("opnd出栈:[%f]\n",a.data);*ZE/cN,e(vQ r
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1jB/V'|7iW#p                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ BoRdkw#g\Sq
                     printf("结果入栈:[%f]\n",opn_tmp.data);Z4W$|&j&CrV'I
                     break;
/c$M0sd"x0kU             }
"^h"\6a%`!}Fm3E'ah-h         }y;Am!X'm"W
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                6fEq+v3l5U|I
    }
,PW(zT^3`;R/fl$O     GetTop(opnd,opn_tmp);(M `"s5mV~9o,tY/s;N
    DestroyStack(optr);
']Eny c#x"F7`     DestroyStack(opnd);
&I@0h"jq'ySbj     return opn_tmp.data;
0xH@Be/LJ$Uz }YNlV)s6a

C7U a_Y+zRz char *killzero(char *res,float result)
]uI r:m"z't `Y {
9an N j/A? b hR     int i;l+a(F I6rH
e!y"CLT#c"TW
    sprintf(res,"%f",result);
Tk|h_y{     i=(int)strlen(res)-1;0e ? [ha!]/S
    while(i&&res[i]=='0')
b@E K5X'n     {
u cr0]+IT         res[i]='\0';
A*Z0K Y%Jv3jZ         i--;9G.MQ7J Hs \Y)X.R
    }*}ip5Yu"V5JFR
    if(res[i]=='.')
jN(L!r2G py[ITu _ g         res[i]='\0'; k7C T t^!l;Q9y4}
    return res;
9WW8v,[M+M^3E };G|8IF,q&` P
5s5i)hw+A_0h
int main()
R&^%`%[;cYa` {
\8m&?1T;l:I [h     char ch;U:]-e5d8{o
    char res[64];pqX6n&r#@
    float result;
bw:@u'e%Pi f[wC     while(1)
;JW"]3E-_[     {
-@ T| Xz\.dp0ac         result=compute();
8aJd {!td!u5E#g r{5n         printf("\nThe result is:%s\n",killzero(res,result));x1`?N1eI+YA
        printf("Do you want to continue(y/n)?:") ;
Vr@ X.D LP"~         ch=getch();R|qK as)x
        putchar(ch);4I5B!@7W6G"N\$}l7U
        if(ch=='n'||ch=='N')
^-j9Z5qw             break;n.u5[-^ [:^)gif
        else
a;G({)@Yep+C%s)X             system("cls"); k+D }h(O%G E3b
    } |oY eeN#P Z {_.X
    return 0;
#kxttmw }[/i][/i][/i][/i][/i][/i]
!f%Af0NV )L V~(pGaC;\"P.T
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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