捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.b T/~wV1ap}nW
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
P;]9s5v@u7D:} /**************表达式计算器************/
*{"AWW3d] #include <stdio.h>
h\!K+t+I [ iQ)C #include <stdlib.h>
v#jUMhdXo} #include <string.h>/s%P(~v G|yZZu
#include <conio.h>|{#eWPG;d[7H+B
#include <malloc.h>-iLM)@Iv1g

mm ij$kZ5~ #define STACK_SIZE 1003nU [B5mF}+kBQ`
#define APPEND_SIZE 106O,tgx n

&gb4@ W%H'X3f"L.tL struct SNode{
%|H!Vq0Cxv     float data; /*存放操作数或者计算结果*/2W4U,rL$mm
    char ch; /*存放运算符*/!EEW\p"?c k!{ }
};i1f!^2z.r G;bxa[1J

%j8NhF5r~W struct Stack{
.NaeW/~H0x     SNode *top;T$OSR:r0?
    SNode *base;
4k$w^:{E7fM{     int size;
Yr1} ] T} V1{ };
4]'VX"c8YLq7p8F x4aMd(U&[,`
/*栈操作函数*/y Y9wHoY%L
int InitStack(Stack &S); /*创建栈*/
3Z~HnTJX int DestroyStack(Stack &S); /*销毁栈*/
O v cz:M N^*`8X int ClearStack(Stack &S); /*清空栈*/
F9lF C[/u+i int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/pP @o*Vu
int Push(Stack &S,SNode e); /*将结点e压入栈*/
"up.XR2^G"\ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/T^)u@2Q2g
wO/RgCG$Ts7M+X4h
/*表达式计算器相关函数*/
(raTa+a1u6] HS char get_precede(char s,char c); /*判断运算符s和c的优先级*/NRB~*s8L(y5T
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/pQ-s,|6IT)k2O!FAP
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/l0H V6P}"?
float compute(); /*表达式结算器主函数*/7T6q3M+vOqh
char *killzero(float result); /*去掉结果后面的0*/
)Y[nZvp!QL
pj Y#CHO0U%[oDP6S.\ int InitStack(Stack &S)0V5J+}-j!r B!Fx
{-J,XX.QxKRu\8c
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); c.Go)~?%\
    if(S.base==NULL)T`ox}Wt2G
    {3AC#x dWFs(P.},KM
        printf("动态分配内存失败!");Hq8T%B)rCQ3dF1e
        return -1;wc ~-{!P&A
    }
b x9u9`2r*K3Nx     S.top=S.base;
tWtyk K)B{     S.size=STACK_SIZE;U!H"l'@#wv9TN
    return 0;
nEQ){K Fb\}c }
#u;r%C9csi6{| 4j6WH*P'Q ?
int DestroyStack(Stack &S)+f8PUe:V/Eb5@? g7i
{
7`;E.hsZWts     free(S.base);
2IK1jk%_8^ Qu     return 0;"y;p"z8Ge
} J#?s-o`3^

RW n D-y8y int ClearStack(Stack &S)
!Cu A-^ b {+G+B \ k(K&A3]$w7l
    S.top=S.base;
)A]LA,v@`DL f;X&P     return 0;
0W%YOF#k(FL }
3EG!r?;? `$g]*Y-MAO 8`y}hS L(_b b(s
int GetTop(Stack S,SNode &e)3A]M:K'n'v
{I;G/T&}+Y;@
    if(S.top==S.base)6JCd!Dau
    {'lb$B+rf"U7~
        printf("栈以为空!");s'h{w i0mk+H j
        return -1;
*s!@I6zx*D|l     }bR?q\ e:T
    e=*(S.top-1);g2FUV1m2i s
    return 0;?0k1{!b4L;G2R/R
}
5A;os7H)FG'DS
!e:JLOj,p-OHek int Push(Stack &S,SNode e);|gK!BGz/W7v-f9I
{&R sR8S5Ukj9i
    if(S.top-S.base>=S.size)
6M j] vB)xT1JE     {
L+c%R!C`*Tc6G6N         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));izC$t0k0^_2r
        if(S.base==NULL)
XH.bD*R.Ny         {
L#Z&_$Nj c"P4xc             printf("动态分配内存失败!");
6J:vexi0q#e6?pRM             return -1;
;WDcM"l%m"};Y.q2[U         })J(o(eK3N
        S.top=S.base+S.size;
~ U,}0Y{;O         S.size+=APPEND_SIZE;-S$Z T8Q'^#p
    }
L s0a%y"g_`T-~8l8O     *S.top=e;
O _*Z k7A.cp(R     S.top++;
8o8|6ZvO_ {     return 0;yNGtZAr3~ gJ
}+vR"r5P G
-?DO;OS a6DxX:B
int Pop(Stack &S,SNode &e) @sE\4Di{
{ ps:Fs!U`'nf2x*k+X
    if(S.top==S.base)
%U s5gQZ(jG j)nz     {sH i^ H+cj0a"Rh
        printf("栈为空!"); v0lq}q
        return -1;
+w U;C1O d*k A     }?A}9v3E
    e=*(S.top-1);
#v?'q q|     S.top--;
V(N8OA-oK5t k:@     return 0; j$`M2iEp c0? w
}+_}:F.StQ9yv0m,[
O.tA,RX#~*[n
char get_precede(char s,char c)
,j z p5ICD vL{,r {
@7Sf6e5n     switch(s)
o2f@#xr#XI     {cV~6DaKBS.y
        case '+':                 8W \ZB3r$p)`z
        case '-':
2U3WgsM/v!P.j              if(c=='+'||c=='-'))] e1?"U7`9W;cl
                 return '>';7e` H2x4g u
             else if(c=='*'||c=='/')
/P(E7v FSq3Q|                  return '<'; ?1t7tSq,g6t/]
             else if(c=='(')]b.m.C C2kb
                 return '<';&}u YS'M[:s-w
             else if(c==')')
Z,v7[!A Le1?                  return '>';_Y3|V,Ag$^Y
             else L gV9iDSjy
                 return '>';
)E of,V\%r(_(O!_         case '*':
Y,h:r,GZ*E         case '/':O"F'?6[Ww
             if(c=='+'||c=='-')
YT)cX.RpH*o                  return '>';
/e#?R+KQ4zeu              else if(c=='*'||c=='/')
p0C ^h X%w)p                  return '>';_!yp'u#?B
             else if(c=='(')
5k8PO;k'^*B{mu                  return '<';
Zw+[G x2UNt              else if(c==')')#\9v8aV2X
                 return '>';#D*WQC5kj6D
             elsew*soz8~+a7U,fbY
                 return '>';
w6p We'ER         case '(':
6g_O-HL,{              if(c=='+'||c=='-')
&~;J8Uq-{:\                  return '<';
y0dRh6GbH~x)E:K              else if(c=='*'||c=='/')O)N0N*A'a'woG!V
                 return '<';+xiSZ;^%]&i9{ A
             else if(c=='(')tMK*j:Z
                 return '<';
c)}&H1@h;M%F              else if(c==')')q`TH#L}Ag
                 return '=';
|U+ew s#]u'jR              else*R5[6Aj$R1RKu
                 return 'E';
._(|@C T6l| ?k Z,s"f5o$~         case ')':2x2rSAU0o3V1d"|z
             if(c=='+'||c=='-')
t{d0x)@&`%v?@                  return '>'; KC-{LI6^#E
             else if(c=='*'||c=='/')
-k2nXe UEX7N                  return '>';
(L%^WT0~7CJ$Hd              else if(c=='(')0@+{Y M{+eS*K
                 return 'E';
~/u2c_&bs _              else if(c==')') g`-Yd!vl
                 return '>';
2[$m"vK TmK              elseN I1LH1y/cY
                 return '>';$l;b&ME)|'E
        case '#':
8Q/yd6L&lyUM!yQJ              if(c=='+'||c=='-')
8ETxm%ms                  return '<'; H3G c1xG"Av@6M
             else if(c=='*'||c=='/')
RB%\G\.l7`z)Q~                  return '<';
d}?#gSv%h:r w!Q              else if(c=='(')#T(LE S'rW?D-`
                 return '<';
B:K{ `{LVq              else if(c==')')^ V)[kZB0t qyi5]
                 return 'E';
Q3y$^Z2a&bn,w^~              elseR {2[1A!H ^$|P x7Y7@
                 return '=';{u2gWnpls
        default:
X:hK8[Ou,O,n              break;
9N%k+n"r6Q&q     }*g_9HC R9] ])s
    return 0;    p s6w;j$j/w mHsT
}4n`3I9dm

5UY*CG]t:J int isOpr(char c)
3HY1q+JX,Ce {
Hu[R@     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')0@.Xe^)oco
        return 0; PB!oP9C D
    else
"E$Lg.N Onx         return 1;
_1O"P-UX5^8N } s8RF O~@ Q/M
2^ZQL?@mD e
float operate(float x, char opr, float y)2sIxV)We sU
{
\2f,s"H;T s%mzv     float result;
vgVB CH(\,K/[     switch (opr)
#~3m'P#G CE     {P8w#V/^X#s_p
        case '+':
g,Y'V} X R              result = x + y;Y"bb$Hd-I1W!x)z'Z-Q
             break;i!l4`3g f UB
        case '-': 7o;xj+R C q!M R9qw
             result = x - y;
!pr:z}^5y6B              break;
,[,a#gu,fk         case '*':
6?dH rG&D'l              result = x * y;'s ?N dL"E
             break;
G WAq5_ @3e         case '/': %i2m9j1N2I*h4A
             if (y == 0)1}a_"WP
             {
'M3Qw:mdF                 printf("Divided by zero!\n");t.L`%u"Y
                return 0;4_:@3I3b;eG'{,w4k+ZXU
             }
+I9d'Ir.~              else
'r"M8Zzc9C])jW              {0N4Q4lT2HKi,N j
                 result = x / y; EK'MGM1U
                 break;\l5dYkJ \
             }
,u7a \k%O4O        default:
j&G e)m6\s$m2KR              printf("Bad Input.\n");
H4r)vm V%H:F8VP1V              return 0;|*c-H'whta'G
    }A7sq+Rbxh&G$F
    return result;C1h M7l o N*}~|x
}   
B*D*Q(j4PWf1F_ f6l/s%b"WiqK
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8aY(y%Tzf.us+I {
`?'z$\*]/y_z1t[u     Stack optr,opnd;
;JS[l6n5q     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;,[(u4U4I ?{ z
    char c;!K:h^$O5tbOow Q-zi5R
    char buf[16];
7i\Q)O0M"r     int i=0;6H;Rb;f'X r(r*Y)`
    8{#y$^S.N v
    InitStack(optr); /*用于寄存运算符*/
vXi&x_'yAeN+r"j     InitStack(opnd); /*用于寄存操作数和计算结果*/+rl!\i5D;u
    memset(buf,0,sizeof(buf));
JZ r_V)O    
@8K6h6I;MBR     printf("Enter your expression:");ut L^L9Jx T iq6a[
        
ez~C B{.k)e     opr_in.ch='#';
%V ES"v&X)zY:dkp`)q     Push(optr,opr_in); /*'#'入栈*/
'ZwKn7yLb     GetTop(optr,opr_top);
k@t.}8n^%O1F     c=getchar();
't)J L:H$v8RAG     while(c!='='||opr_top.ch!='#')
G$Rsb{W     {
A;\1\\6u Uoq3U         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
x&tG1JQ}&K8d {         {
$if\ wt/a             buf[i]=c;[K_g$@iW
            i++;Hk+AppoS4J
            c=getchar();-I:`3X7}F-T
        }g9Z9M9uL3g(A S\n
        else /*是运算符*/
,Z9lW`u)BE         {I}A'J`
            buf[i]='\0';
2w4nO3N-v;i&W7h!d             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/!q#Fgn6E:q
            {
JTn [#{b                  opn_in.data=(float)atof(buf);"_ uv4ZMik&r;s
                 Push(opnd,opn_in);J]z3x;g
                 printf("opnd入栈:[%f]\n",opn_in.data);J%}7D!r2^&QB
                 i=0;
{BXbQ y                  memset(buf,0,sizeof(buf));3H NE8JU/ec
            },u9H1@!SZ#gY8A
            opr_in.ch=c;
#L#{"QN%AB:p-N1JF             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
z+R ^#{!\\             {p3j$r)Q;K4?.XX
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
Rb\&NB.JN#TkU                      Push(optr,opr_in);
/I!zQ Wf AS D$n                      printf("optr入栈:[%c]\n",opr_in.ch);GHDc+abL {,P
                     c=getchar();
j$m_Er f,g"l$p                      break;
(bATnY*A V0b.X                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
q;@*q v5PN                      Pop(optr,e);[6J&M!Ja x,y?
                     printf("optr出栈:去掉括号\n");
's3Q&oCUup+Ix0Q                      c=getchar();
0Y+gZ xW |O*h                      break;
`FX)P"`i1G                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/"PT`n"gX&Xz
                     Pop(optr,opr_t);z$i0PQ bo5C3pY
                     printf("optr出栈:[%c]\n",opr_t.ch);
'B/N g,C~D \:Z4LE                      if(Pop(opnd,b)<0)#v M;U{ Q'yxXd
                     {Qw'n-v9c
                         printf("Bad Input!\n");
E9PS$z'[&u                          fflush(stdin);
~d |[ f l5QA                          return -1;
~7l1B:l3Sj2Q b1w                      }9C,r~:_*].N7hLN A&N
                     printf("opnd出栈:[%f]\n",b.data);m$iQ9i'K!av%nk
                     if(Pop(opnd,a)<0)
+`xu1I(i}n                      {hbs3_6pESxFE
                         printf("Bad Input!\n");
mWB(fr%\                          fflush(stdin);f9V g[`
                         return -1;
i-` lVDOt8r Z/rr)_                      }
af ?#E9t wK                      printf("opnd出栈:[%f]\n",a.data);
(JM*kSA                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9{$_Y9C(J&DM]                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
-h.v^*t[JmF                      printf("结果入栈:[%f]\n",opn_tmp.data);^;?-T WR4nJ%f
                     break;`8p;w jJd9mu
            };b` @6l!M:ko
        }
Z"W9D6yz7EaIc9`         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
9CKwa%j4n%[t     }V gUM d K.O
    GetTop(opnd,opn_tmp);
D;^&ccp     DestroyStack(optr);
YPGJ ]!`     DestroyStack(opnd);NLQ&j.K
    return opn_tmp.data;
5F;m;~&y Zm }
U1CA!~7Q2L `j MR%Pw4nQa
char *killzero(char *res,float result)^g ]p#@q}
{
%D+X)}"ckIo2E     int i;$k4x8Ya.W'Hr'a
y(}7p]MAn
    sprintf(res,"%f",result);
x;s:H3_:t,^     i=(int)strlen(res)-1;\!kx [m9\?
    while(i&&res[i]=='0')
"Q;n,M)fQ.IJ     {
r8e7F$HLT;`:gF/r         res[i]='\0';
4be5@6[ f j(@\         i--;RQ gFE'Z5]
    }
,qh6p8o+geK     if(res[i]=='.')A1u sM!q(CJBW;W"e
        res[i]='\0';&qy;?/[3p2s ^A?H)j
    return res;5go$\+Hep'r0D5[-`~
}2e5P8F]){2zzpcO
~r2HH#F_9`q'u
int main()
%d0e7A-}WD_0j| t {*Bn|I&sFVxyQ&b
    char ch;
1e Giz ~Hy#l     char res[64];Sp7i]g(V
    float result;
1x-X(T.]9WL Q     while(1)
+Sz `8VVG b:U     {
.?zE6~)u*z1`         result=compute();
!R"r&]m:zc         printf("\nThe result is:%s\n",killzero(res,result));
*x/Oo%B P@         printf("Do you want to continue(y/n)?:") ; n{$]W A T O
        ch=getch();0?Dt~Q
        putchar(ch);
!z/Yk4o5@,H         if(ch=='n'||ch=='N')n"?@#WXeo+@2}$KM
            break;
)lK5@3csG;|;o:A         else2B)h9N#Gkz1S'Qm
            system("cls");
,d_r.j m {%n4]I     }
Hjh?,p;EiXk     return 0;t"tj*MB2M7cT
}[/i][/i][/i][/i][/i][/i]
{},_V-o6]:T/_'Qu5^
m4R8iCD6|]r#{)q?j [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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