捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
S w So@? 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=WK+F4|H|:ecB
/**************表达式计算器************/D)z"l0rA"f
#include <stdio.h>t)C$eO1B(k y
#include <stdlib.h>
"Pq MHpyxxS #include <string.h>
`R sNI;{ #include <conio.h>
{c&y@1Z)WR2P i1i #include <malloc.h>
J)}UPI
fs:O \$Bb #define STACK_SIZE 100Qq$~e crmK'Y
#define APPEND_SIZE 10~)X%cl5aI?C[J
0W&QR1dIVga
struct SNode{
7yiFNr)L {/O M     float data; /*存放操作数或者计算结果*/
A!B*TJ.nK a%~h;U(a't     char ch; /*存放运算符*/zp8` ]!S
};
4W3zM0E,S8Y pq!B!m&R2y x.\
struct Stack{
[7B]5{ COH     SNode *top;
&sgN(Q_(x     SNode *base;
4{kt$e"X     int size;
1D6x)_y2y!Z*j };
.[u} p5Y
.y,aLu:`La&Tm /*栈操作函数*/7Q[4wb6eK Y
int InitStack(Stack &S); /*创建栈*/
N0Z$LG/[ int DestroyStack(Stack &S); /*销毁栈*/l J9SP YV1H;uq
int ClearStack(Stack &S); /*清空栈*/
bUy1_+G?f int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5T|H2Ogo3o$w int Push(Stack &S,SNode e); /*将结点e压入栈*/
2a,E0v$Hb o*I int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
n*gpM+E \*` RQ0i"fE @X
/*表达式计算器相关函数*/W N;P"K0{*yv fI
char get_precede(char s,char c); /*判断运算符s和c的优先级*//d B1I m,p*P
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
"P-b {j.mi float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
zrh$~ P"RVS:[6[ float compute(); /*表达式结算器主函数*/*Gd)dF.Y5_/E
char *killzero(float result); /*去掉结果后面的0*/ x nO/U%O f'c'T$Fu
,g)vs9y(K{Y
int InitStack(Stack &S)\r ey3P
{
I&thw%E:G%Ig$Q2L     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/DQ](_ ba
    if(S.base==NULL).\C!M L'h T
    {X|3Y\+c v
        printf("动态分配内存失败!");
{*lu"_^A;@V8u z v         return -1;+~)?vD|qwj r
    }
9E*k,V~)wh{0J     S.top=S.base;
&fJ1}/lGL^;mu*C     S.size=STACK_SIZE;
gP7m@"n7Ni6xHP$O     return 0;ZWjG-S0bq:`3x f
}
1PxMOEY
+N-Ee6T#Q0j UQ int DestroyStack(Stack &S)8T,L%WHbaO
{^7tlScN l`S
    free(S.base);
bQu MJ9?]"f'G     return 0;
'Rh\N1Z@-Y }
)?XAW`RBa-n"` 0M'k{r L
int ClearStack(Stack &S)
]i1s'C0]1th)t {G*m0f G%l k!HHI
    S.top=S.base;
M U C.{ ~]yr     return 0;:Rc-n `)ypWt
}2y@k N1@7tH3j%J\:N
:dE.H)M0u)|R/N [-g)a(D
int GetTop(Stack S,SNode &e)
Nw4~?@hO {
x#IR"mQ,_     if(S.top==S.base)
x5G2zy:i9u G X     {%t2D3N c2fhX
        printf("栈以为空!");
c'L:oE2mCc/n         return -1;z{&Hvu
    }z"qU8\!~(n@*i
    e=*(S.top-1);
v"FI;@XY$@q     return 0;
.C _s;Nv j6~C.u }
h(zU-l[Y!n,[9O
O9ow)A!J S'aY int Push(Stack &S,SNode e)(IBuev@'@M6S-c
{
\UM'T6h     if(S.top-S.base>=S.size)Y&X bv1p.[fo7A
    {
+zcS"Hx;lg         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));r n wV5`5@
        if(S.base==NULL)
5ijuT N Px         {5|%?(U%{c bB2Y;sr
            printf("动态分配内存失败!");
U9T+I3mt             return -1;&N,u/d-sc~X
        }
LJ4~2`U[/]         S.top=S.base+S.size; v L M0X8zA)K-[1`
        S.size+=APPEND_SIZE;
,n0nH(o3k     }4ez"?oN;yf!P
    *S.top=e;-K8EA-wb]0Y*LY
    S.top++;'Y3A$cr"vh5o{L
    return 0;#U?c.y7q,T7Yl:Q-R2b:P S
}6tb]"zS
Sa#K&w `,hwm
int Pop(Stack &S,SNode &e)$b,x"}9s aogg3c
{CD:aZ,b'q3H
    if(S.top==S.base)-|cs?|f:goIn
    {
1o#nL'eV LqF         printf("栈为空!");
)|)|w(PT t%V_         return -1;@6oj ~*X\ p4?}p
    }
(H'zF7M!w tJ     e=*(S.top-1);se |H |9mY
    S.top--;
(vuT {*`-o     return 0;
*b'{6Ns p L5T*AK }
bK4rGto)n7vr\p
v Zp+x5h.Nj7YK char get_precede(char s,char c))H0RD e3ZeP
{
3t H9W9b!I/L+e~uh     switch(s)
5c K]@&\D&X4El     {FSw:V-aW
        case '+':                 p8u?_5Y7{'y"_#LW
        case '-':#@+H%h|*h(@#]wQj/X
             if(c=='+'||c=='-'):KUC` {
                 return '>';
cH,k(is&`6]              else if(c=='*'||c=='/')
,g7OO~rp;{-x                  return '<';
`W7W5Z9hx              else if(c=='(').n9E\Z}m0IjO
                 return '<';
aJ3A\&z9Z)oN              else if(c==')')rL AmI0t(M
                 return '>';
W#P^1pq              else
f$b#A3\k do                  return '>';%?r1T4Jdu+[5zo
        case '*':){D8gXaw(y;^7W O
        case '/':&vj%dbnw |
             if(c=='+'||c=='-')
1MJ4Y!h,T                  return '>';FmA8Wb#v$_ {f
             else if(c=='*'||c=='/')
*Oi3@!Yx5T3k                  return '>';_Ql]/@:l8`2U5lPq
             else if(c=='(')_5lyW,F&Y
                 return '<';
u] \;KSPKZT              else if(c==')')
$q7d x.T-g@,S@4D                  return '>';
R I BGaT}9G(g N              else
\J'S[mp1X                  return '>';'v*n#s)Fk8Q,C
        case '(':[7PO[jct3}-E
             if(c=='+'||c=='-')9x%}!X3tB^_!ZI
                 return '<';
Z~1[:c[+F[              else if(c=='*'||c=='/')
4l0} B%|Pv                  return '<';
?L f$L"MKC0}1~              else if(c=='(')
{Pqxk6wb                  return '<';&b4B*_9Ey[B@)B/M
             else if(c==')')
.EV)Mqx+N                  return '=';2@Kc EHw.sa
             elseMA"JR+_*W)L m0Jn
                 return 'E';!q+u8k7kJ8kh8C
        case ')':
g,E;L2]L Wc }f%V              if(c=='+'||c=='-')
iy_8g?B W)l                  return '>';
3Em:v"{SK(E ~T              else if(c=='*'||c=='/')
;c2b:Q"r|n \v1^                  return '>';)?E`8m.SZJI;J(t X
             else if(c=='(')
5^2[k rkzS0[2rg)^                  return 'E';
2g A+[+@#T1O              else if(c==')')A/x/a+|-Dc `
                 return '>';)r:n#lI P g&k9\B
             else3Y r;Y[*R-y
                 return '>';
x7B;M9E7{&r|         case '#':)xvor;w'HE-H8M
             if(c=='+'||c=='-')9O Q8pF{}`?R
                 return '<';2\ pvr$B%d'Y&^MF
             else if(c=='*'||c=='/'):PU1uC+J5l r0N
                 return '<';vxla-jH
             else if(c=='(')
Y4[F2`e!P.Yv^                  return '<';f Ct'qc {0q
             else if(c==')')/u%W,_x{`+W N
                 return 'E';
:K.O,EPp Q/b'ao:X              else.bW [@ DDsq5S
                 return '=';P$D ^7w2m1v:s-Q:X+m
        default:
/JR1qUxQ"Lq#V-v              break;
.W"Z)obP4B,}"E_-V     }0e\P$` K4AT D
    return 0;   
yo?9N-A }5A*s8vd7K;}

6r5M1\#V(d/do9Dt int isOpr(char c)
S [6?l&B {2W;vC-l@6l7J`(?K
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
WHkK`*B;kv%n         return 0;1q;N@&R9NJ4?
    else
+`yQ,`kc.O         return 1;
;Poc7IYrNG(l#O }/Q)n q,Zu0X

7mF9jR(b2L float operate(float x, char opr, float y) vKPFuqJ
{|-y*?(t2B]-e Z P+C y`
    float result;
c7D1L:FE;VO     switch (opr)
4N;u y,eH9yp6\     {LDg(E&bFy]#k
        case '+':
R2H!B;T m U*v              result = x + y;
R ]1Dc0\3? v7G5ke4E| k              break; ]4](O2SRH2E
        case '-':
y3m*eSMW#\.lY              result = x - y; ?V)|@RP5d
             break;UGU/CYL~-D
        case '*': tu9oWN
             result = x * y;`,CgrY O&t
             break;2?7D'_M|~&k+U3[
        case '/':
,jNk'mRq){!['{%f              if (y == 0)
iYy_A_,M+S              {6{i4A'f jy5?j2L:y,P2{
                printf("Divided by zero!\n");
Tah,PDO lJ                 return 0;
y2n{ _+Vr*`              }
.}4}q5]+SO              elseuGI6G6ka e4Tk.\y
             {suR*_2`V
                 result = x / y;
HJ#`&S:HzPoQ                  break;
D4e%kHy              }
_1uO.qo%~L A        default:
JW8E"k}3g{              printf("Bad Input.\n"); &Z!a o?l
             return 0;9}1~^F Z
    } B,rN u"`o6Q
    return result;
W%|)F5^ D?%@ }    g2Y |+Bdf*I;k x

"\q*B.o0_5zG%t float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
(x)z|o)cU&y0p {
E'hp'L^&[     Stack optr,opnd;z'H'Xn0a x
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
g/k#c/p0DkG     char c;!sf6ZsmP*m/PD#N
    char buf[16];"|ZA Aj[9sBQ g
    int i=0;^2AznV.n
    enfr {tW
    InitStack(optr); /*用于寄存运算符*/#lb ~]6j Wn"v
    InitStack(opnd); /*用于寄存操作数和计算结果*/
0|:kou/f@r'`#aH;z*x(N     memset(buf,0,sizeof(buf));5ZU$x] K`!]?
    R5U#X|8e
    printf("Enter your expression:");3y\K.H Tx2hDy.s c
        
*yB3sJW^     opr_in.ch='#';
"M O6\6_3?(@;?zR     Push(optr,opr_in); /*'#'入栈*/5U'd5q6_8K@'qQA'GY ]
    GetTop(optr,opr_top);1f6v#jF*yY
    c=getchar();
X_0vbzA     while(c!='='||opr_top.ch!='#')uz7aZF!@ ~ya
    {5f:?z bO
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/HXn%Ji9Z5j'~7|
        {
c9Xqn:ta             buf[i]=c;!H6O*p;SrI
            i++;
h'mHN\8lJquZ             c=getchar();
j;fQCJpb5U `         }
s W3K \:^!omBd*n         else /*是运算符*/F+p ~8x4T.g#I
        {
ao;@HYK"w/N] E z             buf[i]='\0'; Or[]1j"lFC
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/{L2l Q/b-Ar.Kn
            {-XVIL)Eq%g
                 opn_in.data=(float)atof(buf);
7Ej)nG4Xs0\U-z)o#pE9v                  Push(opnd,opn_in);
eD4aNu;Vm wDq.V7r                  printf("opnd入栈:[%f]\n",opn_in.data);O0tE HCIX9F
                 i=0;
2U J*RNn0[                  memset(buf,0,sizeof(buf));
7bnKYP8y*dyY             }!j#^'Nid
            opr_in.ch=c;1K Y!i9}2H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
L(X?`lW5J             {
D k3og0J C-c/@y                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
iF:[4I"tz.xP                      Push(optr,opr_in);7@*P"h q-\/Y%y
                     printf("optr入栈:[%c]\n",opr_in.ch);
Rs+e3CJ jL U1~                      c=getchar();
*mVMRv3g/^                      break;
%IGR@%rfi                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/] dh/j f^
                     Pop(optr,e);.c'Ye(T7i/YO
                     printf("optr出栈:去掉括号\n");/pj ^SHwH-S ~p
                     c=getchar();_SH@nLCi:xm
                     break;9cz)A x1[%F Yd
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
s}P!A'B7E0A                      Pop(optr,opr_t);
&p/Fk u_ ZR`3_                      printf("optr出栈:[%c]\n",opr_t.ch);
xV+_T'Z&M)c\5C                      if(Pop(opnd,b)<0)
'nnb6Q+BC"fd                      {1sr'E;JPy
                         printf("Bad Input!\n");0Z6`;t|:Jx5pte
                         fflush(stdin);(m } F7ew Q
                         return -1;n-q4erKu0CYx0V
                     }RP??ZV
                     printf("opnd出栈:[%f]\n",b.data);
:? Lq+O1X'a4v                      if(Pop(opnd,a)<0)
,QX!C?A7[*`,H{                      {
~^'BAC                          printf("Bad Input!\n");%C;g4nbHL
                         fflush(stdin);
_oM2Df4w3b Xh R                          return -1;
P3p,VghI                      }
%X Z]w0u;j                      printf("opnd出栈:[%f]\n",a.data);"u ?AH4Lpv,D
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
eRB2`l4g\Q,U1^                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/]n;]OnVw_^0d
                     printf("结果入栈:[%f]\n",opn_tmp.data);
JJ&E*}"R\Mt&w8O$J&T                      break;
eZ/l%B5X }#c[             }z4r7E Qgvg
        }
'k.^2a&JV)?zH-G%g         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                g)EB'M| p
    }
T8y8Al:yz0j     GetTop(opnd,opn_tmp);
)|1\(]oP-i+D }     DestroyStack(optr);
u{@P2b6Nc'D-A,t     DestroyStack(opnd);G2m,}?)WS%e,s7Z$E-T
    return opn_tmp.data;
x'tT/i O7Q\ }
O3|CV*z|1v.A z6N`fipkb2x
char *killzero(char *res,float result)5C(f'f-I8L
{Y3Tvpy^
    int i;
0@C a%N*m4n ~%^4zUPxz
    sprintf(res,"%f",result); }3Z p9_3j*aOs#@
    i=(int)strlen(res)-1;
C}x$m#t3?n     while(i&&res[i]=='0')
8nKI%l6Oc     {"n+I qz;fb]"yn
        res[i]='\0';2a8yV}7Y/i)pD
        i--;
Xj U[!D     }
fq\ny _$T6@     if(res[i]=='.')GQ-B R*M1N$PO
        res[i]='\0';*b2^ Z(V{7c
    return res;6tT? Ys
}
)k ^]5h!t2_
.xj;K(gNfME int main()
8{a1OOh1t8qJ\4T {
^ Y,Np$]ow@     char ch;
"~7f\*~O|BQ;J B     char res[64];
w p;iCu1m)H3_     float result;
)gwG*RCH1L&vi     while(1)8H4Vn'r2_*qIlh1F
    { }I*K` z%m9a
        result=compute();5t4u3S|u6n DK
        printf("\nThe result is:%s\n",killzero(res,result));^oT;Q{:d ~*t/|
        printf("Do you want to continue(y/n)?:") ;7L0q Pw(H*o
        ch=getch();6l4z ~zG2~
        putchar(ch);p%z(P N/\L%O0e%Z
        if(ch=='n'||ch=='N')&M[&{9Z$K} h kK
            break;
2n)TQ1w6[:VU0S3S         else
&T~;w&Cp+~:oFw             system("cls");
!]6[6[)s#] T3n$e*O:a     }
"P3bY;Pb/@J     return 0;
I Mdy;zWc }[/i][/i][/i][/i][/i][/i]Q8gmh#a

n ~A GB4^ U_d2X [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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