捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.g8r%l{ g,L1O
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1Nv3?L!U ^ /**************表达式计算器************/
,Fq2c\0t #include <stdio.h>
0W-Ho1YLG+y h9@D #include <stdlib.h>
jA3J&rGu #include <string.h>
N_5eP5@.y4b8F #include <conio.h>+sGY/E-\4u^
#include <malloc.h>
I%Q5|5Ds P2m U&XE1i\,~
#define STACK_SIZE 100
_3@e!F|%_ #define APPEND_SIZE 10!M;}"k]a+D0_O

)Ub4C Fv)cM`#E*^8D struct SNode{
e,@ x0u{@vk     float data; /*存放操作数或者计算结果*/&n al*OO s*g ~ R
    char ch; /*存放运算符*/7nf {,m K2u
}; {@Fo2S&xV|0}d
X?j'w+_LQy
struct Stack{
&e+Z rseTb*p J     SNode *top;#]6oQ p!mY [.N:f[
    SNode *base;
p?P5_/ug'Z*AC     int size;
;f J,~0}Q.K.Y };3W?!RW;?&G"r
!{7Q:hX/m'J#?&u%~
/*栈操作函数*/
7~I!y!e oi)Dg int InitStack(Stack &S); /*创建栈*/)ao H,O D{5UU
int DestroyStack(Stack &S); /*销毁栈*/ sv+D9rN r
int ClearStack(Stack &S); /*清空栈*/
^1c\2q A\k5O9f:U int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/(_ d+?7S/U|-g7E
int Push(Stack &S,SNode e); /*将结点e压入栈*/z VXe;v%j
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
3Wsv5@g^|!`q P8_:J{Q
/*表达式计算器相关函数*/+X(]1E Q&].d*OV"P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/2V-zS0eV
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
li}e I%K float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
#?D EQg6|X float compute(); /*表达式结算器主函数*/
s7n4[1Y6v#^/k,u\m7e char *killzero(float result); /*去掉结果后面的0*/
D']9Y fp6C9Q
*[4RT$y;r(FE int InitStack(Stack &S)0t6L.Tbt
{u*v'S9o Z'Dm
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));G-OF5Cyx_8T
    if(S.base==NULL)
u)joe,b'A1W y}     {x,JPS W;NW
        printf("动态分配内存失败!");%GK5TJ y(@1C:~
        return -1;9sB(xh0v[
    }kW.B2_"iy,w
    S.top=S.base;
2t#_5qBn N?$r"I     S.size=STACK_SIZE;
4ZUyGl[9SC     return 0;o+n q XLE{K
}pMR U7q rxA
{CO.IR.y9y7N
int DestroyStack(Stack &S)
e UP#gz;c4p {
I1rYU3wT!H c     free(S.base);N^7z/L*gJ8y
    return 0;
!e,WF)H3v k([M }
j:o!Xb!C*_%d
:NpKd&PSi-i,\ int ClearStack(Stack &S)9B,A~uX~
{
:m%n;KKW$FEETH     S.top=S.base;\;{+C~X.Kf
    return 0; K9pBt#D
}
:yh!a+v0q/y M[6{ B:@P8Rc?y
int GetTop(Stack S,SNode &e)
U6ji qX6^K+Q-l V {
HNOB8e+\%l&C&af     if(S.top==S.base)
!r`d H P_.Q|? K     {3a|5_;~)Hdz
        printf("栈以为空!");
fZ:g1Jhm8wz*Y         return -1;
SN]%P DO'}m     } K8E ~ZXD p
    e=*(S.top-1);
M KZ'k*[EX     return 0;
u$o!E$n&wz5X }
G*n3M C m0l%N7h[s
[&\#G \4DT1q int Push(Stack &S,SNode e)sO5t&w;{axn#~0L
{
l9?.SEek [Eo^     if(S.top-S.base>=S.size)
j E M w9PX5S \,QF4r     {?Q m"s!I6k.O!s?
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Mp7M)a~W6b         if(S.base==NULL)
%sc|#XJ2B9A} U         {#y#H&t9GTL'w_+la?l
            printf("动态分配内存失败!");c Xs'D9G$j
            return -1;q6bNpy
        }
-VC7NA8t4f+e         S.top=S.base+S.size;
Z-]7r[)\         S.size+=APPEND_SIZE;
(C8G}FN%y-E     }
@E*VR2TO3|5O     *S.top=e;
XbC)J7P \!ao     S.top++;
3Y(]Qg%J9u$H W0~!i     return 0;,zBt w [&I
}9o`EkF'mc a`!a8J
0w&\6_5Y&| z
int Pop(Stack &S,SNode &e)"m p0EABf(^4C IG$qG
{,D2JMa'l Fyv
    if(S.top==S.base)
,O1H|:qo$v     {b Z%r;L.@:B9R
        printf("栈为空!"); u&H2@@R [X%K
        return -1;_+Y$B^;H/w8s
    }B?+JCS ^*~6Z
    e=*(S.top-1);N.yz(c3N/Gf#}
    S.top--;3H`R]"DC})a-r4|
    return 0;
/XBsj V"O9E$K }
aaK jIu _D fER-u^L5F&\
char get_precede(char s,char c);ucQ'F1]
{
,h!s#NF"h'yD$F     switch(s)${?h9oYC-G?
    { h2Q3GSB
        case '+':                 
0yKm7U0F/?y+RP         case '-':
p(rx#t{ ^kR,s              if(c=='+'||c=='-')l M hu6EE
                 return '>';5^1w.E d{ C^
             else if(c=='*'||c=='/')2d1Vv0f"s!nY
                 return '<';
$J6AJZW M              else if(c=='(')'_K z$]:B ik+z
                 return '<';(w'Qr `1r K#|;{y W
             else if(c==')')qSd]G
                 return '>';y6I6X0q4Y cH}`
             else '?U:pta9y)SS
                 return '>';*E/e)}7zN;y)] |
        case '*':J5J(V*t5D4l;Ya
        case '/':
K"MJ3i oW              if(c=='+'||c=='-')
aqT#SVb?                  return '>';
h^?u5fkjT              else if(c=='*'||c=='/')
U#U^d9P~                  return '>';!L2Vh4Wim c?
             else if(c=='(')
5S\ i0{1z?W                  return '<';#B gxq6}-x
             else if(c==')')
Dqe4k.O!Lr                  return '>';Z,]z0\r%R*J7n
             else
S+p Tzq                  return '>';
1G'D(Or$g lr&y2Q^         case '(':
?7aY%|&X+x5Do              if(c=='+'||c=='-')
0P(Z(?:U%N(wwh j3H#i                  return '<';
m b&g)h;V7\O+t5Oq              else if(c=='*'||c=='/')
8a$Pty t V$iZ?Q                  return '<';9{1pES:zLe }
             else if(c=='(')
g/KW$qf0Gu'c*M                  return '<';"z-cd1i9pya1s7mN[
             else if(c==')')
^ SVQH$`0DJR0`                  return '=';z~ xonz
             else3}0w9d'`7G[d}
                 return 'E';
V\8{]6c.|         case ')': O0rFYP0[T0U
             if(c=='+'||c=='-')GmUE C#~DU"@ G
                 return '>';z&fh [6n-j,B;j Zh
             else if(c=='*'||c=='/')
~[_#\5zqb                  return '>';;S"dj7rnq8}3d WX1U
             else if(c=='(')$QPI"h5s)T
                 return 'E';
*I%|Vm }3d              else if(c==')')
?7XBmp {s                  return '>';
ve3BA$QI]7tF\              else
6sadi#TZ0V!x                  return '>';/H;M0o!i8E9fE4V"M:y
        case '#':A:k Cy pm
             if(c=='+'||c=='-')
ty,D4cFMR                  return '<';
e/h+C[ H2@              else if(c=='*'||c=='/')
X'Jex o-u0SW,]                  return '<';MQ0W\NH
             else if(c=='(')
3L#xh:T`N                  return '<'; us.gEQ#O I
             else if(c==')')
n7NHhW                  return 'E';
*c R)h%s'D/c:m              elseA:G(V)`}'bj4l
                 return '=';+D2U3J'N{ |
        default:.J!ds(zU
             break; h J E LYQ
    }
Azc1Vl6U)D     return 0;   
a}%j-m#c }U$NJC l~"A\n_z

u&U d D;p1m9WXK int isOpr(char c)
#U}x&`\ {
0nd3j;e Kp     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')hA3`~+Te^+R
        return 0;v3VUy+]tA2Jt
    else
/c1Z Vr9Ti4t FuLGA         return 1;
+f+Ssn~ }PoV2h&~ ok

hV!C },Gmn float operate(float x, char opr, float y)1h#J7P{["r({
{,Eh6x?;\^8hI AuG
    float result;6`0hT3l%o
    switch (opr)
8_E*ZT {K,R_     {
iI+BaKTK/\ F         case '+':
}aUY9FW              result = x + y;#zHbH U$J_
             break;/_(WA/X C{R:?
        case '-': Y'F u Ds|
             result = x - y;%u*L?b x(G
             break;
-J5k&t*^5Z&E9YF e         case '*': Ic T)CGe1wij
             result = x * y; O/})a$gr
             break;)U9cIN#bFO
        case '/':
t8ZclY              if (y == 0)
;XeA+} J&n!d              {
I!A4I/J%X,eUu,q]                 printf("Divided by zero!\n");
E ^&| i T0N                 return 0;
$b't,i$]-}-`              }
G}ki8Wa!~              else]'i'g3j _u8b
             {
s#@-dq5x,?                  result = x / y;
-]I-q4^]6zl*o                  break;@Nz9eYK~
             }6v4oJ+] NeLh7Q(b
       default:
HNK0bS`w              printf("Bad Input.\n"); 3m7V"H8L#I!u4_
             return 0;@C0F'I*As8t DWuP
    }7Vg{0X.A(a]z3d
    return result;X A3I?bk
}    %Z L@%Y/S m
N2V ?7[7_n,I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1P:cW \5Kbb\-lN
{-S$?o/dH3JBE
    Stack optr,opnd;
G?`^&u     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Ui E{9em4B1MN)K     char c;.Dp/j-d1A@\L;o
    char buf[16];e(VN z G s*e@
    int i=0;
W6j[DU&~/h(DQ'h"n     #D%IIe#\.t.T%?ke
    InitStack(optr); /*用于寄存运算符*/
6O'yw M]     InitStack(opnd); /*用于寄存操作数和计算结果*/
?m,W4qVp2g     memset(buf,0,sizeof(buf));
O%bBZ{x}&l.]I    
&f6jR.VR     printf("Enter your expression:");)n hH5B n&sn:d
        OeY7M(cmi"{
    opr_in.ch='#';
|@8G(b$V"g:[G     Push(optr,opr_in); /*'#'入栈*/Ns1X,NHv%w z ^ E.f!w
    GetTop(optr,opr_top);
ZG6@Er0\3c'?K/a \     c=getchar();
jniA?3B     while(c!='='||opr_top.ch!='#')5m5gi`%AFS
    {
"j(gy\X*e.u0J+Au         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
R N/_0~j)],U$Z         {_r@w6Hr q9rL7?
            buf[i]=c;
7aW9SA tO1j"C             i++;
#k3Q/?t'|q2_             c=getchar();
iEvAp+N         }
v {0LX ])e g+W R6J b         else /*是运算符*/v|,y&^2mh#e
        {(L?9^K9^L-U0\1Pd:Gt
            buf[i]='\0';&bsj@TK
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2`/|h8M*h3ir
            {:OB,FYL3k;M
                 opn_in.data=(float)atof(buf);
:nr$h&\B                  Push(opnd,opn_in);Gp'c{,H[j }.w
                 printf("opnd入栈:[%f]\n",opn_in.data);
^|8]7^-IAC                  i=0;dw$~P,[I y
                 memset(buf,0,sizeof(buf));!@h;A Z(Q V
            }8A1J P%Q0U
            opr_in.ch=c;H}.{#e*Mhh9Dnd
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*//j8C/Z~g#e5MB)i
            {
F5d0s1|*v&Re                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
}]c:Y#JMy[Xq                      Push(optr,opr_in); t rM5g/R
                     printf("optr入栈:[%c]\n",opr_in.ch);s`.To5Y1w&}}
                     c=getchar();
_+vRF+Z? X                      break;#_$hcg.K;PLpH4@
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ iR8i*ZM
                     Pop(optr,e);
H+VP3Q Q3`                      printf("optr出栈:去掉括号\n");
h,bhA(`0N                      c=getchar();
#wa }iwX~ GE                      break;4bh&Z9C8\
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/? [.nw[-s!F#F
                     Pop(optr,opr_t);3GJvui.I5x,V
                     printf("optr出栈:[%c]\n",opr_t.ch);
g/Q"U-Bn e4p9Y:Z}pl                      if(Pop(opnd,b)<0)
Q-X5QK3^2m#H                      {&mJ+HG }m7pl
                         printf("Bad Input!\n");(B,S Bl0o;f C
                         fflush(stdin);
K!{ x#_Rb                          return -1;
.lrH,}0c                      }$G [U[,qt,o+\T
                     printf("opnd出栈:[%f]\n",b.data);
%N Q4sP6dv]                      if(Pop(opnd,a)<0)
r J'^/~s                      {
v7v(LCf2Za)@@                          printf("Bad Input!\n");p+D k~+o;E#V
                         fflush(stdin);
3w| GXy&W"U                          return -1;
5q7~&Hi ^iSl5ru                      }
H,W6xO$rQ? k(A }                      printf("opnd出栈:[%f]\n",a.data);
Tb.KxRa&x-LA                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/|n|TLV.`ted~
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
i tG h0g:P:}U                      printf("结果入栈:[%f]\n",opn_tmp.data);
,d*bz$s{q4M$v                      break;
Q.[!_k6@             }
e vj!xEV6YO"a3W         }&?U3d@"\,F#X
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
&Xh X I#H }p@     }4Y!f Yg`3ifP'~
    GetTop(opnd,opn_tmp);Vj;H-Q7b6m'~_`
    DestroyStack(optr);|[0mF)^7w'_`
    DestroyStack(opnd);
k |3w2C&I     return opn_tmp.data;
|o[;sB"MF }
3_)LWS*dL 5q3J$Dd3EN~
char *killzero(char *res,float result)v#{ZJ@ ?fYG
{
(dcq1u(i#HJy     int i;
W5BaA D ]_(j "z4e0{ey#Q7_%N5R E
    sprintf(res,"%f",result);
i m&@VP2x     i=(int)strlen(res)-1;|{lMY ~C/g?S"e
    while(i&&res[i]=='0')
%L\'x b!C|     {&Z dW1v y#D5g6hE
        res[i]='\0';H%UGW])w
        i--;'Dg5D9I)w\_
    }8~$| b l"y4? KVP7j
    if(res[i]=='.'))u0jd l!d g!I
        res[i]='\0';
`8Fphn M0_     return res;(mp/{+S){:N5k
}
N%oJRv]u x3x t.p4w
int main()T4Ay^u;D R ^:n
{
U"U"yk7bm     char ch;Qw] `t H t}c
    char res[64];?*L0I6Mu*SR
    float result;
.O8V9h+Z4U'D@ H$@     while(1)
9n9HnvLy#?i$s     {
zf3b q6h qd9No         result=compute();
*sg?H^LSD&P         printf("\nThe result is:%s\n",killzero(res,result));Mg%x!j"{ e*B
        printf("Do you want to continue(y/n)?:") ;i5Y8^9_9dN$N
        ch=getch();,ac)j)Qq-P;\'q2f
        putchar(ch);
,g ]3tM8w8y         if(ch=='n'||ch=='N')
G`{5X o             break;R:c2[)R N^*[2v8mUK
        else
si+D){+r}{ Q,I&D             system("cls");
+lf(dZ2EJ.A/P/F`"d     }$uNU d Jll
    return 0; y%]%c@'no7v
}[/i][/i][/i][/i][/i][/i]
V5xM Kmi\^ /k?+DL U
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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