捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.| zz%\i,h1o8_
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=V0l,tetfn"i
/**************表达式计算器************/6b5U Igp,Y N+ZU
#include <stdio.h>'_,U {7@#h D/j2R,J F
#include <stdlib.h>
x#Pg1T%B.`%f #include <string.h>
p tny4rE%rz4y r #include <conio.h>8l1p.X(N4q!T
#include <malloc.h>[4|.C~$s o,Y&Q
3U:kSV2Y_$Rdx \'Ea
#define STACK_SIZE 100#B^+Q-U\,D
#define APPEND_SIZE 10
(I:_9mJ&K3@hv$q
}o;|'At;Wp M struct SNode{#rEz!],Sp }],z
    float data; /*存放操作数或者计算结果*/8w"q!gAy1q
    char ch; /*存放运算符*/
E{*N s4xvn!J };rQ8LY6XK Q"K#y
XD,b)? D
struct Stack{
:c(?%fnP(DJ     SNode *top;US v7i$rf
    SNode *base;
1pw9yVd0~     int size;X [8T+]o!b;f
};
@0_2|5|:A'Sl ;e~T'\ IR#A;K,V)K
/*栈操作函数*/
&q'uM(~6z+nN} int InitStack(Stack &S); /*创建栈*/
h^PDW!lq int DestroyStack(Stack &S); /*销毁栈*/` H"L a8jR%p-Y zS
int ClearStack(Stack &S); /*清空栈*/ CcS8X/cMW
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
emnBE!C int Push(Stack &S,SNode e); /*将结点e压入栈*/
&g!a)x}:|*@ Q4p int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
Bp\3Q b:l2@J/x 5{8zO P/GF,B5rP
/*表达式计算器相关函数*/["CvVi$T q n
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
k`:`].JApB int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/;q"j+f9`~g Zi
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
g%T)}Qd1oN float compute(); /*表达式结算器主函数*/
9Ocb7Lxg/eA char *killzero(float result); /*去掉结果后面的0*/ a#vSw+bu^
*m"x` W"W q2^6Xu]
int InitStack(Stack &S)
sB"g ?Ff {},|%j8y u g
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/}Z iW2v!j9_(^y}
    if(S.base==NULL)
0TH Y#g!hn AEw     {|-E,}oz([U'},k;o
        printf("动态分配内存失败!");K A P2YC#e6v zo0q
        return -1;ZD2W.q(k8vrrxOt
    }
X#v+j?rbG     S.top=S.base;,xS ^Y4kMNd5T
    S.size=STACK_SIZE;6I"g Q R l(J1W,S
    return 0;
'b$qn9Z7y W }+R4{0g/^!};yKH
8k^!Wfe3fG8{$WBR
int DestroyStack(Stack &S)2H] Ja"R.~k
{
5^d8u&_ IPp     free(S.base);
)bF(V mP-Aa     return 0;
z&l'],l9z K*v }B)|fA6}6c7ov
;E[#x4@^ Nz5G
int ClearStack(Stack &S)
8Msr&dLq {
uF@J\"X ^2W     S.top=S.base; Xm;_B-vy7C
    return 0;(X}(^a.N!u
}1Ij!OHb,D)P,[Q

D\5E7d-O0y int GetTop(Stack S,SNode &e)
1rU&_U;R)u:~ {
(Pr6h G8W|%E;|jb;c} s     if(S.top==S.base)
?U,Kng:y(@ qh4{/I     {
N7vk*a"bB         printf("栈以为空!");@r'{5M/JFQ8f h
        return -1;9a-k T mJz;XB7x
    }
!rw3E N5tru&X x_ M{     e=*(S.top-1);f&Q%mh1O!a y
    return 0;k"C$j*`J4c4W0o+xQ-l
}
^,l%E^s^
}K@9^&Vv3\:[X int Push(Stack &S,SNode e)4?sC'q @2^;Y2dd*YrI
{.lN.{%si
    if(S.top-S.base>=S.size)n.uxi0T#^
    {0M4VyAR0V2M3i
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4kr,B(Em|         if(S.base==NULL)S;l|"va/E,R
        { EF,FA\
            printf("动态分配内存失败!");
{2bv/AK%{+X             return -1;HP!K1u)}fG6p
        }
j YE;v!i         S.top=S.base+S.size;0a&RAQ!}9[j$^
        S.size+=APPEND_SIZE;
)G5SVmu(O,k     }et$W;o(Fp!mH
    *S.top=e;
*@-X#S9]`u mc     S.top++;I A/V7~'s#_
    return 0;
(dw9q[aG&V.u*U }k9RY{6i*FF*|Z
7m'wU P{{x&i
int Pop(Stack &S,SNode &e) b kgWtD l
{
U;g;I8v+sMR     if(S.top==S.base)
PWY rw(~'N0Y     {
oOVnu*s'V         printf("栈为空!");
!Gjn*@ b*N$px         return -1;
]p0s9L{:[T'J     }
`U{}-L.Xd3LBL5y     e=*(S.top-1);J/B h*i5}kL
    S.top--;
:\YA5p&L}     return 0;:UQ@,jZ4m0VP
}tU{L!M$I cY.K

:B.op:VLCP%w char get_precede(char s,char c)
@(N*MB-aZ {:j[@V9U3IIK5lO
    switch(s)v g#tc jVz*E z
    {O'W5g HqT A _
        case '+':                 
P3^)D2f:hcLV         case '-':
{2^ndC"p,F              if(c=='+'||c=='-'){7WHFQ/w
                 return '>';6|:]U(sf6\*z2sZ)u"Z-F
             else if(c=='*'||c=='/')&g^V fqi
                 return '<';5EM@-D3_Z
             else if(c=='(')
4`&?8Z7m%Q[                  return '<';
s@}~6} bt              else if(c==')')
/WG x p+S$^                  return '>';
*P$E+\ sD4`              else
8HTy;H4HI                  return '>';
aQ B'~-~%S         case '*':!h V/D*nY;luY
        case '/':
"~CxI+z_pJ              if(c=='+'||c=='-')0w@g7UVm L(bt
                 return '>';
_ \)\4Ip q{2b              else if(c=='*'||c=='/')
'^n)LP4`                  return '>';
-lUb-Q8cq]Zx              else if(c=='(')g.~ImZl1E
                 return '<';,kZ/B5@ L
             else if(c==')')
h(R(w`cFy R,w,C                  return '>';
6T:l,zs,Z8hL)WB7@              else
qF T0h|2J3u                  return '>';2X,],Vz3{ Q ]
        case '(':
F^&a-x^              if(c=='+'||c=='-'),s.qi3{S O#NUU
                 return '<';
+WJ+t;Q+TPJ J              else if(c=='*'||c=='/')qQ7Q YAt'WN6d
                 return '<';'L\3u!CH pE+M
             else if(c=='(')?c"i4\ ?jt#d
                 return '<';
Yi8^ Rl%e3k              else if(c==')')c*N2b/~ w$I(M|
                 return '=';
]Om*}!Xr9n              else
;p5o3nKO_(hZ                  return 'E';6v,IOr3z(~%W0As~ f
        case ')': yd[2O;g-L]h;e0m-c
             if(c=='+'||c=='-')n+}:FyHk
                 return '>';
Kz[ r,QX&d              else if(c=='*'||c=='/')
+DV*P}$EA'r                  return '>';
"I&]-F9HE6_G7y              else if(c=='(')
G UoFhvku$w                  return 'E';,F?'F'DV/O)]
             else if(c==')')
yi hx s6H                  return '>';
UU@G$VUP5o f              else
5h @u^aWSy |                  return '>';
P.W(G^U         case '#':
(Mx$cR-T:^ yf              if(c=='+'||c=='-')1a5m-vB-C
                 return '<';jc9J}l7K
             else if(c=='*'||c=='/')
yD,X#GE1s                  return '<';'D j1kD3V:Y(C}
             else if(c=='(')
s A_qP#U|}                  return '<';4r vr$Uxa9H/xj/@
             else if(c==')')5X cTotUhF
                 return 'E';
[WJ:}$\:kl1h3g;qv              else].|)I1e0`(P.dId
                 return '=';FO#e4C{ P!Z
        default:
J*V0C1f5R-G              break;3Xh-S?[x
    }
C{&p&`_FiJ#D     return 0;   
V p6y GG5G*L&_vP }
2H8^ psa5F7B#R #_9^ `z1m QU
int isOpr(char c)
_Y'`2G"Y4@Y k {
G(|,jZ @)`8N3^$ym+~     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/J#C-zV$MR*f9?
        return 0;
0F S0?\F@A     else
d X-a{Kd0Uy$|6U         return 1;E/u l(N5sPS}x0m
}n0{|(P.P7w_KP

p/?YR'EmrH float operate(float x, char opr, float y)
C;ZK_!G5GU {
3_@ ^oX3a%`$Y     float result;
,wfy+T2xFV)f{     switch (opr)
:a9sh:Vh     {X]}U B
        case '+':
nP^`gw$_F              result = x + y;
[(oe,{J9kDP%R7o0L              break;&oU:`4[9n%Y
        case '-':
m0t(r#iPN3t              result = x - y;
+UT x-I0Nh k f-h              break;
^ j-yT$R         case '*':
L,i%Bu$h@l ~ZD              result = x * y;
FL.|Dn?%K*q5E              break;
@s$Yjn.z"be         case '/':
z*~2q~9wV"Wi              if (y == 0)7eW ]Z8_]5p
             {:?:^*^k1S&E!wy+l
                printf("Divided by zero!\n");Z"?| ^!ku\
                return 0;
}(Sa;Y1YXl              }
C{a3o,HI0Q              else*g ^RpMKmM2QD
             {taR5SQ|
                 result = x / y;%E)Vxy)Eh)Y7S
                 break;
E AK)Coep2R              }@n n:G-iy[$B
       default:
$Ot'|2y `G6\(e'?              printf("Bad Input.\n");
a0c Gu5b?0j/x p/q1q              return 0;
Ql_Z+pj(xn"O&Q%X     }w [P9Y"_f
    return result;
}.\`b_&LbeJ }   
#_\KaW m0Ab3g(O
1NH,Ij$IiYG~ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
J g+[l/{ {]oZ0y-T HN
    Stack optr,opnd; Q"RR1KD
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;!fw+|8`2~$V9k4WZ
    char c;(jF5vvHG
    char buf[16];
t { @t3B4b:K     int i=0;
%pqs5X&LP0R+I    
!KkxG S CTpt b     InitStack(optr); /*用于寄存运算符*/
5k-Hd7gb"vDo     InitStack(opnd); /*用于寄存操作数和计算结果*/&W:y3M#{G_
    memset(buf,0,sizeof(buf));H/A@$jA8dV*C
    C G|!a'A8Z
    printf("Enter your expression:");
'r K\NSVg*?         k)EZSP5rw
    opr_in.ch='#';~;DW$@&k4RQ~
    Push(optr,opr_in); /*'#'入栈*/
}Fk?'d     GetTop(optr,opr_top);
BQ^2[:^*Jy.B     c=getchar();fk6g1NpC;u
    while(c!='='||opr_top.ch!='#')
\`/Q@ c%w     {
0a;U6M%{pa[0a9z         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/-C9k$`'f2A1epE4HCIw
        {!ON&sn2k8Xg
            buf[i]=c;
nt9s*N"mAf @&r             i++;}Uz x7B:\ X
            c=getchar();9e?-lp"`RH0wHc&` E
        }Z*O5mO3C
        else /*是运算符*/
)J x `L!T:s         {/Gbi$J!_ Fd"J;r
            buf[i]='\0';
4MqNl{ W vCV3_-k             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/#H1x-z([$Dm5mrL
            { S g r6J6{K
                 opn_in.data=(float)atof(buf);$K+PKX$e$~Hx
                 Push(opnd,opn_in);VE M#|!EWhg
                 printf("opnd入栈:[%f]\n",opn_in.data);4PM}8{ {
                 i=0;l;T7?b)W}w&I
                 memset(buf,0,sizeof(buf));-]J$\#@7h"H
            }
P'c(]4Fe5_`             opr_in.ch=c;o7{*|G#xIr
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
B"Uv\;q             {
t$N cg#t7@3I                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
J'O,]_+@ _                      Push(optr,opr_in);
L'|bJGg$m                      printf("optr入栈:[%c]\n",opr_in.ch);
1PE,GEqQ'Y[ S                      c=getchar();Y{4J2Zi$J)`&ufU&D
                     break;}U#Z1F5SlA
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
$|le6@1Ua'B ?                      Pop(optr,e);MO#fp z!sLF"V
                     printf("optr出栈:去掉括号\n");
}~|ZY$_d;Vm!I/}                      c=getchar();
}Z_a)t6MC!mq                      break;/`q8bB fG.wZ/jR
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
@W:HJ ~0k.M                      Pop(optr,opr_t);
@&k9T svg2h j!x                      printf("optr出栈:[%c]\n",opr_t.ch); K1iR!EC
                     if(Pop(opnd,b)<0)^i8?U(VrQ o:J
                     {
,d{;F]'pZ                          printf("Bad Input!\n");
oP-e){ @ Xa0`m                          fflush(stdin);
"yp SeD$e,Q jbzi                          return -1;*I#}0h+N)T!h;\g srY
                     }
v"_p'k%T Qk1\#g^                      printf("opnd出栈:[%f]\n",b.data);7p4aL|2\9va
                     if(Pop(opnd,a)<0)
7zR6[5oB/?`T-M                      {*K@I Z0k
                         printf("Bad Input!\n");
2} eJ ^2_Y                          fflush(stdin);(l:k-liQO
                         return -1;
6d7j}T'q4[                      }v)w(y9b8fZg
                     printf("opnd出栈:[%f]\n",a.data);^dS.~G(?+@u
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2P!t{kZ:d)o&\z                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/'oP`d9B$U}2N G {
                     printf("结果入栈:[%f]\n",opn_tmp.data);
|bH!~4y\5FY6x\                      break;$f,~9nd[H7P,H
            }l c3lLn
        }
-R zJ5~3b'qn         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                "S5a+m GW
    }
~[Y4r L}J}     GetTop(opnd,opn_tmp);
1h9E&oH;dH9I     DestroyStack(optr);-AOSCX
    DestroyStack(opnd);
1x]uI8z:_3_1\+n     return opn_tmp.data;3o2o;f3\7L
}a E:B7{}#h.i4d
8Z/~1yV{"u6B
char *killzero(char *res,float result)l-c1w)uW6J%J
{iLvf]kz}3\
    int i;
n6|&M0AX Lb
g*H;~,u6Jn     sprintf(res,"%f",result);
?-_L&\ J/P)Wnxq     i=(int)strlen(res)-1;
$z8Gx;O6sR Ri     while(i&&res[i]=='0')L l&VKa
    {c j8Z^(A+?/}
        res[i]='\0';
.n"}4lT7Ycd5P         i--;`Vy};P
    }r#M*U b&h I g
    if(res[i]=='.')
oIY`X7M1[         res[i]='\0';
S+TA)ZT+Wy)Du     return res;f"g1{+tJ)jL YX9{
}xq|~x$fFy

Z!k-tWQf ji int main()
0~d#j:kn%S1zXS1k8N {
;e2_"|Q5g7ZR     char ch;
CL6m/t3Gs[p3wo O     char res[64];
9nZti RT     float result;,T{3uR [0{y`'r^
    while(1)w0?!dxl%p
    {r"Nc$L US^'N x6Cm
        result=compute();)K+x;Uc#y}
        printf("\nThe result is:%s\n",killzero(res,result));QK}.W0Kb_
        printf("Do you want to continue(y/n)?:") ;
2y/C%D"O.EiF         ch=getch();
0Wsk+Bj Y p3~H         putchar(ch);
n]|P V~ R6p         if(ch=='n'||ch=='N')
6oP,^ y,G c             break;
-[pI[]         else
CAl!R/B/Ld?8l*F)R,z B             system("cls");W G f1pZl
    }
x CYpB(T2Be     return 0;T2rE-_ q @6@FT
}[/i][/i][/i][/i][/i][/i]
km/kz;?A@ 'Ea/{1N1D%NBH d Dc
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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