捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.;j3P5e MYjk
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
u"[h+l:XbX /**************表达式计算器************/:X b"DO}Y
#include <stdio.h>.BuV Mb
#include <stdlib.h>D.[(L8[ m.I:S8~3u
#include <string.h>J'i G,G:c!DQ
#include <conio.h>5[N0LUe^
#include <malloc.h>
j8Yg&jP0|;r{z R YX/](s1J,Z
#define STACK_SIZE 100
L+XOa ^:v8s1? #define APPEND_SIZE 10
3Q+K`i.HbT#IJ8To ou}n6i [Eu
struct SNode{'GR ~,pv
    float data; /*存放操作数或者计算结果*/X.M(o[a6|@5[
    char ch; /*存放运算符*/9D^~i"eh
}; y(AD0D)OG

B;G l?3C2B)e struct Stack{
*d(F&u%d&[9gJ     SNode *top;
HAh;E.h.h.a     SNode *base;
6g1CH:t6K%NUd     int size;%A t7u(TnXllw3S
};;X Q"^ g&g@/h
8_/j8xh})Q(f
/*栈操作函数*/ S \`lW q#Q
int InitStack(Stack &S); /*创建栈*/
0om/~R2F4F![ to int DestroyStack(Stack &S); /*销毁栈*/
/i;q5xuk int ClearStack(Stack &S); /*清空栈*/$SF8~SEN;iy
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9uPU*}9s;bE
int Push(Stack &S,SNode e); /*将结点e压入栈*/
*e/Y$@&m3V_%R'B:\-e int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
5e4J!jJK.v$h
vX7[Pu-q /*表达式计算器相关函数*/2L)AD'QcR:nR
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
u#zs!k@j int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ {J&A H0@
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
m*{8i.m0z#m#]4e float compute(); /*表达式结算器主函数*/[kp.Zx~@H([!b7d
char *killzero(float result); /*去掉结果后面的0*/ _ l!Cx(As$|*i3h
*z+woGa^
int InitStack(Stack &S)
0I2IlEx9wz {.s j4l"o/_
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
!ml3A \.FI*IqI     if(S.base==NULL)3y*Mo H_\5N3u
    {t\ S9Pv/y5b
        printf("动态分配内存失败!");
zn6|+eKy4^1Z^p         return -1;lLop1r
    }
T E!D(f/P~;Vz     S.top=S.base;} I~uL)S+j
    S.size=STACK_SIZE;X v.O1dP+}'mDW et
    return 0;
r l$rEp1|(R }
^}H(iu
3C(KF+Q3\)X p int DestroyStack(Stack &S))WZJ*Rd cH-D
{
uY9F1jM1b     free(S.base);
$bT[/^:x1YE     return 0;3K^(_ t%ZFs X cu
}\SE"XYNq I;r
:c6b6uW W3W,|
int ClearStack(Stack &S)
q_WAu3@mX {.t N QHOS.ach l C
    S.top=S.base;
:fr/uQL     return 0;,T;J4p8{"~!r;x!n K5L(e
}
9Q9U*\#~B+j(g m@s\4QkAP
int GetTop(Stack S,SNode &e)gD7jD7h Kt.SV
{
Y*JQHh!S     if(S.top==S.base)
R;g"~(O-mZ E     {n:]D-pW{ W
        printf("栈以为空!");
sm~[-l9VN7\\3K         return -1;qS%|IK^
    }
A2PBK A8U*}b~     e=*(S.top-1);'J|B-oq$[Ee
    return 0;
*M7Wa&H$d }
_ L,PA7m*UBp M
%^&A(wqO int Push(Stack &S,SNode e)
Vk/~ K2QTd:O~ nM {
l o8u3Sl%Z.c \1o     if(S.top-S.base>=S.size)#u.IKg'R1BC
    {
P:N1jZ j$f8v         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));e9twGU:^
        if(S.base==NULL)
c0|R\@*]{%u3Q         { C:Y#~&E*wh
            printf("动态分配内存失败!");sUp0b0Ce"K
            return -1;
X%Ma5L8nZ;RR6S         }
:` K~9nC(\8c'R         S.top=S.base+S.size;h&TL3u9[+U
        S.size+=APPEND_SIZE;
@ p g$SS&A%vQ     } P}3yFb+q
    *S.top=e;
rW+xY{,A     S.top++;
ma5^ N#m7h     return 0;aB0hib
}e+i U VY.~3o1g6i%I

7K.`7ZwV6i#B k int Pop(Stack &S,SNode &e))SX!w!e5`}!Nj,G
{
3q*y$~l:Y5fs     if(S.top==S.base)eVHd2y
    {
zhr_e'F/lpVV         printf("栈为空!");+v3eL3?&ML2P3w@
        return -1;
@GQlA }Zif%|T     }
zR`Av#];bS.|     e=*(S.top-1);h\ e,Al#R
    S.top--;
'N{8a VB     return 0;
"w2B T:LX@#P3zLXk }G v8|7p*V P^

L r%A&dv&Rk,H9y char get_precede(char s,char c)
hAE8k QkPa {J3e m!h2g
    switch(s)
j G6H8t#T+@     {T!X m0s8Re h
        case '+':                 (r&]Uz%iY;oe
        case '-':
Doc6T E+N])\m              if(c=='+'||c=='-')
${I'B i L%nm3bG                  return '>';
D i6X6T#P              else if(c=='*'||c=='/')d;MT&h1ii m'G
                 return '<';
1]/S!]c1p7g,HH              else if(c=='(')"qM2h'tx
                 return '<';dl-xK0B'M
             else if(c==')')dh$lx[*Zm8@~
                 return '>';m%I7K/Aq s
             else
.U`4C,f? ?4n_H9Xw                  return '>';
]3D@-M6M5gQWd         case '*':
'd9b[ONA@         case '/':+} Amd;w
             if(c=='+'||c=='-')
!`{hrw`F                  return '>';9Og"d3nq:F
             else if(c=='*'||c=='/')Ft1I+?@o|
                 return '>';2\ ZtWqU#K
             else if(c=='(') MqJ)ES H FX
                 return '<';_8l ^1t+Iq
             else if(c==')')
`M%Pp![|                  return '>';^ |Wg{,P
             else
C*p,y/l)kQt g F                  return '>';O{b)g]
        case '(':O)Z*aO]P
             if(c=='+'||c=='-')
rc5E D@ K,j#jii                  return '<';u(S [$Xt$v
             else if(c=='*'||c=='/')
+?7VI b'}C                  return '<';#tX.}#V/QR"U
             else if(c=='(')$mb'k qi:nA
                 return '<';`oE!H4]6Y ZI
             else if(c==')')h } zl-U#Q kG
                 return '=';+NO[5D1S[E7AM
             elseOX8tF`^ i
                 return 'E';
7`+Y eV#CT~[0Kz         case ')':#cL4eIK'\ LL8t9J
             if(c=='+'||c=='-')2x*R^6Gw~%h,Z
                 return '>';
t(md2Y:fka              else if(c=='*'||c=='/')
u']+|-|@8a:[9p"m                  return '>';@S Ue4}~&n1B
             else if(c=='(')
Yfum5K+E~oC                  return 'E';
.c#{[5qH8H              else if(c==')')
x y2_'q/O(B                  return '>';6cX3aT'knyN
             else
e:t!P&oj"Ut,?                  return '>';-?&K`+l {3YI9_t
        case '#':{W&g,f+| ` a-D'j G
             if(c=='+'||c=='-')
U-Ls5J,D                  return '<';[2vmY,Q H
             else if(c=='*'||c=='/')
ZE0h*S.i4z-m                  return '<';JE6`"z%c*dI
             else if(c=='(')j C9y }a n \
                 return '<';
9HbGi-gwCyS              else if(c==')')HY9uB T.oh y
                 return 'E';Ttnq(`;Gh0m G
             else/A{A2aT;z&^ G)dG
                 return '=';
(N{"d]PYbY#B2]         default:
(bp)}V}*TV[ h;sZ              break;!`)U*u2pZ'~5~1E1E
    }a$w6z x s3U%q.F$Op\
    return 0;   
!z Yb&Lui }
@WjA"\p9r p$hz A#v~pV}
int isOpr(char c)
GW.U.K*\` {
n&XNJ4gB,s!a     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
['q.g7sA D'b"y(N         return 0;{%QB;lt {F.}
    else
N'W @q-v         return 1;H&w `[)`+y-a,J
}
zy A B/Tl0_,h*W S4FH/N/im xGD
float operate(float x, char opr, float y);I5[~7A$g:n}g
{5}n~)d }c9d
    float result;-E_~:vk4l
    switch (opr)Ll,J8w8TKN.lP
    {!Sd%h&s{p
        case '+':
b*KY+b,|-Ao2X              result = x + y;%c7L3M}"cp8zB KH}*P
             break;'P|A'Ae{t'G
        case '-': B9yjA5W(d
             result = x - y;
'},} I+a x!]6E              break;/B(s Q(h2Z(zD
        case '*':
Pk{+oL*Kl?              result = x * y;l8_ t1T*j @v6b!O;t
             break; Up"TM5b[q!y
        case '/':
hssMG6wf;a              if (y == 0)i5a*u"e(t-h
             {
4Je\&\*m%S4]                 printf("Divided by zero!\n");
lH8cW$U\ @                 return 0;
5[8}"r l&i#S%_              }\9jz#O!gLc
             elseg'Ik9O;Af7rs]
             {yW;k ~ Ut0w R} P
                 result = x / y;9AKf1N(e9E f
                 break;F6C/T%T;y9V |
             }
`KN$R*? _z s        default: -t`eS eu
             printf("Bad Input.\n");
"BG-S/xWk,S              return 0;
._v7SwVR     }1af&|i5H0~"F
    return result;_5|9s#Q w.`z/rf
}   
l9v;{%n0w)} t!l}
[fb~n uCn float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/s-h%B3RN4c
{,R |;aS I~p2_P
    Stack optr,opnd;
^L!B)Ut     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;,cd3m9v f1m
    char c;,B{ B9NZ"z(^n
    char buf[16];
qH;g.k2lg1yw     int i=0;)BFF4C2c9@;d'^%?W
    E? ]L TlZ:O
    InitStack(optr); /*用于寄存运算符*/
)d3b.Q,]rTg     InitStack(opnd); /*用于寄存操作数和计算结果*/;@J(\%Hf zz
    memset(buf,0,sizeof(buf));@1z%?m,jB
    $x-Xo4?kP
    printf("Enter your expression:");t#W.{%n*EW8\,v
        'Vu#Hn.G~
    opr_in.ch='#';D/@5i l m-]5p;T
    Push(optr,opr_in); /*'#'入栈*/ X7L9Z:] bwO
    GetTop(optr,opr_top);
~+|2[4@OyM!n&V     c=getchar(); G qC!M+c;A
    while(c!='='||opr_top.ch!='#')
C4Ve.d1yXI     {
5` ww!Vxt/\         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ r+`q F*dN1cJA T4b I
        {
cY4B u;`z,RHx             buf[i]=c;
o)HR7Yrv'qVK0m             i++;
b;Psd(Ik Q']|[             c=getchar();&I T(RN qS[wP(t
        }
ua @!X.p!a         else /*是运算符*/-f$c)B$I Wpc:EvG
        { r_~O"x
            buf[i]='\0';c+m.K$h rd3|o?
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2oM3[t&Y,T^$x|
            {
&Mf0}E(J]7H2fX                  opn_in.data=(float)atof(buf);Z5C'_Hc d5J'EJ
                 Push(opnd,opn_in);!Yizj/A{]s
                 printf("opnd入栈:[%f]\n",opn_in.data);
H0U7Z%J^4@                  i=0;
7E-VNNG[4\i C0]                  memset(buf,0,sizeof(buf));,}4a#hUCE1|Ot
            }
`Oh%X-cJ vG~             opr_in.ch=c;:G0~,R&_1U wP5h#R![
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/H2H!f pk#D`
            {
W8q _ I$u$]I@                 case '<': /*优先级小于栈顶结点,则运算符入栈*/*?}0M0M ^ i,Gc JB
                     Push(optr,opr_in);
W ["{H Ut                      printf("optr入栈:[%c]\n",opr_in.ch);
1i:}5[ E'b]2y0B                      c=getchar();
|$|#U"O0`-o'a E                      break;
bI+N)G*Wp7yU                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
-N1Zn M#V`5V                      Pop(optr,e);|6o,CU4r"F ?
                     printf("optr出栈:去掉括号\n");
5{l s+g&a [uTT                      c=getchar();
[!yz E TRK3j                      break;-x1PK4p1AU-s
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/+D`:[6EQd*J!y
                     Pop(optr,opr_t); O_PE4LW!OG
                     printf("optr出栈:[%c]\n",opr_t.ch);(`Z*z8GR-nH p
                     if(Pop(opnd,b)<0)\Q'g-}5\(Ye@H:A
                     {
[7G,B @-n m                          printf("Bad Input!\n");h n/_\0W[
                         fflush(stdin);*q9C_!n:d7?
                         return -1;
|3]#m}?T u M                      }
J8XK;| v2EC                      printf("opnd出栈:[%f]\n",b.data);#K?6y~X6qwv
                     if(Pop(opnd,a)<0).n Cb8n\l
                     {
i1^nek)`7w3s+A                          printf("Bad Input!\n");B$[ E9Y:cG N~0N
                         fflush(stdin);
f7tjI~6hM A                          return -1;
D }(Y2[R Zn                      },ucc9rg
                     printf("opnd出栈:[%f]\n",a.data);
%X,rZ{ R.z                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Z{9\r8^q6k                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
Z2`S]cpK;I                      printf("结果入栈:[%f]\n",opn_tmp.data); Z2|%Wis$p8v4oh|
                     break;0w3gO e z]t
            }*]$E\v8RF w
        }yITP.v*C)m
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:m.`C5df%o9_;i     }8yq|M5J _+Zi*j
    GetTop(opnd,opn_tmp);Z/lJv4z^"W
    DestroyStack(optr);
"RF9? G_     DestroyStack(opnd);
d,?XK,o]4S Y W6T     return opn_tmp.data;Y9X Jy5V9n*o
}8pAm LG!ynZ ^p
,A/_:k\ e*?,z1q!q
char *killzero(char *res,float result)
4IiW t+O.d {#]9Y4{w%`(J
    int i;'e/yC8P ~$_/k&F }L9i
aHm8|5c
    sprintf(res,"%f",result);
K6Qj.HrN;X     i=(int)strlen(res)-1;
bQ)])fK c7wSF     while(i&&res[i]=='0')
k6c Y5OJJ aI     {
2K%J!t'?$~0t1E8|:j         res[i]='\0';:i^gpD CP
        i--;jRa}mMl'Q
    }
(uZ-Rb1HF ub     if(res[i]=='.')Hx }w0r7s
        res[i]='\0';
9M ex7Lksjpa     return res;
q0xV\K8ef }"t@uTCM"|

)PZ$WL]E'_o int main()$n s8T"g%e4cS
{
9f(}!cujso8Z     char ch;
:h7OV:N;o i [ f     char res[64];
B`,B HBnz     float result;
G0mJ(O1U9^     while(1) P xlO3| R
    {+C8D_q8]7`,r9?
        result=compute();![ g~`4{4C3k:}
        printf("\nThe result is:%s\n",killzero(res,result));E!s"Ei5^hl
        printf("Do you want to continue(y/n)?:") ; B }'NBGQ#N!j;V
        ch=getch();3AU0i(~2|J
        putchar(ch);
!GLGTD+J         if(ch=='n'||ch=='N').q1u)N~xN'?
            break;:~4r Z5M)R+C`
        else
,x8J1_i B8p-U6f             system("cls");Dn~w/R
    }$aC#O4B0Q.U5|W?
    return 0;*IGe_v,\'L'C
}[/i][/i][/i][/i][/i][/i]
2e.B8W0X(Hi#JW g7uK/G`#V-c-h@
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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