捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.!B [vm'N/]rn
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
x&`/E(@5eko:Q /**************表达式计算器************/
)W e0J\:dm{/B #include <stdio.h>H7J,k~s;pI
#include <stdlib.h>
,SmrV!~5d7{2\ #include <string.h>H&Pi?@3^
#include <conio.h>m0M2`2fR`
#include <malloc.h>
2l ^%B(nH7FN
mst moi #define STACK_SIZE 100*oza4ja8z:m;LI
#define APPEND_SIZE 10
'i0r@Wi }0i` x e{}7P+PQP(Zs
struct SNode{%z'm)E.u2Si([/|$p
    float data; /*存放操作数或者计算结果*/r/AV2P-?(X`z:I}
    char ch; /*存放运算符*/!bZ] [} NV%E%d
};-Vg n m;t _q

RG}+pB+O1vS{+| struct Stack{
1w\mF { S3Ks     SNode *top; T'Q-^vD3X:IBB^]
    SNode *base;
w:{3kLN3X7W     int size;
bH? Hg2?7f };
-nN _@ S0N O
H]@ _U6d/F /*栈操作函数*/
!qwP)Kr O int InitStack(Stack &S); /*创建栈*/
9f(`{m#K(JE int DestroyStack(Stack &S); /*销毁栈*/
G;e2}.d5n4dW:u+y int ClearStack(Stack &S); /*清空栈*/8S1}gdX?4XS
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/3h1lb'yS(P*_A
int Push(Stack &S,SNode e); /*将结点e压入栈*/
(Q.hw-qy/e| t7g int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+\d xL?
Wl4x8M2m o c#i?H
/*表达式计算器相关函数*/
0|JnS|pm)S char get_precede(char s,char c); /*判断运算符s和c的优先级*/x huI(M4Y
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8mG3T1gi#wyRk.q float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/+S LNz1Mr z(JAa
float compute(); /*表达式结算器主函数*/
i%p"?3lI6q char *killzero(float result); /*去掉结果后面的0*/
OR+Wek
N ~xXF9I \:r Y&d int InitStack(Stack &S)
8U't,kba7C"E {#` Mi#Dq}b2P8j
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
BD,~4}g.U}uZ     if(S.base==NULL)
[ R3\Ny0B^/T     {qGH,d{-fA t'y}9]$P
        printf("动态分配内存失败!");^bE db\G
        return -1;
;H%c~A[F-E     }
*W ndR'\'QE     S.top=S.base;
z%ut6bs     S.size=STACK_SIZE;
x0T)o7l*m:p?3o     return 0;
)mp5gb7|*se9~!xr4?&? }
;Z i ?5jY Kkg$W/\3R'`
int DestroyStack(Stack &S)*M],x z C,F
{
s}%?dGBL#P:rJ+M     free(S.base);Lqts}
    return 0;
qp9jb!SuK }
RIaT8Hwh7u5BM
L9|im:AX,USj int ClearStack(Stack &S){ q3vEb7?"ph
{
0R"N7DH Wu0v     S.top=S.base;'oZ.M3U3l;a%h;R g0v
    return 0;L*F6w7i0?#\/rS
}0O?lKt

&hTw4S:C y1o int GetTop(Stack S,SNode &e)'b*Pf!Yn$e
{
/j,dv4m;ghika*A     if(S.top==S.base)7^ HaaJ3JK
    {z8S$_/dd \:z Mu4h
        printf("栈以为空!"); Xr7Op m,R7i{l
        return -1;'zk0n"H0D*Z waE1z
    }+_1vg"|H%pmea
    e=*(S.top-1);
XZ-M)GcRD;E     return 0;Hmn;Rk'QXA
}T jp+h.u*DMs(|

R"oB wj^ int Push(Stack &S,SNode e)a8J$S)U9J
{
Ec |P2ar     if(S.top-S.base>=S.size)
*C{%H5^[     {
;D2TG,?#VR[-H         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
e6Jg1z6O9Fqn         if(S.base==NULL)
c i\|&s~\A         {O+ic s k[#l
            printf("动态分配内存失败!");
0A+}H x)^r kM             return -1;U.|`,R!?b1R+R
        }7om d5\M
        S.top=S.base+S.size; z'Of;U6j'` ?T
        S.size+=APPEND_SIZE;
9R.O-Kz'd     }
]mf gmO     *S.top=e;
)S;J*p?)i3Yh     S.top++; [ Y$UD lu5H(`z
    return 0;
4],G\)}Y9D1wS }
/SWr2@$C;@qr(W@
T3c&ErW0IE-|[a int Pop(Stack &S,SNode &e)
bt ?r WY%[ {&Z0rx DjI$D/n$C
    if(S.top==S.base)2J*le7I Sr)Jdu:O
    {
1A PD3RT0y;o         printf("栈为空!");:QP X:vL_
        return -1;;FCfy5|QS A
    }
j!n!YY1P$j t x2} @*w     e=*(S.top-1);dT Q6|L
    S.top--;
S vqW cN3Sw     return 0;
} H;_,x7g%aA }
!Me rz#B*M pF4QzgDVy
char get_precede(char s,char c))^/n.}(q AM%n7C
{
K7z"|9a$noz6M]     switch(s)
{a INK+wDj&jT     {5z/_#Rtz}9M;N }v
        case '+':                 
:Fgx(j2Y&@E c         case '-':+T"q'A,Rm%^W&n
             if(c=='+'||c=='-')
1py!V5u d5b7H                  return '>';c0o0^P3P0@e}
             else if(c=='*'||c=='/')&hjvP\E!A T
                 return '<';4` @"}/G^+Bj
             else if(c=='(') MEpJz"|1Ji
                 return '<'; Y,W z]f#MB
             else if(c==')')!\+?A5Po;a
                 return '>';
6u$X~ y3I"bSX              else
3]d(sQ;k$At3H.UH                  return '>';
(QuO:nL6d         case '*':k$@ b)Rt}9I
        case '/':
~*qy P6?8i y9T              if(c=='+'||c=='-')
w%k4K3rZ6`                  return '>';
p9B9uV;U Gr              else if(c=='*'||c=='/')
B0nQ!Al}|                  return '>';
N%D\.F&z.lF5QP GPv.C              else if(c=='(')
0_I3ZYO5W3m                  return '<';$i-X9|g%d M)vp^ y|
             else if(c==')')
s9b+{;]^A0T)MY%X*fN                  return '>';
~e:|)Yg f \              else.yJI0W'c9[
                 return '>';
r6t1EU%pn;y2C         case '(':
l%Z|VKf              if(c=='+'||c=='-')
8^}Q0j!@-\0S%|Dm8G                  return '<';
Ix.Y8GaTe              else if(c=='*'||c=='/')
X_^s)p0G,Y[%n                  return '<';
l8K%x/x ?O"|Q XN~              else if(c=='(')
^ G-g dc RFb                  return '<';
J i|;FH&^&C              else if(c==')')$nnNO vC$mSw
                 return '=';
2pf,\^D'sFF              elsel!C!o].ng a+[de[*F
                 return 'E';
'W.Vflg2QY.{q         case ')':
z ` H U:b} L+H W              if(c=='+'||c=='-')1{*^ sc7n'ny!i
                 return '>';Ui V@h*Y0[1d
             else if(c=='*'||c=='/')
Y-n3TC3VQ2][                  return '>';
anJ'd2F/o^              else if(c=='(')u:]6fmZF
                 return 'E';l8U u?R
             else if(c==')')` B UqlS u
                 return '>';"u9Yb/s3r't(p(H&rQ
             elsei-UN FAl [Q9iB
                 return '>';0Wx:g3q0wg1]
        case '#':
YWl\_6m*a:j              if(c=='+'||c=='-')*@l;n+z9uNg.H6Z
                 return '<';-Yw9dy,dh_!eg-V
             else if(c=='*'||c=='/')
M+D1~Lyu%y/c _ Y                  return '<';%Ob?!@7m#Ir%XoN
             else if(c=='(')'k%R8mjDzZ{3I
                 return '<';Sc%Q*fM1I b
             else if(c==')')6r)uiZ7D:Q0]
                 return 'E';OS\W)G-YD
             else
.xjzF-cH&?                  return '=';
RNq8{x WB%v ?V         default:
FV-bC`8L`              break;
`w6z WSx)[|&J     }e y(G~5S
    return 0;    G'nzD msCu
}
Go5w8B'b1s-G .AD2m;@E
int isOpr(char c)
A0G%h9ars {
ZEQ(Qp.T5R5s     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
r4E\*P4p.T         return 0; Q@S0E#wb t)b E
    else v7q9fUV[4}/B
        return 1;0WDhLL-Eh0z.|
}7D5]s| Q6U'x@ b

0lr3Ws+d;^3Iu float operate(float x, char opr, float y)
/a'iE,_}7z,qF(QA {
6| c?"vcX&_Q     float result;AXqk5s&Y7C
    switch (opr)B.N!zT@ Sea
    {m oM%v5g(O
        case '+': 'K;N"FKg` VO
             result = x + y;
x GQ%u#]h%|+c6C"L              break;
$N-t3d-v+pE         case '-':
N{@-S,[0kE#]              result = x - y;
m |Y ^x Er9qC              break;
W v4v|(b1|         case '*': \U#V9}*p{P{
             result = x * y;
#BK)G,o4r iBup ?              break;
$om:j7gQ1~         case '/': MiJnt"[ qM
             if (y == 0)
ce0__8@7K,fqA              {O1yY`2xZz
                printf("Divided by zero!\n");2BcLPCg
                return 0;
#T~E-g0v3yjd\              }
C|9Y'JC$XU              elseRt3d-s0Q5\
             {TU9wF$K
                 result = x / y;4E2p Du$Q}0M7uc,I#|
                 break;
-G(plm+fT]              }(AF/p+cK*Ym
       default: ciar ]y
             printf("Bad Input.\n");
$S8kB8yJ mU              return 0;r n*R;[Ow4l$g
    }7wo#l0z p{4ml n O
    return result;
+s_a&Q c-Yg}Y+o }   
6^^"e)]~$PvCJ @ dn"J l([5X#M7EU
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
i;y#uh^S)bGF] {~9F"K{%K?il
    Stack optr,opnd; l{/iwv\&w{V,`
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
b[2K7m;q{ K{4E4?     char c;RJc3P9G8Ox0K:O
    char buf[16];-B+]ZblT%O%h
    int i=0;fI2|C7d+@6U-F
   
0hH]xGoA^     InitStack(optr); /*用于寄存运算符*/p,]#g PK R5R.am
    InitStack(opnd); /*用于寄存操作数和计算结果*/
jD(m?)u~?     memset(buf,0,sizeof(buf));
Rlos(M;`&S-D    
jGjHd N z     printf("Enter your expression:");Xo{Eg.u |f:Bs
        
a&UxLYwj:U     opr_in.ch='#';
%DW5w%LQ7s+N ]     Push(optr,opr_in); /*'#'入栈*/,K~ X-FletX0DDy
    GetTop(optr,opr_top);
Zgon-IP     c=getchar();
1X'[.n5aMa:W     while(c!='='||opr_top.ch!='#')&?)Y#n^ Qm,wM1d
    {
3['W7|rYM CK7x         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/-L%L8?$fT? ?N
        {&x+AX8['l'L8D
            buf[i]=c;
~Y,]?8j(T6~4m             i++;
H{#A.aV8Z%^*m             c=getchar();2S&^h _`4X"[
        }#V/H5u7Q:^:Z
        else /*是运算符*/ {u,|co ?R9U&Tm K[7~5G
        {4N4p.Qg(Xw6i3K:v
            buf[i]='\0';?K'fBB%d-cAof
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
w0D;@PTKYe\'jzW9a             {4qV RRUP"s
                 opn_in.data=(float)atof(buf);(x"r K"FgB1~
                 Push(opnd,opn_in);:vX \Ph8I)^*gGl9L
                 printf("opnd入栈:[%f]\n",opn_in.data);
#` N'Tqg3pa`7k%j j$M                  i=0;"Bqi1`g`(y8sg
                 memset(buf,0,sizeof(buf));
\8{T ZEs h4Y             }
5G&|Hw2M6v/Vnv9s             opr_in.ch=c;
K MkD+fk }i             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
hDSo7t             {
9JA,DIh7~~%M h                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
h:h~;dr.QXz                      Push(optr,opr_in);dab2k }E
                     printf("optr入栈:[%c]\n",opr_in.ch);G:v5` q Y_$D2u
                     c=getchar();
lm};S_4O|$w$A                      break;-s4}HCu6zWD8cJ
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/LbHi9bH K                      Pop(optr,e); j(po"s%n'|'Pk7Q BK
                     printf("optr出栈:去掉括号\n"); t3Hf0`Z#s,{'q#K l
                     c=getchar();.N'Pc$G-tN"J
                     break;
S^8nA1J^ T                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
^m y"d e!Dwut.}                      Pop(optr,opr_t);)~ p6}Z#j#R0G
                     printf("optr出栈:[%c]\n",opr_t.ch);)h!w&] F,`&_1Ea4P
                     if(Pop(opnd,b)<0)w:[*F)xE@6P8]Bv
                     {
$\G6jf;U]2o w                          printf("Bad Input!\n");S$utVSNbCNXR
                         fflush(stdin);
kc$j%Od4PTI;]                          return -1;
V+] @aifx4m                      }
K Z%b w]w8x @0p                      printf("opnd出栈:[%f]\n",b.data);
D\$|2o5FG                      if(Pop(opnd,a)<0)
G D FED;R                      {
V,z LW*r                          printf("Bad Input!\n");
/lDV3u+g/t                          fflush(stdin);W m5}-[5d3ym
                         return -1;H*G&e/B(u6N1\2Z*t
                     }Xz@Fs*Bn
                     printf("opnd出栈:[%f]\n",a.data);(pC6V hyX
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
IyF/o3E(J-n \                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/~8do4Z%slY"e
                     printf("结果入栈:[%f]\n",opn_tmp.data);Y(y^+C _K_K
                     break; B[/H"D8Q2S ^+T
            }t*XD"L7RdJ
        }
KBhWli z'x         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ?.MZ;YZ:x
    }
6dba5pnw     GetTop(opnd,opn_tmp);Q"o$v(o8cX[D
    DestroyStack(optr);
B$H'C!g2@LKzn     DestroyStack(opnd);+hK$\+jJ_ P m7? Q
    return opn_tmp.data;T&SCTN)Q*EF+}[0]
}.[ o$~4QNk9i5?
v.p|G+lV4A
char *killzero(char *res,float result)uhkAl
{
M*S z;NF#Cv+U2BlB,lM     int i;5vLK!whq

Tc)Q6J-jS\:C5vj     sprintf(res,"%f",result);
F?2[LPy5?qE9p&dT     i=(int)strlen(res)-1;
*Zt%i q|zQ3q     while(i&&res[i]=='0')
&O jc;i;[4a2s     {
'oB TetEn         res[i]='\0';
'jU(f-acc         i--;
CJhm5^{(D&ND-}&`#G     }W(yC:xYjm)xUL"Ly
    if(res[i]=='.')&|iE?e(qh B
        res[i]='\0';~Lz(s@&r M%p[
    return res;
8hK.q]8V*} }
@lt^0I"U)d
#qQ-H0ex[c int main()
suS1W7[#Cn0ch"I3GN {
\u&L&A4q     char ch;w!knq'h"dz'e5x?
    char res[64];
`F Ct1[9U)X*m'\|g     float result;
j#CvF-T:C g]D$`     while(1)
5|Cge?C;o8b     {1ebo[B$e*I0YP
        result=compute();
1gmU1V&d!T h!Go         printf("\nThe result is:%s\n",killzero(res,result));S;p+Y,F/ca8i)[(}"V
        printf("Do you want to continue(y/n)?:") ;
J7DJ1QFJy J$~-YIt         ch=getch();:qg}'B9hq s
        putchar(ch);
V C5XWS         if(ch=='n'||ch=='N')i2Q*V4@)[U5oR u
            break;.]E8m"vJ6H
        else9Or3C? Dm
            system("cls");
FS*|]0vg5P     }*xv-u]F
    return 0;
)|:yyD1s }[/i][/i][/i][/i][/i][/i] oaqs5jF
Hu p)j8K7~ Y%Q Z
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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