捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.C$t b}*H!t
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
NVZ,o6b /**************表达式计算器************/
.T,ju^2e!v)h@ #include <stdio.h>
"k4e%j2}%yWN0^ #include <stdlib.h>
*]uxg Z4{^Wa #include <string.h>
5A!a)w:^gO0s #include <conio.h>,w:|#b4dM
#include <malloc.h>'u)s(rnfv5Te9pC

m7{ K_-oh5U #define STACK_SIZE 100
gV%g7]!F fq #define APPEND_SIZE 10!c E)a~2J
H0k/Ft$]0\k0}
struct SNode{
xJMXN+b c)z?:M(m     float data; /*存放操作数或者计算结果*/a lg$WT1VT
    char ch; /*存放运算符*/
@k I+M4M"m^ };@'`x,|%k.W
(w(h\ cMoy8s9^t
struct Stack{
zD8f\'w#@b1L     SNode *top;
C4@!p ?^ r~     SNode *base;nn)z0W_'qh
    int size; Zm;G"| P;`
}; V6b%A0|/X
GPk+o,qq#h~p
/*栈操作函数*/
:eo/U6V1u1_/nn int InitStack(Stack &S); /*创建栈*/+R!C+v e&j]A]
int DestroyStack(Stack &S); /*销毁栈*/
n|M,}y+e int ClearStack(Stack &S); /*清空栈*/
4`V9p/{&_%i int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
e:\/Yf;P!AP{l int Push(Stack &S,SNode e); /*将结点e压入栈*/B#g'hiu4g7@hJ
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/(nT(R8o v0_ X4{
Jw ~v.~*im;F
/*表达式计算器相关函数*/
rOxT9l"I Iq char get_precede(char s,char c); /*判断运算符s和c的优先级*/
BY H"D0N"GF int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/'d(w*wXom
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/\3A;?WkM!p'?[
float compute(); /*表达式结算器主函数*/
-[/ACWV#Z char *killzero(float result); /*去掉结果后面的0*/
)o*bbwr,u
z^o:P n9~*B int InitStack(Stack &S)H-PJsi5Xf7w9[]
{
s%J!]?(e     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
r/{-d,o9p4b {'n*VD     if(S.base==NULL)z'X9J)i[
    {Hf2z)Q6tn)YAj
        printf("动态分配内存失败!");cI? _#dkH
        return -1;!y#r^]3`C
    }2Kf Ko0t8Ep
    S.top=S.base;bl N6j5b$dZ7u z
    S.size=STACK_SIZE;`5g-d&sXwA
    return 0;
#SM&H6P [+ir2b }ke)g hh4HH

gP8\?j int DestroyStack(Stack &S)2gx XeO(v(g pU;d/}
{
2|-? cNn     free(S.base);:}@pK1^#W&Av
    return 0;
/tsl{*T;J }5vHflfmG8c

^0a#LQ @I t8qI1lk int ClearStack(Stack &S)
6] `N KMa+p cgv {
s|"O_,L+{     S.top=S.base;E[(^*s rs
    return 0;#l c"sN4{[9H
}'J\_6vf
!t qZU4|hI
int GetTop(Stack S,SNode &e)
7@ i%F,z/o)];F&E {
4Q m)~bC8d:y?EnE     if(S.top==S.base)
D1ul nHp'U     {
Q:eFuo6yq,j         printf("栈以为空!");
V2Yu8F4_1g:kc9Q         return -1;W/r vD5N d
    }
;md&\%N%a+@&I     e=*(S.top-1);
:q2BV,N b$j#u     return 0;
v~D0?f*Z }0i)^s*wzp

-m4\ T;f0HeVf int Push(Stack &S,SNode e)
!o&hH$A P?3g {a}.v)HU4d[p
    if(S.top-S.base>=S.size)z(de(ui e7p5P
    {
N3{mPnM:x hB[}         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
D DX~ z#C4?5R         if(S.base==NULL)n i l-?U_BD*M9q`
        {
4N~9xY }b             printf("动态分配内存失败!");)}8lu{kZ0z
            return -1;
6Ke4?)I9~^Q{;{         }
E,v?5@j         S.top=S.base+S.size;
V4l;jZJa-E&u*^2c         S.size+=APPEND_SIZE;
5F l'R)WI oS:^     }
&^G:KYfL%H     *S.top=e;
op3hEf*bSj     S.top++;"z%Gb`A4L7rNJ7\
    return 0;
o{1}wW} S#u*q${ }H(VKy%q:GD7N

]+u%r'Ow!j'U3l int Pop(Stack &S,SNode &e)
/?[4~iK(p7BG {
p)ls)wuY~Q?     if(S.top==S.base)
UDw _o     {
;e%b\Vgt         printf("栈为空!");
5e/Eg {)S!d&y/P         return -1;
A-tF%l@$},g     }
n/nO#uZWS9k     e=*(S.top-1); ?;\ q ~0],X(G1L
    S.top--;
x3l Ts Yy t+}M     return 0;
"R} e-^ w-h7f'bP,Q"} }7T lm[(| M o

(F*ajr:Z char get_precede(char s,char c)Yf3lx%qD
{cd gNx'P u Rh
    switch(s)?3ZtOf'p6f
    {
-b)w2z'y|raP         case '+':                 7FREV-M`
        case '-':
a+eS uR9r]              if(c=='+'||c=='-')
4J]`F F:p8s(b8G5J                  return '>';"Nt/Js(@D(a
             else if(c=='*'||c=='/')/t9i3V7Qa6`}
                 return '<';2z A`3cF-[2C
             else if(c=='(') ]1_?O7s'f_
                 return '<';"[j6B)E)Rx,U'EP'b C
             else if(c==')'):~j/I2Sm;P(r
                 return '>';
P+}w]3Jm:a MSf;E/f              else
b9{u^;Cxw|,A3bu-t                  return '>';
"T8j!?7Z V W gMc5v         case '*':
7V8H#]9|(O uB"r0\sE         case '/':
.Ov|5i*MeY*t8D              if(c=='+'||c=='-')V1e'a0J-u9L3p
                 return '>';
3f8Fs'[u7g:H              else if(c=='*'||c=='/')
A \fr ItF                  return '>';
7[wm'YD              else if(c=='(')
bK:f&S%S]c                  return '<';,g%k!@p ~
             else if(c==')')Ar-z'JsEk;\
                 return '>';
J nl$O&F/^7o5Q&B6J              elseyP8kCe9j4[
                 return '>';z;H:|9oJ(gxm @
        case '(':'Y'OS/p#II^_'dp
             if(c=='+'||c=='-')
.tN7{*f+_^1u2n'HZ3Fp                  return '<';
;T4U9Y/@{              else if(c=='*'||c=='/')*z%H$o7Q-RhZ
                 return '<';i!K v(Ig&_`
             else if(c=='(')
A y3aDE4U8p$c                  return '<';+q+j%mE:|L&s&m3}_
             else if(c==')')
"ufjhLvH[&NQ                  return '=';
#LU~!x["H `UIZw              else#{ u!n%s&Q&E/Va
                 return 'E';6urX| ?8ob Q.] f
        case ')': Le6c.Q w^$iI'WLQ
             if(c=='+'||c=='-')
%ysfH3wp7o^                  return '>';
v7V Q-{-_U.V*@7H              else if(c=='*'||c=='/')
)Hu&na&O%R9w5H                  return '>';
Y.Kb0J3b#h7AE)R              else if(c=='(')
8_O;El~C:Y;r6[                  return 'E';(gJ8A M5x
             else if(c==')')
x+q sB7z                  return '>';
*h-yE7]j/[              else
Z;y] ?-{r6?,eco J                  return '>';A*T\$N(~$yP0Q(J
        case '#':!i%U8S1qL.Md
             if(c=='+'||c=='-'):Kz9CL$`5d2n2U
                 return '<';
#P.SiW2MHi              else if(c=='*'||c=='/')I_(t:[Q kvd
                 return '<';
Wd{X&tLX }2@{              else if(c=='(')
1y^8Oq;`                  return '<';
-l-p W'_&\              else if(c==')')
1I'^c!M'MuO9F%G$H                  return 'E';6S$a1V!zxB5n l9e"o
             else
V W3c)t;SWz,O,|                  return '=';9lSlE)m:j
        default:
]m0aoO2Z@              break;k#o&aIc J4dIu @/I
    }Z h8b1?4u7\;X
    return 0;    Og _:R3iM*l
}
XgfK*w:]R3_t0{ 4_j*l'G2tQA?8S
int isOpr(char c)Z;P"a0^rtf
{
-N%c4g gY     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')#K n;_,X X.[
        return 0;
]w%m0@IL~T     else (Dslls'P'w'V@@4{1l
        return 1;s]*k?*n X9a]y
}
\N$u&{)pCIl7u
i4` amD7P gY(U"Y float operate(float x, char opr, float y)%IzV\"n
{Jblw8e L W#w
    float result;
4q?P/~,hxoD     switch (opr)#F!T!]7|5b(o!G
    {)`$o3Mo7dtvSU{
        case '+':
/H7CSIf2Nl8RO              result = x + y;
u6G.RhJ;g              break;
B.J1F6e3`WJ         case '-':
L*Bi:?:gBZq              result = x - y;9h'T,`$Gr:Bh
             break;c!N,F7Nn
        case '*':
2up+^3Ek Mxf              result = x * y;WJ'c*^~KW
             break;
X ap6K+~o^b)u+qE         case '/':
W@1T/k,J`&Dn              if (y == 0)
L-f4sa2^.g.^              {(t(G2T9M&? | [ @
                printf("Divided by zero!\n");
F#k1p5men;A&QF                 return 0;
~ Y(gJ rC5wu              }
X.B+ydgG9o              else
p#KK@!X Xc              {8Se Fs3^d;W4h/n
                 result = x / y;
y J%bs,f M.TW;O-|                  break;
ugC`D[1F              }
(o._qXP        default: #[P%c6`;pV(q o,qE
             printf("Bad Input.\n"); YGpj9Y
             return 0;
Ws}-N,~'D-M0O     }#G'MP9N,n e7h w+?
    return result;7uJ4F]L\Qk+U[VP,}
}   
sw i9Q?*UXP/V \D t'\&Z|,^"^V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ V$mnI"w)Kf
{l JW'sj*m.u3^ E'B2R
    Stack optr,opnd;
^*Y{Y T+UC     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
z'fo"ykf     char c;
(y1J"o Bbi8Pe8A(i     char buf[16];
Tg:j8i?4mU'wF+H     int i=0;
j"xs5i1|c:J)K    
3v"{ SgXTlN     InitStack(optr); /*用于寄存运算符*/S)E*U9@]v
    InitStack(opnd); /*用于寄存操作数和计算结果*/*N5nks|'~wV
    memset(buf,0,sizeof(buf));
mW9ppe G:m.]-Z4K    
`5c h!pYUk a K     printf("Enter your expression:");
s o-D3v1q"}1TG3FD         ^N-Ytj dPMh
    opr_in.ch='#';,y*f,mNH
    Push(optr,opr_in); /*'#'入栈*/
%C-b axcBK[ ^     GetTop(optr,opr_top);0e0G@:ww.l
    c=getchar();DxF:r%k)r$]!z)TfM
    while(c!='='||opr_top.ch!='#')2^fZg|
    {;kz[hWK*O
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
;~9V m~!\ay:Al N         { ]^ W!O!\mJ"Z]m
            buf[i]=c;
.s(G{ass$]             i++;
E3{6i)b0t^.z4yq             c=getchar();
4JC;S OfA         }
U$i p}LT5z         else /*是运算符*/d z~Y(N/v!B
        {
~e2c!Gj             buf[i]='\0';s.k{0i5f OG3GP
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
s6`(PW:K1@K             {
A3|o%dBas Y                  opn_in.data=(float)atof(buf);
x`0W)_|*q7F;{d`                  Push(opnd,opn_in);
2T3I~*s#@J                  printf("opnd入栈:[%f]\n",opn_in.data);
]nz/uQ                  i=0;$o2I8xt5i1f H NA-b
                 memset(buf,0,sizeof(buf));
2@{!gL7PPP             }2GnU&`t
            opr_in.ch=c;Eid}']Fq`Q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
K@a5E"F~4Q L             {
L8@q.H-r(bA(U'S                 case '<': /*优先级小于栈顶结点,则运算符入栈*/#Z t'l,Er9H^ky
                     Push(optr,opr_in);PT6r7ZO
                     printf("optr入栈:[%c]\n",opr_in.ch);
9hcQ:dZ9B                      c=getchar();
4fk1l AO}o@0o7N{                      break;
b1wN^~p|X                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
E#}$]\ v2g`CV                      Pop(optr,e);
m.bAZ6|"u                      printf("optr出栈:去掉括号\n");?qO/N!@R9U![
                     c=getchar();1V p.r#S&@$cs
                     break;
K1Ln$V8d vY I                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
Jgt K.Rk"FC~                      Pop(optr,opr_t);
^2[)G j;pe\ Fz                      printf("optr出栈:[%c]\n",opr_t.ch);
Lul6|:G @:k                      if(Pop(opnd,b)<0)
8CFS[ Aa                      {
{Fg\r'v^nd                          printf("Bad Input!\n");UH+l gn1A
                         fflush(stdin);l @Q"nV`K/Xe,Z
                         return -1;
l5F*M&{ K^o                      }
G!} WZ G-jK T                      printf("opnd出栈:[%f]\n",b.data);&i\l-wQl*a
                     if(Pop(opnd,a)<0)+iHl(s:G
                     {
]1xl*I!x0^9X/j                          printf("Bad Input!\n");
I2@ w!zN                          fflush(stdin);
!KQSan+F,@)yo*_r                          return -1;._W0l%n M$m7V
                     }
IyU{4g;p(^                      printf("opnd出栈:[%f]\n",a.data);[emo&JMQw&g
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6sos7a iq0wC8^
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/#F5clCv|!H
                     printf("结果入栈:[%f]\n",opn_tmp.data);,K!VY m5zHs
                     break;"N2h OIO#|
            }
@AmI,UB#\T][         }'~N~v;w
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
2w Y:{9{ ]T0J yZ5]     }
_*yFB-a(D.lr     GetTop(opnd,opn_tmp);
|K!k |*X9U$@VB     DestroyStack(optr);}beTeU
    DestroyStack(opnd);XL$FE[$Vo(b
    return opn_tmp.data;
J7cum4qp)R k1Y }
x(VM1}yXN
1\*FE!QFUxL char *killzero(char *res,float result)
.VO MfP.e)n?(I;tJ {iW:W@#Y;`i
    int i;
%T5jJQ [ e8Q p3X.X mE,A\Z"H/y
    sprintf(res,"%f",result);
eP-t!h+y)I)E     i=(int)strlen(res)-1;.E6U0@.FY V
    while(i&&res[i]=='0')
2[7M|\%k/|$RI6c     {rG9b5}Mw(GV^.L"s
        res[i]='\0';
6R3O3_{)Dm4s_L,H         i--;#W#\+]:W^6bl.T0s;z
    }
dF7f NIu     if(res[i]=='.')`V Le'T
        res[i]='\0';
@O5P}9w2uDV^     return res;$V'[]1gimyy
}2L4Y7k/e;]-o$m

0@MS!qq8wA int main()
~/X h%GV3v {wSlA6c'j
    char ch;
!MrF s4YV0_w     char res[64];
+E&JhK-L#Y9K&aEB7D     float result;*PDFV\+N1^6d
    while(1);zLxS-](]'Ry3l4O
    {/kL}%m\8n
        result=compute();&kc)sk.M g'lm
        printf("\nThe result is:%s\n",killzero(res,result));
wQ h`V"A.i         printf("Do you want to continue(y/n)?:") ;
0_E(N(QQ+J4`uc4a'M         ch=getch();
5yP$W(U!hc         putchar(ch);%X*c5GyNG1{w
        if(ch=='n'||ch=='N')$eej"f!hv(f ]
            break;i:?w"[7Fx]
        else
pybr0`4{f2Z.I             system("cls");6_&|TVd9z'[u%I
    }
~;P!g_-t(@#]8R     return 0;-V |,esi1k
}[/i][/i][/i][/i][/i][/i]
&HZ | W"]k
Cf H6Q$D [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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