捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5@:|/P6aMT)K%g[pU5}{ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=~-f9P,m P J7i
/**************表达式计算器************/5XA@!I w
#include <stdio.h>g"V'S i vUd+I
#include <stdlib.h>
/h _CK$iet #include <string.h>
O*i~Z|4Q P3uR;F #include <conio.h>f3r6tSEz
#include <malloc.h>
3A;N e2mh #J*Ha c TS2t
#define STACK_SIZE 100c5z2jV'`2O?
#define APPEND_SIZE 10^*V*{S.n6kg [)D
"_ Km2Ae0[X
struct SNode{"D&`rj:a"p-g;\-\{
    float data; /*存放操作数或者计算结果*/
8WT7F rj%NWUe     char ch; /*存放运算符*/
"V3\0E.i(R L&N.W,_ };
JPm5R/B Dq$` V!i2L
struct Stack{R/z-Ra h3sK`
    SNode *top; w+?g ^4G*KM6pW%R yeE
    SNode *base;
xR3@1e4w     int size; Wh'n&y#?%aL
};
D me? R!CY :[$P3d4G.c
/*栈操作函数*/ dA'dMd#MD
int InitStack(Stack &S); /*创建栈*/
6{7d8JZ'k4}*nZ int DestroyStack(Stack &S); /*销毁栈*/
$wZ*f1n5I3Al ^)]L int ClearStack(Stack &S); /*清空栈*/
2r!K7{AU(D!NJ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4M+n d v;q
int Push(Stack &S,SNode e); /*将结点e压入栈*/
H(|y/oj$? int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
}(]9vtUZ/U .?q"b{TD7O
/*表达式计算器相关函数*/hg,_#~o H'h'C;uB%{
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ xj G ]qQ x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ S5?3QP;ywD?3LL9r
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
j*PG.h3E4w1z float compute(); /*表达式结算器主函数*/r r e4Y'E)Y
char *killzero(float result); /*去掉结果后面的0*/
EpU4M8z x efj~y
&n:A r&J a"d)M'w:u int InitStack(Stack &S)
N Ttnyr8iQ7^ {b9}6C5lx2yr
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
l Fg-[ k5Hre5X6@     if(S.base==NULL)
X_3c1Y V"h     {
Uy8o]9~:lYi         printf("动态分配内存失败!");
Nob$IM;@6G7_bM Y         return -1;
*e.~X KB/C     }
9xM @+on ku     S.top=S.base;
'p7UW$L1x$m     S.size=STACK_SIZE;
;X o+["cfJ_     return 0;
*~Cn L[7fpYb }G+fN XX9Jq J4N
3T"P;y _2k4Ta
int DestroyStack(Stack &S)/u(T6~5|d!fb
{I*ZM"b*ns0\x
    free(S.base);
.q,V8Y-w0b1K H     return 0;
K@ \-z},vG }fc2V j:J,bS
b/mPq ~rgw
int ClearStack(Stack &S)["r?KON/Q-jv
{.|/[h%jT$k'c$~@m]y
    S.top=S.base;
wD#[C(_     return 0;
sHmRSx+k} } i6UCs Xjf M D
g;h ec^pWP aR
int GetTop(Stack S,SNode &e)
Ws0nXLV J3c~ {
e WB:Xb,~.g H'fv     if(S.top==S.base)5wAP0fZKA:j@%Y"b&Z
    {
~#dc&tcOd4F XWs nZ         printf("栈以为空!");0]$g \ dL&GD|&P
        return -1;'{ T {r$@%|
    }
/~3c5\f;b$kX V     e=*(S.top-1); c\BR:I$iC
    return 0;5U&d.J;Ow3}x(ZQ
}
;|Q#GV:Nvu
-O[R,R~ int Push(Stack &S,SNode e)dO(_cm Q
{ys,Vc Z0W*b*E'W
    if(S.top-S.base>=S.size)*KP^~!}.cxC0e0v?
    {w UM,y K4e o f{
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));)r7r3NkmMW q(o'K
        if(S.base==NULL)h9[&JT t%W*Z b
        {a-FdQFs
            printf("动态分配内存失败!");
5p2b0B*y"J%^0_^             return -1;L&h @BEA$}O_ q
        }
1rxW4B"y"Mysg         S.top=S.base+S.size;
*A D my?H}         S.size+=APPEND_SIZE;
t1vnC-P1} y{     }X.e+uT_
    *S.top=e;
6PD#J8rr5I/n     S.top++;!w*u fY;`;dW m%X9i
    return 0;
7oK'v0O2^E }
7N$V z!A5\"|M eX
} c wX+K,{,jG int Pop(Stack &S,SNode &e)
X @%{\*d1m%L+wF {:i:E{#e2U8s9~ ?.@y
    if(S.top==S.base)]0}&J;wI"P
    {7pw.Z7F["I8u v3o
        printf("栈为空!");
cUh`TS+h-{&Au         return -1;$M*k Y6LX
    } V1Fc7SYQ
    e=*(S.top-1);~1R4n!|U0x%G
    S.top--;
/i(B k-D J:JF5E     return 0;
5@(x _Q@qu }$i8P@ t xc'})r9B,m {,W
J#T Pp(ijb/S
char get_precede(char s,char c)
"[r'[UC!Qn'ZR {1|%Df1Aj
    switch(s)
$W;M*r Wq~` K`Z     {TP%]M~8`1s8cX/q
        case '+':                 
`8[|IoJ         case '-':2CHu R4ZWy Q
             if(c=='+'||c=='-')mR5j#G$TpXA
                 return '>';| v|"C,` Xi
             else if(c=='*'||c=='/')oz+r3P7Ti/i%r-tF
                 return '<';} YrD/XE
             else if(c=='(')
a*wsB\I                  return '<';
1m2o7c7?,x6ry              else if(c==')')
0^ | {OX"h!^hn                  return '>';
8M1?3Bn-Ux$Z:yP              else 7CQ b6TK9P
                 return '>';
:PmT\ {%] ET         case '*': y1P:E}0v!k
        case '/': CH7pR;gj
             if(c=='+'||c=='-')3O Yx;Hb;Sq(h
                 return '>';
8F*MX1B8U?%aP              else if(c=='*'||c=='/');h0slb-T7l
                 return '>';#r`x&H/},{%[*h
             else if(c=='(')
:T5gB dVx                  return '<';
:Ph0?i6hB#i0]e              else if(c==')')mfE7^6R6E#U p
                 return '>';%Xzp-wX!iI
             else
f_1w {t5U                  return '>';-ax7`m"n1Sh:W(R
        case '(':z [6Rj b)[fH]
             if(c=='+'||c=='-')
-l4cz)v[|                  return '<';O+a}HRB+i
             else if(c=='*'||c=='/')%O QH!|;P"sv
                 return '<';;e"O,ZjS:{s
             else if(c=='(')Qc0y2[1Z7^%IY#?
                 return '<'; ||\P#f6e
             else if(c==')')
k-X9`8Y*O                  return '=';
9t-q4c*};Y v"NUy              else.\+?6q&v9wgNSFl
                 return 'E';
([*sM@4~)[Ygt S         case ')': N@6UJ;y+LG7v dHB
             if(c=='+'||c=='-')2Hf|!jL#p,o.~
                 return '>';
2}p7xz,f? \?              else if(c=='*'||c=='/')
wj NZH |7D J{ UA                  return '>'; L uSs+u*h`
             else if(c=='(')'a#R ]y3jQcx
                 return 'E';k!pv2l(pP O
             else if(c==')') KqJJS^^ x
                 return '>';
:D-biV ^              else
:QnH~qS                  return '>';
ea^Md         case '#':
8[W/S*D*i\Y AB              if(c=='+'||c=='-')0i1l RhAe
                 return '<';
}} U\ m'vL ~-B.S-Hx              else if(c=='*'||c=='/')4YvXFf#_K9f
                 return '<';dh,z7\ nC
             else if(c=='(')4W9G ?z!Q-m.P
                 return '<';7bgkuH ZX3[F:A
             else if(c==')')R0o*n T,K"u3["}O3T:@
                 return 'E';G A1~S+h X-x
             else.z2_4a)sA lZ5L
                 return '=';~-D.y#B%|Z
        default:
)T:Vj&R!{A#^)}Bb              break;.f.r Y,?a2dw%x~
    }
&m9M@kK*Q3S'k B     return 0;    +],~F7]&F%ls _5c
}
Q;N K.oaj8^ t;?!xw8hq?6Wl3p2@
int isOpr(char c)
b8b-?MF%k}[ {f't8U}+@0bm/w/j)J&P8N
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')t ^*T+F pG MCxf
        return 0;
J/O3t*o)o!X\9hp~     else
atN"Z-C_~n"X         return 1;'I\T;p;dwcOkE
}
"e }&w y`
(e.GYM|MKi$B float operate(float x, char opr, float y)r_J,P7o)C
{2{;ioN0D9bp+i
    float result;)^#M&}8aFp j+W
    switch (opr)
RuX+H5C4k|,rO     {
U8@;Fb"]&Uy~         case '+':
4[ m t t [K)X              result = x + y;
~t0g2U&O3a              break;.ii`f.f jJw
        case '-':
uz"CWg0h^0s              result = x - y;N.RZ^m;R.G8VL
             break;
`a5E#Pj6e6[ji&QC+B&v0F         case '*':
u:Z-t(B r1yMB/kb              result = x * y;9aR5B%Y oV2NN3U
             break;,{J/\^[aQu0gQ
        case '/': "T)Itt eX
             if (y == 0)5^4d5ZE5nec:mY/Y
             {
;r|DWrp7\LAT                 printf("Divided by zero!\n");r @Qb2U wK
                return 0;8b'|u j&G!N q
             }-z ~u#?(|6B-t:Z
             else L"T4p9]v/N!H:g6x
             {.mm;m&gxc^%B*_ L Rqv
                 result = x / y;t,D C!Fw tJ Y
                 break;9} u3l IH7[8PE I
             }
G1c B,o%nr*D$C0PD        default:
-Mv yZe nb              printf("Bad Input.\n");
!Ge Y1j,X1Ll              return 0;-V*Zo:`$I
    }D'tcH%z
    return result;
,b\ A`!w K }    |DFzF,C-x
3j5Jd"p'P$e6AhJ
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
~b#K,Q:Rej0a"h {[(iG2? U$QI
    Stack optr,opnd; Gk8ty%?7I]ap
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
2t\@7lLo;?;Ps     char c;;w[(h+m,[
    char buf[16];
{ I&f"B,q,Zuo     int i=0;
svjz+v ~    
w+y1k&E'^:`H"N`     InitStack(optr); /*用于寄存运算符*/Pv2_}.uDh*k*f D,K
    InitStack(opnd); /*用于寄存操作数和计算结果*/
?+k4jr$u/T3T-}.P     memset(buf,0,sizeof(buf));
l {] {3|/u wU    
rz5wGl-n_@     printf("Enter your expression:");#xI|r"~M
        UhRH3YHx/g
    opr_in.ch='#';
$D6H~ceQ!S2|"A     Push(optr,opr_in); /*'#'入栈*/'Km&t6x:V]F
    GetTop(optr,opr_top);
+D4q/b1?o8{ a     c=getchar();
s&~[[P/B     while(c!='='||opr_top.ch!='#')9g/u2r#BH|.N
    {
4y"?C Yw         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/R~3C e-Z|
        {HT%{*N H)@i
            buf[i]=c;
t?x,mg             i++; n{:g-j4x!F s
            c=getchar();A6k"zxh
        }
)K irp*^XD         else /*是运算符*/
9qZt)g1_&K         {"dB#p:r"UJ
            buf[i]='\0';
TTz+hP_'z9G sKN             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7Sx b0YP!i
            {
q.PMC'VE.w ps M                  opn_in.data=(float)atof(buf);
/A#et8BWE                  Push(opnd,opn_in);
(Uh+n"M'a | z%\                  printf("opnd入栈:[%f]\n",opn_in.data);
kqh JD}o                  i=0;
(O5b/fRsBSq{'F/MN                  memset(buf,0,sizeof(buf));
E!@Q.Q~             })X;P[7e jC `b
            opr_in.ch=c;
7h"i)z6EMt oIY u             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/'iD{ra#t[*d
            {
lq;E2fjl                 case '<': /*优先级小于栈顶结点,则运算符入栈*/-I!qC}X|
                     Push(optr,opr_in);N1~|.sp J
                     printf("optr入栈:[%c]\n",opr_in.ch);Fm7pM xb/s
                     c=getchar();
DE g~8c6y                      break;
!_-e*V$J%D e                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ } r9Tp i-N_"h
                     Pop(optr,e);j:r(GWjJ-z DT
                     printf("optr出栈:去掉括号\n");Ehw"o5T;F!LS?
                     c=getchar();uC5@"^x-CT/X
                     break;M;V/zr2h1kX
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
-u3HR3v:wa7n}                      Pop(optr,opr_t);
2E0aVyv)y e"A$F                      printf("optr出栈:[%c]\n",opr_t.ch);
{$?W lq4m8t,P}                      if(Pop(opnd,b)<0)
} W&r*Y"T                      {(`p m~6l#Q y
                         printf("Bad Input!\n");
q(s(wzkFf$]+[x                          fflush(stdin);
/C w`(er4Mn:^                          return -1;
%TRp.]!@W$L                      }
.q0Vi%x E+M                      printf("opnd出栈:[%f]\n",b.data);
'FS%}E3C#I{7~K                      if(Pop(opnd,a)<0)%gS/hc_c@S
                     {N]tw*S!s6f
                         printf("Bad Input!\n");
a/O9C.X egwi.E0G                          fflush(stdin);
4g9P2|;b6xjdS                          return -1;F&d;Dg e&Q@L e#H
                     }
!Ta-p-`1u                      printf("opnd出栈:[%f]\n",a.data);
L%D)@PN,c                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/%Y6I#_a Z XO/[zM8Y8G~
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0XJ]4h+@D2ke                      printf("结果入栈:[%f]\n",opn_tmp.data);
4|T+Fg.g-e"h ].S#N                      break;%maQ#QR8a jW'\2|
            }9~A6jt~_|
        }0I m K%_[[/H`S
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                I#QKaX$r'nj F ob#e%V
    }4{,`8~ L0x qM
    GetTop(opnd,opn_tmp);5].e B!Goi
    DestroyStack(optr);f k{3l8L5T(J2w
    DestroyStack(opnd);
@"D{Yer     return opn_tmp.data;] sq9yV'o(L
}
QT:r}&C@.hX2@ Z
K0?)p'B cUu char *killzero(char *res,float result)
Z\G"Q7a]}#y s"@ ? {
N$N0WK*tF+T*O Ru     int i;7Y%cora mJKG

Oe"iGof/jxy     sprintf(res,"%f",result);
8Jqr2eZ5u*^     i=(int)strlen(res)-1;
T"a)g(ZV6?4R.O     while(i&&res[i]=='0')e/I;c{ w Vno ja
    {
6dP jOFWKp         res[i]='\0';
V*f)m!~'w_8_         i--;
5V(YoYZ/vXA     }
Pl [ Z|I1N X;{'B     if(res[i]=='.')
8Y!j(p3_1b         res[i]='\0';
0ah|V7]}pN5}     return res;
~u}jc4? }
}W)wsx5@4K3Mh-c)z :y6]7v4VsiG1pt%|K"@
int main()m y0]vC x RP p
{M`6VI f)~ ]
    char ch;n:M@F7\
    char res[64];*~+||;m2}?z
    float result;5h;Ej6oe;\s/d(HO
    while(1)M;a7fE z;fZ~
    {%MP;E^+v!p T&C/s
        result=compute(); i)@L } N*WC[,o#~
        printf("\nThe result is:%s\n",killzero(res,result));
;`6G ~9W9a'W7@U%q2V         printf("Do you want to continue(y/n)?:") ;
n t&ot|Z3S         ch=getch();,i6f jD A\(|
        putchar(ch);-y)? cvm7k)n
        if(ch=='n'||ch=='N')A+W-zX0C5I(O.q
            break;H ^FY;U$zD_?
        else
H+hk hj,@k             system("cls");
+pm,t"F&vz O*m     } g;jQ*^r;D Aq
    return 0;N!g"_f5u
}[/i][/i][/i][/i][/i][/i]d&LT P7~'dbs@

Xl:g,@RQ? [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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