捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
^)M8T l#A]l D:Mv(x2V 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= {%Qe D)p P
/**************表达式计算器************/
B"T rmi+_2b #include <stdio.h>
8^Y_0wX.x2P #include <stdlib.h>
^8swwx #include <string.h>
R:YkF!U!G$zFr p #include <conio.h>KOt~z S5k
#include <malloc.h>W A6dQq7k

,@c6VF0mt;{ #define STACK_SIZE 100
_ h(v['F+? #define APPEND_SIZE 10 z-wtw slCg Y~ l

I'U9Qs'O {(Qe-b struct SNode{!Vq&g9]5R!i8@
    float data; /*存放操作数或者计算结果*/&t"Z Z#B*E po z U
    char ch; /*存放运算符*/
F'o9WS6{%`Bm8Q M };
`:F]v(ZV\YG:n
}w q AdA struct Stack{ g Lj Q'qJ |C [
    SNode *top;8bqG3FT2v
    SNode *base;
u9vA#FrN"fd5J#\/m     int size;
}9VA8If.^ }; Tt&RQM
'B F7I3S:q7r
/*栈操作函数*/O"j9WyG?%d F
int InitStack(Stack &S); /*创建栈*/
;M;G`-r-`jd!l int DestroyStack(Stack &S); /*销毁栈*/_5V4VR*sQ3HZ
int ClearStack(Stack &S); /*清空栈*/
RTD u^%Q8^z,F` int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/B v\0}7g`9E4r
int Push(Stack &S,SNode e); /*将结点e压入栈*/4nKHH-yZNF;Y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/a:rahi1w%b4bC

9d"y%oaM IR2U /*表达式计算器相关函数*/:S4G TEe
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
a A&Z$qU Mvt int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/l2]3No4Pf7D2V*]y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/m@+M n W
float compute(); /*表达式结算器主函数*/YHrF0BpNhM
char *killzero(float result); /*去掉结果后面的0*/
4E tA5Ve:S9l9yx`o
` {h_ [ _"p3X int InitStack(Stack &S)Djn/oTZ/]
{
J s$[hS5O     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
m A&pfg K)T     if(S.base==NULL)3Y9q7m7?LS"V~
    {
~6E1B d^%mV7P         printf("动态分配内存失败!");
-\ y9ZUue!o#l#|7l-J%g         return -1;
\S[!N:V     }:I5{NQ:z"EMX_c
    S.top=S.base;P c$`*Ta#g2w
    S.size=STACK_SIZE;
@y'z ].q:u     return 0;
WS ^t@g3a3z'oj }%c6N{3Ez}

#v+NTf eY8{/m int DestroyStack(Stack &S)3oh$XO-X
{"R/T!iyxk
    free(S.base);
P5S _BC zv     return 0;(}rd2| fE4[2v
}
C_ seF?VU
k U"Q;K_u'u int ClearStack(Stack &S)-OHT \9h%Q
{
4PWo[D dY     S.top=S.base;A\.xZD9~\B
    return 0;
M9u-d8i#A??/t2b }
$A,z"Qm2z8O ui +Drm0{F"j e
int GetTop(Stack S,SNode &e)
o b?:y7s*A:`2HpbA d {r}7Awm-I@
    if(S.top==S.base)
H7hA_+I1{Y9S+\xI     {
oK@x"zfm"@         printf("栈以为空!");1Su_'@7}p
        return -1;c-N!\ r(BS
    }d5F,Px b
    e=*(S.top-1);
E(o&P7ZM~a?     return 0;5e2Ly8y;fh Y
}
R;m9Kk.rTO|N \g,\#I'RM)c
int Push(Stack &S,SNode e)\ |c(U s5u1S O_
{*O9_:ZKD+a
    if(S.top-S.base>=S.size)d-p5Cag8]T#RC4VZ
    {
+g-I0\3}$zjX         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));p(YlI,i(J0RX:n*|
        if(S.base==NULL)
7C5~ MNC9G9X G8|J         {+F x2N)E)tg G m W"K
            printf("动态分配内存失败!");
#s4F atL3X(Gl;od             return -1;
e&S%r%fM         }2I-d6Mz3d+_
        S.top=S.base+S.size;_/~C]X7^eQ
        S.size+=APPEND_SIZE; d];BL s]/d;h
    };ws&{D)P `xln
    *S.top=e;,i v;E_qLd
    S.top++;
k6`-nJ&c4rrw     return 0;
@D S I%B%a OPT }%KcX3WZ%p5ilO#N

L!p4mvV2r7qo int Pop(Stack &S,SNode &e)
B c+E9pUVL { n3\%P;R{
    if(S.top==S.base)
3?@&]w2v L     {X-r] e\QH@xkh)}
        printf("栈为空!");Y tX/D6r
        return -1;{J3@~g/lA
    }
`_#r IV3O*[*Y     e=*(S.top-1);
Jv.^ZM     S.top--;
,k^'U0r W5U     return 0;
U0i,q XV:U{ }DUe {v6PM
#?{0l5|_ r
char get_precede(char s,char c)-E J7j%M7V
{
q{/_9X.P0P\     switch(s)$Mb-vh(VAK
    {
O [ TDg6J!C         case '+':                 
]!_%q-|(W,S         case '-':$K Qeg/OG'["`
             if(c=='+'||c=='-')
S[$|@3A                  return '>';qd'LxLas
             else if(c=='*'||c=='/')7\0@-p)`B
                 return '<';-B1|2^4M ZvK
             else if(c=='(')U-B7fQ7zL8@k-C'd4u
                 return '<';
1l1EM@/I+G#?6X.{D              else if(c==')')qS i!z&@0\#UsP
                 return '>';
K$sR+G)?.Y S              else {\k|3lj/u
                 return '>';+OwV%R CY
        case '*':
,V&W4q]i0r1K;Y6Cs B         case '/':8e&f8R4AO9[2j
             if(c=='+'||c=='-')
-k-hv"Iw Z.]$}?$l                  return '>';
8?9})F ti+u^2XZ              else if(c=='*'||c=='/')K I8^OL4x2vMb&|!C"D
                 return '>';(jA)S]1~r3Ig!N:uX7F
             else if(c=='(')9SwD'D:~L:W%|&|;E J7rS
                 return '<';aT` l9dg#m
             else if(c==')')
3v3X;]Dp e:@h                  return '>';#LFmG%M7|7V:d
             elsecfc5IL ],C
                 return '>';!Y9[n,{(nI)Fk1Ph
        case '(':.S5Cz(Q \ja S }y]4F
             if(c=='+'||c=='-')&z(Iy%K)g6K(iGx'F
                 return '<';
e&X8h{"FL)I%M9i              else if(c=='*'||c=='/')0@ J/V9aT\#sH-m+]
                 return '<';xH/dUoB
             else if(c=='(')
[ uG-p$R5h V'Uc Q                  return '<';
7t'UzA/\xr              else if(c==')')
ZF@-C(uDN                  return '=';
;F jk4L`b6m7Sc1u              else
J*Zm8X ]&R2Y.p F%P                  return 'E';
y@:C ?!TnZh         case ')':
Y2L;s+pY%_{q              if(c=='+'||c=='-')
9kx@/g^9fL8P                  return '>';|M.I-p;n+H
             else if(c=='*'||c=='/')
$Tq3d2}st!mD                  return '>';
}5ML b o$i              else if(c=='(') l6{V6l'DKy
                 return 'E';
R6nt i4xL7K)i              else if(c==')')(i8NR1{ X%E5g
                 return '>'; [0~p|.`1|&e
             else;dRbZ9I3v
                 return '>';
rz$HX#c K1]         case '#':1Qf"vWAH
             if(c=='+'||c=='-')vR^Q(KQd[(rg&P
                 return '<';
7Y&\;v*Uy0U#y              else if(c=='*'||c=='/')
/w^$H|4sJ                  return '<';
C$gK%C:y`1X)U              else if(c=='(')
p8a4^SE)t? w                  return '<';o8dEP#?
             else if(c==')')
mnM(B X GY||,w                  return 'E';
2q a i8hK:F              else
0z,`X |Fa{ U                  return '=';
5wl`,[}         default:^ qCZ/GW^8@
             break;
/?G \)z vV     } pj?PUM)TA&b
    return 0;   
$SX,Ar0Cc B7?O }l8D*\qYGe-}

%o f9z5H3yGJCw int isOpr(char c)gU w(`vx
{Yfm$?C y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')-eH1moB'pwZ
        return 0;
,B)z;w2m/v&q b1N     else ,Ir*U.aW}0H^Dvk&i
        return 1; L4]G&\ y|2X
}
;O`9kE}x4[8z
j ZHr0a float operate(float x, char opr, float y)_b)F*V7B(cx
{
d rP[])@._ t8@ f     float result;aD[/o1sX
    switch (opr)
4w8M0WzKr*B1w c1F8|     {
#u&nVfky.L#vNc@$u         case '+': -F8R}*e+S~
             result = x + y;i4dH5~` s$J:?I
             break;z$oBCR
        case '-':
!zSW+EG&Yf0N              result = x - y;
/B f+P'D N SZ              break;[f'Y Np ^{
        case '*': @ bBA X'g^
             result = x * y;S3I4l3MM2M*f
             break; F f6pML3c/@,Z*J
        case '/':
R#gS#T/[,C7L              if (y == 0)
X+J+HZ;ES,Z              {
)j`/D U9@Q                 printf("Divided by zero!\n");
m&I fs7w V N                 return 0;
QA5X7G^:_              }
v4e OA/dT6AE&O              else S0a1~1Se,^8^s+y y
             {
3i;e.w*c*}c`8A                  result = x / y;
y3g5sh4q"ME                  break;
yh_/\_              }/Y/K7A v V-mE VL[;{
       default:
5O2{n8B`q/uC              printf("Bad Input.\n");
}7s*}uHAgzy9m              return 0;U!r}dw
    }
l }9vX'?,l z}7i){     return result;
$qi:X4_']jP }   
*tG?I.a3D+w s^ {\!C"H.n
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
%U{Yk*kz0~ _!l r&N {
~ZH-w*T h [     Stack optr,opnd;
2b1~ ?6igS$s@Ro"v     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
G![0X Ll%w w     char c; W|N5V}(d+@l
    char buf[16];
;a};hi0dm     int i=0; ^ n/e Q&r
   
V8eiC(V~9S?8b     InitStack(optr); /*用于寄存运算符*/f2h6OYd b;A[@
    InitStack(opnd); /*用于寄存操作数和计算结果*/
6prn%{~8`(^4h-E;a     memset(buf,0,sizeof(buf));,g$w mVC0?K(W$t
   
wl{:Q0y|0{ tmU     printf("Enter your expression:");jd8n8R3|Uris
         tJ q,u,xUg
    opr_in.ch='#';1i1pQ*^Hg
    Push(optr,opr_in); /*'#'入栈*/btIA(K_
    GetTop(optr,opr_top); v&DF#k,pH*E*F6b!Q0u
    c=getchar();
K,?})S4S [ h     while(c!='='||opr_top.ch!='#')
8p4s3u0A;X-P;|gs3F     {6A%{&R$V&D U+v
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
G%B1Sb%xV l         {0U`"O.ia _-r"d
            buf[i]=c;7{K+m%n'Ie
            i++;
ds3^*qBJ I             c=getchar();#T7tL(kG?&[a nI
        }
:IXy5W1` [8l8w.b         else /*是运算符*/(~t} e(A nH \
        {xo|0M&s/b8nq
            buf[i]='\0';eR}$Z-\-K
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
~x5JIRyG1D             {
^S |ZD ^                  opn_in.data=(float)atof(buf); \l/FM lD3] C^5nQ
                 Push(opnd,opn_in);
-Q2Nb"xXb                  printf("opnd入栈:[%f]\n",opn_in.data);&p)w}b+GO4nh
                 i=0;
MFKy(I'P9S                  memset(buf,0,sizeof(buf));
LG d b-d-l"o!yH             }
#L{ U-?v-q,D]             opr_in.ch=c;o;uEV ax1l
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
VZ(EU4bQ             {
`Z/N#Y,dx]H cZ                 case '<': /*优先级小于栈顶结点,则运算符入栈*/6L@n&J L,EX
                     Push(optr,opr_in);
,T4c rI.QI0q+K                      printf("optr入栈:[%c]\n",opr_in.ch);
6O w HUV                      c=getchar();
x2S4C9lOODl5O&c                      break;
c? w5_KR,_.a)c                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3]o%y)R?o                      Pop(optr,e);\6o.Q0~R
                     printf("optr出栈:去掉括号\n");P j ~P ^)B
                     c=getchar();
(Fa ]`o+`                      break;
0n&w!| Sj/](d)|7~z                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/v(G$@[3LzcA+EGl
                     Pop(optr,opr_t);mP4W[A-s%y;@!Y
                     printf("optr出栈:[%c]\n",opr_t.ch);
K z t@ ft7W                      if(Pop(opnd,b)<0)
F?$h*m g PAG1q3Q a:@                      {
{/Dk,t(rh                          printf("Bad Input!\n");
9Y-c5U&h e                          fflush(stdin);
:E1IH?eD                          return -1;g cp:? Y~w3A.Pb
                     } w9Chl[ j/x
                     printf("opnd出栈:[%f]\n",b.data);
y;@#n"O,A'k|%qH B                      if(Pop(opnd,a)<0)
pH!D&_$A                      {
WK:D+cQ6p#V                          printf("Bad Input!\n");k&aPm4F
                         fflush(stdin);
s!o;y\8Y;G                          return -1;
Y;SHD!P;]ViA                      } Ut7G0HfT*_
                     printf("opnd出栈:[%f]\n",a.data);
Qj'Qw n                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Q,`VY)KV                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
X%~s~)AsQ                      printf("结果入栈:[%f]\n",opn_tmp.data);
}}{_5\P                      break;
NO`~to @             }
'ZpRa.A         }xP C;{O Aiz
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                E/Z!my"m@
    }
f1g4Q5WG3m)q!]     GetTop(opnd,opn_tmp);
+N8~P!n6s     DestroyStack(optr);7Yj0{;q M3Z8]]
    DestroyStack(opnd);
8Z+cx/Z,`%^$Hck     return opn_tmp.data;
eT^_Nbd0i*ZX }3e'S!],J"aCOGpKv
h$}O[oTjX
char *killzero(char *res,float result)J~7e.U O#a'h
{7BG6g'B!|9^2ox1lb
    int i;m&_&tc'D7SpW4E}?
:[.qG#D [\
    sprintf(res,"%f",result);
FJ@%x,L[.^     i=(int)strlen(res)-1;7xVX[g\:?2Xv
    while(i&&res[i]=='0')2R/S0o#My`t
    {&[I(pG,k [ ]6QGzag
        res[i]='\0';J5Uk:Xw(V
        i--;*U6iTo"N5gw
    }\&u2GB[,V+Pql
    if(res[i]=='.')
A$aG*I }3n^;m7v         res[i]='\0';
T4[#ar7KrZ     return res;2D*J}WU$q#@[M'dr7{
}
^ ?~ k;p ,n+Hq)|k&k:s*V;m
int main()*o;_e`VSpcb
{
a2H2I mE u     char ch;
;s+Ed'Oa     char res[64];\ q1FHw
    float result;Or@PE*^3|{"L
    while(1) tG%dx y^
    {[T3K @zi
        result=compute();/?9WJ0u3bW't
        printf("\nThe result is:%s\n",killzero(res,result));
k7m"\ `6Qk         printf("Do you want to continue(y/n)?:") ;%e:OO W(`;Q
        ch=getch();
V,x3z5B-qD6q         putchar(ch);
\CZZt/ls&i%RW         if(ch=='n'||ch=='N') i2vd4@ qE!k
            break;m'Ng;|-l0u)a,P
        else4b7E*a5L4YP#R
            system("cls");
%rFe:n~A;wn'C*I     }^8t Gn y D
    return 0;k6F\/d&F
}[/i][/i][/i][/i][/i][/i]
r(q+H*|5se]+g-l -z)X'a8c;g l*n6I`
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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