捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.*J O%N PY(~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
h.b-wNP)P5i /**************表达式计算器************/
1j*RX/Rq3?-VY #include <stdio.h>
%c,ea*A S&p6M #include <stdlib.h>
'w"Bt"L O #include <string.h>
;D'Hx3O T7tV #include <conio.h>
.yP,V2I*Q)H #include <malloc.h>
P9N` Q5u5V|
U|1A4X%Kul Z #define STACK_SIZE 100
#J{ `*ODP1B&} DN #define APPEND_SIZE 10
,Dy)xqRA L aB*Q.PvWJ5R
struct SNode{
f#_mP0p.A`X P     float data; /*存放操作数或者计算结果*/ ?)B j,h8lz
    char ch; /*存放运算符*/
$LCs#@s };1d0Kd3Cav#v

-x%x]`D struct Stack{
y-[[^b4ayp#c9h     SNode *top;
b0NipW s0i,O     SNode *base;
*xv2OF%~0D8x|d     int size;+H O%r(G9p$Y
};
si WU&L2e | im-z r2w%my(~?
/*栈操作函数*/
|9t4r yE&?M(b*V%d int InitStack(Stack &S); /*创建栈*/.cY+v)yL&Nusxiv
int DestroyStack(Stack &S); /*销毁栈*/
ht1P;T#Z EM int ClearStack(Stack &S); /*清空栈*/4|R@$i^9l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/:O'|$} H/J A+hk$J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
T8HO4]9@ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
_0^r.r2Yl#U
db,pzn3v H s EK /*表达式计算器相关函数*/f&oH&q7i4k
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
sXu6y:r&X1E)C int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
,{E"Ez~0sk float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
%R7X@&fG+`E float compute(); /*表达式结算器主函数*/
iW5D*v&|Y:BJ;T)h char *killzero(float result); /*去掉结果后面的0*/
o;m?X0|S7~
.VBJL0s[)M3_ int InitStack(Stack &S)
d:G&wR.`jP2^P#k5b R$d {^*`y?"q`(@
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1l;~9i&N \JV
    if(S.base==NULL)9fw v-p0{[:J$M
    {
-h1v2P*gfY9y         printf("动态分配内存失败!");"_R A ? T_:rw
        return -1;
vB [ht`7U9~     }A(l[2}k/L3o&e
    S.top=S.base;
5A*G%v[6W2eatl     S.size=STACK_SIZE;
|&Ch)k_#?4?/M7P     return 0;
~7{2u OT }w_s-qaI9|2}
]hs:R[;AM!C
int DestroyStack(Stack &S)
hF6p%j i#nKF1k ? {
%}#w,z?I)f%Z     free(S.base);FG%l(R5~ |5p%U&\5Z
    return 0;Qgsv$wVS
}-K*S ~Zo"_}!U
&f`}/V!n2o)f pKh
int ClearStack(Stack &S)}2uoK!G]5yz2I YF
{
O(Z|I)k2R     S.top=S.base; oIu!v-E.p
    return 0; FH8k J(^(D5q Xo?? h
}^5Y?-P6k_
*n,sl }"y3?
int GetTop(Stack S,SNode &e)'E0T~W)g;B m
{
| av Uq h     if(S.top==S.base)
x-Ka}/j     {U-tHG Lv W
        printf("栈以为空!");
#SpdCyx;YS,C*K(F         return -1;j:O|Bv E0? @$j$a:{A
    }
"?u6g~YW     e=*(S.top-1);
J4[@ Huw*T5w     return 0; v6e{5Yj4GN
}
4m+qgoh Xp T"t*]+^{x4w#A
int Push(Stack &S,SNode e)'bI&tf)nJ
{
;^TQt1Td8]     if(S.top-S.base>=S.size)2}k%iyc!|Z*G
    {
x'v{7s/x5z4O         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));(Lz8w;o Hk
        if(S.base==NULL) pS ww4L.L7W+I[:x
        {
j|TF-aIc1A.n             printf("动态分配内存失败!");
fT6E9x)r w             return -1;bJ9OWJ^C Jte3{-k'I
        }
4mf],c&hXb7`~         S.top=S.base+S.size;x*Pi},e#jE F
        S.size+=APPEND_SIZE;9}?Hj C)^
    }y[Ju!pPhE5B*DX
    *S.top=e;
A`6zx0A6VWg     S.top++; aky/O6L;Tj`RD+z!w
    return 0;#`;A7dmq LxpE9v
}
2h%BL"nq&Y4VD(`%Q ^ }#bHK
int Pop(Stack &S,SNode &e)b&\+smX ks l
{
0\6ih'`N*J g     if(S.top==S.base)mh }+H[\6l.AI
    {k2Y H5Gy;I
        printf("栈为空!");
q/]#I!Lz'ekH{K         return -1;aZVrp!n#b
    }
;A*b&CEW;||;N     e=*(S.top-1);
;K.A,w6\["J;b     S.top--;yVT^ Fp5C
    return 0;
"o'K [XwB7q5al }P*K1FFzXq
R@0YpSK
char get_precede(char s,char c)#H$^!w4U+Lp4s
{
1Yq,o8t+yafv(N:t1I     switch(s){Qme3[/n:O
    {
$~:|%y"Eb3P+xb         case '+':                 
t]1M]n%k$E?$uV         case '-':
`!Jkc/d,n#wh+Y*n              if(c=='+'||c=='-'))V v+s4u*a+o
                 return '>';!C \ Sn _ q q
             else if(c=='*'||c=='/')
&BQH{7Y @HE1S*G                  return '<';
6U3w3s1X%F)S\B              else if(c=='(')OeC5O6} TRdZ|8A
                 return '<';
PMS7Z9] Q              else if(c==')');c~O5zhN#q3l/p!Cb
                 return '>';
(P:\%v)K/x;H              else *e8U0i | w
                 return '>';z8L1k%wC;rh
        case '*':
M'dv]:Ss         case '/':
HH1jc!A%E              if(c=='+'||c=='-')D3BDX0er ] ht
                 return '>';+uy%orW3x.o\
             else if(c=='*'||c=='/')a(Gi k,N XI:w
                 return '>';6Q{&mi S(u,_%L]
             else if(c=='(')?Rv KPMp&by;L
                 return '<';
LwBJDq]c              else if(c==')')4In3l0CK9@D
                 return '>'; qJs*DO3Cf O%`V8d
             else!s{t3@$F
                 return '>';(f x-zQXIbI
        case '(':
R-c;m^0N|j              if(c=='+'||c=='-')
0{$Yv Ec4kT,w/yKq                  return '<';
}h)M-F:M3[!s;h)WUB&V              else if(c=='*'||c=='/'):z2|u!d2N\ c0x@-z
                 return '<';
h*m:f3WZ.K;IR4B E/|/u              else if(c=='(')
0SLl&M4bq+Uc                  return '<';LvQ^!l3D
             else if(c==')')n+y(sKo-d;[
                 return '=';
7X^Lrp'? q9E              else
zSl5QT.Wm'k}:V                  return 'E';
\t%r!wDJ ~         case ')':5gNgo[c/vRoj5Fn
             if(c=='+'||c=='-')
+|p&~9p3jp                  return '>';y r3z}2k`
             else if(c=='*'||c=='/')
;~NB5irlo                  return '>';
NWA\"o9U              else if(c=='(')
a~ Y7b-[]/e"rmy                  return 'E';2G/Pw8m9q~
             else if(c==')')A&l] s_
                 return '>';
X*}Ns|^zX              else
2vVR#Xk                  return '>';%[Fs V]7J
        case '#':
TT3c6}I              if(c=='+'||c=='-')j"mI+B;]q4r%K
                 return '<';VwO3P$Y[q
             else if(c=='*'||c=='/')1w#~$^9@ C
                 return '<';
5Oi'v YFe3F$d              else if(c=='(')
^C0EC3t D&jJ4@                  return '<';
7U g8N#n w@[ d|              else if(c==')')
AQc6Gm/NQ1s;^                  return 'E';
9q%Y N,JRb-d&L2O              else s-V9bs5o"vD0~w
                 return '=';
zu'i!U"?         default:
-[ XjpI+U'o              break;pYv)Y{0D'A*A
    }
]E+F\&?7U     return 0;    y#g1scfGkl
}JVEn,o$J
[3ivLw9S&[w
int isOpr(char c)
#Ir0~ x.kceZ] {
n WW4m` ?     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')(Q+bP$XX y:G'j1h
        return 0;
7}&IB]X6O4J"st     else N;E#m.Jy7] @ wv)Q6y
        return 1;"p:Y+VS'X%\*@8s
}4V2oV ZE;]
(O)U+]Q+ZL
float operate(float x, char opr, float y)Lkj0O%Vq v
{ ved0nr&I)Re
    float result;
-m9c0R~S     switch (opr)
3Pl(wF,[O u&p     {
ja"O.N5B:as!m&p         case '+':
R~ wG-`!e5Z              result = x + y;
,M3q8~A+xpfl1z              break;@X)p*L.e*qX4v:f
        case '-':
~4[v e2Dl*d4h              result = x - y;
aDOv|~8T              break;
A]\ t"L3M!DV         case '*':
k+D.yfzH              result = x * y;
*C&bIO R1u J[/z8H              break;
$i4vjt{8M         case '/':
'Ge'YAG'Z*|#F              if (y == 0)
2YCOsp&B              {D G@4M ^e
                printf("Divided by zero!\n");
(kp(~E6H%o                 return 0;
)DY(M\2nK9D              }
7M\U"e'Z Z'C)u              elseM F4]:z~X-gy#Jjg[
             {
#Yq$^cA9Eql                  result = x / y;
A-o{2`P.l                  break;
e/N];v.Qo%B8^1]#h&G              }
7d;c1@)lf9}af#b        default: o#nEPW/H5S4yr
             printf("Bad Input.\n"); .w m~-Yk,|L
             return 0;U'H7_;X(RZ"P(u
    }
K;fb0goG0v     return result;J"Xb4W1lRB
}   
uR4Y [)dB
4Qy$g7GFr float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5z ^q4Ki K {
iJKF'm6}CN.xm     Stack optr,opnd;}WzG@Ja
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
ye#T9p*L     char c;
6?g ]dB"hd7tOs     char buf[16];1v I @0d0t&GiEZO
    int i=0;A&P9KVP-S
    5E8N4Br8_ ?
    InitStack(optr); /*用于寄存运算符*/2XY.J(?)TYK8e
    InitStack(opnd); /*用于寄存操作数和计算结果*/'p3NA$QQ @NF)s#e
    memset(buf,0,sizeof(buf));
o#X&d,D,`c,z:e     1e4{0p7i/~nL'om
    printf("Enter your expression:");0}:}_g;Im/u8\.H
         b;C#H2M$O$]8z6rL
    opr_in.ch='#';5qF!R#x9P E9t9gW
    Push(optr,opr_in); /*'#'入栈*/
F&uI8TgS?p.N8O     GetTop(optr,opr_top);KS/Gg6S4q!l
    c=getchar();ll1L(s%I1~
    while(c!='='||opr_top.ch!='#')7}6[ F`C:_4v K5PC
    {
\3ap)W#crxDzo(|         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/?^O-[ww&bAT
        {
&P!h4y+EZ+osx             buf[i]=c;
QmR_ WV,aj.H&}wO x             i++;
gN9ZG5c.V|             c=getchar();'r(wV-R*i2h
        }
)og[.i2G1CT         else /*是运算符*/7z2c}&dn9ib.a
        {^G P0f7I[q4DW
            buf[i]='\0';
q'ss.Hry{}%j#T             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
nA5~D5{}4Y             {
6T"es|5Kx%D7a                  opn_in.data=(float)atof(buf);
1ph5n.Lu(V                  Push(opnd,opn_in); W,TRw5ir:\^o
                 printf("opnd入栈:[%f]\n",opn_in.data);0thK.dY\
                 i=0; bI&G2Mxy
                 memset(buf,0,sizeof(buf));
#mx+i [*U$V9DG             })a)ra:[^D0@T
            opr_in.ch=c;
U$~.mzE!k7U             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Il8D;iP8K             {
}!IJQh'Ypo?%g                 case '<': /*优先级小于栈顶结点,则运算符入栈*/#lMn(n;H7mm
                     Push(optr,opr_in);B)tW;bgPK"l
                     printf("optr入栈:[%c]\n",opr_in.ch);&`2x.DOcA7d0c Uq{
                     c=getchar();
k,mY*C-k\%?                      break;
(A i a%H)C}2G8U S                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/4m;^U,F-}a#w]P
                     Pop(optr,e);
Lp ]3go                      printf("optr出栈:去掉括号\n");P X!v b.\h:I
                     c=getchar();ThhtsS3y1tC
                     break;,n N#?]2oD
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/;G)X2u*IYQ E3]yU
                     Pop(optr,opr_t);
ct4\5^-F#R"wxb                      printf("optr出栈:[%c]\n",opr_t.ch);
.t ^ZhtvSm                      if(Pop(opnd,b)<0)
T7o k-_ZrA                      {
{#C%eK5N6]5x                          printf("Bad Input!\n");3Umj.J F
                         fflush(stdin);r!k/bH&f Y
                         return -1;"C Q2Zus S
                     }
&xQ2k'Dm+^E"AF                      printf("opnd出栈:[%f]\n",b.data);
f+J(e-Vm                      if(Pop(opnd,a)<0)8EI6Ay3~LY3yqZU
                     {*?7pL |P ?z
                         printf("Bad Input!\n");2IVb {v Stk
                         fflush(stdin);
*Ia7K/R"p'h ?                          return -1;~YO-F9r4[\
                     }+{hw2r-]t4s
                     printf("opnd出栈:[%f]\n",a.data); A6Z9g$G_DL
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
L#Ta-I Oz}Y}K                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1kA%U1[ B"l9u/dK)q
                     printf("结果入栈:[%f]\n",opn_tmp.data);
*s"]O%TV)q+dV pE                      break;
qia:{W             }
({0YT7i!Zx |         }K*AQK#{ \ N|5Q
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                X{'AX lhN|
    }0Ggled6S6U V6kn0Z
    GetTop(opnd,opn_tmp);
u0Jnrf     DestroyStack(optr);
/]6Gf,i w.B-L.on     DestroyStack(opnd);4@-B&baYP4V&J4?
    return opn_tmp.data;
.?3N5X PU;H _4N }Y2Wjb;_FY
?X6};T8nZ"j
char *killzero(char *res,float result)^-OQ@0e'P:e1b
{
l-Z-@rjfd~5c7B     int i;
u2g/cwG%h-K c E3D8\.o.c k
    sprintf(res,"%f",result);
]pWO-ePj)j     i=(int)strlen(res)-1;Y vt D)`q
    while(i&&res[i]=='0')X R$Wa9Dm hV
    {*lVI7IL"m.D
        res[i]='\0';J$e'To O g xx
        i--;
(I)OI0G*@1y` Ft'K     }
| TYk o9d/j     if(res[i]=='.')#S?/v+xr;Z9\$c
        res[i]='\0';
hb6T:e#B d     return res;(Z l ]KA!I-yj
}
x8p0P8\ Y/G$X:e"OQ4E 5YSV[8\,w G kb
int main()
.CsV Uu!?:T9m {
&AOWW}     char ch;8JT$L1z R?G
    char res[64];
g.hY9L^D`     float result;.co`}5tcTlP
    while(1)
$p(C{8B0mnR/z     {
/t2C-qQ:F E         result=compute();
#mNUC[h         printf("\nThe result is:%s\n",killzero(res,result)); _*l,fO0@t%T bO N[
        printf("Do you want to continue(y/n)?:") ; Kb#E`1k'_kY!Nd
        ch=getch();^0S[9|\$ec
        putchar(ch);i3a8Y}5zu&[
        if(ch=='n'||ch=='N')
8zLSM f}+a             break;
Ti7u2R{F         else%Y&IOY!e3I L
            system("cls");
~*Se@1Q+p     }
5uov:};V b}&i     return 0;}3[K m"O"Vo4q
}[/i][/i][/i][/i][/i][/i]
&zi6RS ikx\ SM5V [,c-Y8W
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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