捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1KvT(gr F gv 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= hCp)Va-jE E
/**************表达式计算器************/
fC8S3dpi;rv,?1N #include <stdio.h>,hVg dDp*Sf Y5CO
#include <stdlib.h>
"x7T9i d2X"{8^ M0} #include <string.h>4Q&^+jiFg@.s9IH
#include <conio.h> n,e dr6s:u;x
#include <malloc.h>
D\,iLj D n6ue]h@
e@u2upv&Q #define STACK_SIZE 1001a7l}Y"X$yyg
#define APPEND_SIZE 10
-l }I8d9\3V1_/M6^ *h}Z?7h
struct SNode{
j j"C.}C.a No     float data; /*存放操作数或者计算结果*/
-ZgK cP8R     char ch; /*存放运算符*/Bz F5Id7[e1e$Q-Y#v^
};
:{8bU4? T4HI2Va
D/_b?+A struct Stack{Yd's*Tr
    SNode *top;
t6k5nX,[     SNode *base;V$@E`2t[9U!f e3U
    int size;a(HV1L4{-h7i
};k`3g#L_-bE?$`t
|r.?^@
/*栈操作函数*/"vAqW9I
int InitStack(Stack &S); /*创建栈*/(ap*uAj)w
int DestroyStack(Stack &S); /*销毁栈*/5b^yC9f
int ClearStack(Stack &S); /*清空栈*/
M0O.|*taH5n,^7Q*c int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
^*u{!@iA@t int Push(Stack &S,SNode e); /*将结点e压入栈*/*N1`9["GKd [U
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/)J~j:LF ?7}L:R ^9z
|md/FA xG5e"{
/*表达式计算器相关函数*/6O:JC2A?7N^
char get_precede(char s,char c); /*判断运算符s和c的优先级*/OG acL;q c:A7|
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
V0?M~!Xu a EUW a4g float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
hZsf,IyR9zWl float compute(); /*表达式结算器主函数*/!W*KogEA
char *killzero(float result); /*去掉结果后面的0*/
m5rurO?\ Q AGu4Xf s"\C$bRe
int InitStack(Stack &S)
:[@'YD(c1r {
[]`ev} g     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1?5sE V0D)W5t     if(S.base==NULL)E*O#A!lU
    {lGYj Um6}
        printf("动态分配内存失败!");
3n+V7Y)yq2Q7r:Z;T         return -1;
6h:Ok9p-w9en     }
0uRP2G"Yn)v8P,C'y%@     S.top=S.base;yuyJ9~7N8tHb
    S.size=STACK_SIZE;
3iB H:uu"X7Bv     return 0; m6p1k_Cv^-t R
}
ud5y,g(D
+E7jjkSa&IR5Q int DestroyStack(Stack &S)!Y lDT h7^a
{
Z1T q)Z/kSx3j/W     free(S.base);
t2mWOSJbH [4l5qe[     return 0;S]5H1_u
}ly2i Zx`.o/@

w-|P|;d:P%K int ClearStack(Stack &S)
|j+t3V3Y7LiU+W {
` n5kL4p     S.top=S.base;
tLDS:~9nHD     return 0;
E%y-XH]2s/g"[ }WE7J e;LE

d)I Su3h#g&w HXhz#V)? int GetTop(Stack S,SNode &e)
;V {c0ph0@C!O {
V!R2i:U)g     if(S.top==S.base)A#\?zl H#}b
    {
3b})u/|v'q         printf("栈以为空!");
$Q*PG!C*yU-P2S)^Z*O         return -1;
)GezF_+qQ%n     }1x |/_1w4T/~w
    e=*(S.top-1);g7@iDO@
    return 0;D(q*]3z/dd8y
}7t-rM x9QK;E/y

wY Q%XrEo5~X int Push(Stack &S,SNode e)
PIFmQ$n {
!K {e'p#A Km     if(S.top-S.base>=S.size)
'Wk6a Ad \z~     {
a,g5p:cQ'Z0R         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));s(@$~[h~6[
        if(S.base==NULL)
"MXS is4q~#T         {i)K7e6z f1U5L
            printf("动态分配内存失败!");
!c(p BDdc             return -1;
!JZ8i1so#r!D:E         }
FH~8j@a1e         S.top=S.base+S.size;|+y)u)n!A
        S.size+=APPEND_SIZE;|/[4z;yVF3x!_(~
    }6J ~;{b]0]Y
    *S.top=e;dMQvX9b{$_
    S.top++;
%Z5Dlw-l)p     return 0;)h'UOXf E/x
}t`E+uXx F9e8[

As\S-t!yn J x_4J int Pop(Stack &S,SNode &e)
5vr$}a%~8pua {
lxG+ugmP     if(S.top==S.base)3WFhF%SH7pS
    {
z1s'z2]R+e1w$M         printf("栈为空!");6H rT hzd'k
        return -1;5[OeerLbv
    }
5]4|K `x^f,C Y(H     e=*(S.top-1);
v s5LmO m7b1G.n~     S.top--;!qp6a+P_4?:oQ
    return 0;
i7Xw UE5E }m2f3]7i1K)k

W{ O%iH5e!s char get_precede(char s,char c)Rghq`$K)kb$H
{
"NtR9rZ0JAx*v'F-S     switch(s) cZ0YY(o&CjX
    { ~{l x.ip'{m
        case '+':                 
T.Z#T;?F1c;e"A&BdT         case '-':_vTt(`f%N*z;`
             if(c=='+'||c=='-')
'X,jV;J9wq@                  return '>';p!h*q?2WW s9L
             else if(c=='*'||c=='/')
$Ak`?] h'u0\                  return '<';
'xf(|W v*S+SDZ              else if(c=='(')
a5Y M9f&q H1jx                  return '<'; M0W7cI[0o*It"P+C G3F
             else if(c==')')$?P*p/B(|
                 return '>'; et#^I Zjs
             else
!@%Vt J)H$Q                  return '>';([Qh2f!n;\#` ]"rQ#F#z
        case '*':
]Vwh7`[q){n         case '/':
i1D {*Uj6t              if(c=='+'||c=='-')
7Zuf `)oJ                  return '>';
`7U+H-i1?\E              else if(c=='*'||c=='/')
PGSfc                  return '>';@)Y!F]N^P
             else if(c=='(')Wb&`Id.Z L+l_4H
                 return '<';
L5L8a\K-LSH              else if(c==')'){&g8pJJc}5KW[k
                 return '>';
4w@DX#n1?'S(^R              else
io3?$JkOl                  return '>';
oDk fyu;ysE5P         case '(':
V y G l\1~              if(c=='+'||c=='-')
t4\H4r,_0u B                  return '<';}/a)R+j&YdP@
             else if(c=='*'||c=='/')
$N n4{ U4m{4A2v%|                  return '<';
u?l;O*ig4y              else if(c=='(')
8h FC0dW-JO u9e                  return '<';
Nr Z![(g[ @ wWn y              else if(c==')')
0E~._k y z"Eeb-@                  return '='; C'k0Q5k+bAeO6o W
             else
#yJ$dw$uwZ S                  return 'E';
I)g*r @/F;LAR1F"\D6]|         case ')':
#~D7~(Ul*Kld              if(c=='+'||c=='-')
mz q-Wx.Mam/a                  return '>';
@-N,R5q+u le q              else if(c=='*'||c=='/')
Fs5k%j4~(j G U                  return '>';%dZvg\s3zD!z|
             else if(c=='(')*X%T1j8O4DJ,X W/jM
                 return 'E';
wYR#J8`a?              else if(c==')')fWq#a1z*P2mg
                 return '>';.F {(\i%} {*\&H(ak(rf!J
             else
/t9I*qYz                  return '>';-MJ$W+D;Z\u z
        case '#':xivl-s e
             if(c=='+'||c=='-')
aN-L0sd J \'@zK,?                  return '<';
t G8^,H4sS,_G              else if(c=='*'||c=='/')^`!IZx0m@
                 return '<';
S(F1r,\_5O.?              else if(c=='('){*{ YX$Z4b
                 return '<';P#a6l~"Ht;\
             else if(c==')')
w9ol;i.~5Z/b4q                  return 'E';h,jIte}/uzV
             elsec&u5X*_3bm&{9u _
                 return '=';8G ]h%R;PW.[h8V
        default:S4v1{M*~'p0v
             break;
WqHx"G4jev     }
.S2K @7q4q/B~)cxm     return 0;   
!j| M J9x\Q }
Yzr:c6m
9xg8k)B,B'd[ int isOpr(char c) c"a7VU}^ J*kP
{AJCdo[.p3]k2J8[
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
x m%u3h9ih8l/Q{         return 0;
t;O1WJ~Z(an[Y     else
:A0a;F5q UGf         return 1;Al5BvP&On4L
}
Jt"I%Hn0E!W{q ||1zO)c0D-r7{
float operate(float x, char opr, float y)2r4}/]k\6K;?#DR
{%@#r&^!P(nR]al!c
    float result;?^$\)Z(]3v;y
    switch (opr)
!H3A)|#q4b2w9t     { Hf;[)p;Q&XLs[a
        case '+': Z8KiJ/rf)h
             result = x + y;
-R8SR_ E              break;
Q4L1V2{|&B\*LCG-I         case '-':
^ F9[@Uhr9X              result = x - y;:WbT6yo7O*H
             break;
zIJC'DC,g         case '*':
#X1c{N }LaJ+^              result = x * y;
d IAj-Cy              break;
r*s+^V3e,x         case '/': z+cUoRTL6`
             if (y == 0)
:x;l8@(x,E              {
9F3x(D${9x;IEvZ$T                 printf("Divided by zero!\n");
RPP'P-hapY"{                 return 0;Ifeiw(B$up)K&|
             }
'Aza-h7UXY+y$bQQ              else;Z7cI hJm%J
             {
_/t(t@&~b[ {                  result = x / y;7SY+{%At2s#[9lIy wDh
                 break;-]7_wFWj
             }
bL4|"e;r~mL T        default:
$m(pE,? RW/b:s              printf("Bad Input.\n"); (q"bl1pf@6ON5jHd
             return 0;I ~q"Qr]$O.yk
    }b/v]0NW H|
    return result;
#ce#_H9~:F)` }   
&O2g~~BB
^1R)^{3|}.R float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+i&pd'b s#\8@*sy
{tC#TR$Z7Q\7Up
    Stack optr,opnd;
;l^w+_-B,H-dK     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
9P3wha;h-L {     char c;
,nX(A[k Pd"E     char buf[16];@!GX5`c)JI
    int i=0;$e!@9yIRg7V,YI
   
7r"i!VKS9{~/{     InitStack(optr); /*用于寄存运算符*/0q"Jtf:p s0m,H
    InitStack(opnd); /*用于寄存操作数和计算结果*/
dKHO'U$P     memset(buf,0,sizeof(buf));x`tp.jh
    K5g2H8^["T)_;M:O
    printf("Enter your expression:"); @Z~"G4TP"s0LpE
        *q4Dp&v$]&ClHf
    opr_in.ch='#';
p`'UG5M%K^Y8c     Push(optr,opr_in); /*'#'入栈*/
Z/u\$`2}x'@     GetTop(optr,opr_top);DO/ijC6r+W0O*SS*b
    c=getchar();x R.yb,\Q,r
    while(c!='='||opr_top.ch!='#')Rc!RE&_5{w
    {
NI"x*w%S1{_V         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
gp"? wa         { K3_n W+{r.O1J
            buf[i]=c;;Q7w5kI-]`
            i++;
D Dbf(a`ju|Ts K"x             c=getchar();
\`5{$AD7e&EwJ$U"H         }8p^+}"j"y^ R
        else /*是运算符*/ AD*b a&@7D5p
        {%]/\!_B5x~n*D
            buf[i]='\0';
"^ Sc-W$K1XR!Jk             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/x1d!RJ5CjX_
            {GFE\J"g'o#SE }
                 opn_in.data=(float)atof(buf);?(I3uL![^&hhr^
                 Push(opnd,opn_in);
R{4\@.ILu.b!nd6A                  printf("opnd入栈:[%f]\n",opn_in.data);,[ Z%^F6@/q
                 i=0;
"NA"n|0a7vNi                  memset(buf,0,sizeof(buf));
,\6Uf3b-Z Z!r;w             }
V:ttJ!e6wL             opr_in.ch=c;O,ln Ui@Lt
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
)_$w? [I&UA             {AK0V3l3dT1k`n'Y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/M/T)N:S}C l&C y ^UK^
                     Push(optr,opr_in);
P:rv(Fk"d2]c f                      printf("optr入栈:[%c]\n",opr_in.ch);
KAd.H1AEr,V|;g                      c=getchar();\a8^8y2\:M3z
                     break;
5`(r;p"f-J Zw                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/\w i/[)pt{
                     Pop(optr,e);
k7F~gv Y1|                      printf("optr出栈:去掉括号\n");5L7R/hx!u^2s
                     c=getchar();
jR4pBsw`                      break;
U w%v"~,o G                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
G!x5H |Edp1b                      Pop(optr,opr_t); wf ys|t#[bNM
                     printf("optr出栈:[%c]\n",opr_t.ch);
Y,Z&J7@ooj3?f+I                      if(Pop(opnd,b)<0)XA%L6g p3}
                     {
-ry p9_e's$b                          printf("Bad Input!\n"); ? F!V1tn,Q S
                         fflush(stdin);hYUWK-x7B z
                         return -1;
9S*tO4xy3Xt                      }FZFXpJ0iV
                     printf("opnd出栈:[%f]\n",b.data);
1e'Gw'Gs!{7|                      if(Pop(opnd,a)<0)
5[9uyma\#K                      {/? @ S)\Bk$?;[
                         printf("Bad Input!\n");
N-x!|)DG,`C                          fflush(stdin);q/Z ^|x*u Mg[
                         return -1;HIF6S4t@+X9EY
                     }
1bE8X%A,sNL                      printf("opnd出栈:[%f]\n",a.data);
7?1pe,P!blXE;U                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*W\9r3Y$f
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
biaxG1z1D                      printf("结果入栈:[%f]\n",opn_tmp.data);7kM)ra-NZ
                     break;,w,e3i {5V.Pi!P,m
            }eGu9[3L
        }(?)Bd1C(x/vbG1d
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4{P%O5t.O/l d     }
Z1S,s.yj.LL4`+Q     GetTop(opnd,opn_tmp);+XgBQ5D4wF| b
    DestroyStack(optr);1@;yox*gi6B
    DestroyStack(opnd);
,Y7}#Bh;GOae!e+z     return opn_tmp.data;
M` @5C$U U9v },nRl,^ rhSRy

Bb*H A$J FB*C0K char *killzero(char *res,float result)%m3]3W Bq5\(e$LV
{i6Ip Q1x:U`B,`
    int i;
T?-{]&Mc/?
!I8a/xPk Ch P1RB2S     sprintf(res,"%f",result);
d3g2qV T_j     i=(int)strlen(res)-1;n{2ykKN J;Cp
    while(i&&res[i]=='0')
O6W/w#l6`|6Bcb     {`LR t ]!G8c!`
        res[i]='\0';
/?'C6g"x8t         i--;
2x_&m)Hn!O1u     }o%\RZEE
    if(res[i]=='.')j X XN L^0I
        res[i]='\0';
*fTJ tC]     return res;
-cph]0LXl4s }!V i{yg%s`
~Q/ulOjA
int main()
1dl HnNR0V {2l'Tr,r"^Z
    char ch;Cq&I7WQ
    char res[64];
/us8Spa?*m     float result;
5k'H^3|"m3A{     while(1),NrDi$] c]]W[|
    {
HB"b@{1?e:F/Q         result=compute();
"N%ewt5q"S"[         printf("\nThe result is:%s\n",killzero(res,result));i[*B%gK.q zT
        printf("Do you want to continue(y/n)?:") ;
.k4S|p2oW gg0JQ"y         ch=getch(); Rk H?a.W:l,`K2rn
        putchar(ch);
G}'|6Q2l;USy         if(ch=='n'||ch=='N')
%v(E0QNs,jI4t#T             break;!J+V%pi[.M7N
        else;axfncBt*^B
            system("cls");
D1q4jL7EG/H3]     }kBK([7^H
    return 0;pp"hLD
}[/i][/i][/i][/i][/i][/i]
6bA2v0a[?U
Ju:T!^ @zj [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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