捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
*U#n:? bu2hRP 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=G/gc%Z}-x
/**************表达式计算器************/
W*J} B3r;c/[ #include <stdio.h> dV,BhZd
#include <stdlib.h>
-v6^ H_kCkv| #include <string.h>
5eau(V&aU #include <conio.h>
L"m;VDx8r*K m/q#Uh(E #include <malloc.h>
3FgC x:ga3^U
v3Ak9DU%H #define STACK_SIZE 100
T&e,I+h-N #define APPEND_SIZE 10D:bS)~6cg'\{
([n0A/b2n!brG%Dp^
struct SNode{z0y*pl.p
    float data; /*存放操作数或者计算结果*/
1G { i-j P _     char ch; /*存放运算符*/K2CN S$S!D(A&@K-v
};
9I)PY j6m FH9O
2K0q:l c/h?MA struct Stack{
w:E p`tQ Yi?     SNode *top;
MM;_'[p)~     SNode *base;
r#Y!p9A,w f&I?h     int size;
6r Z0qm8V8IH-s'E#W };
!RTTC&B)M {$M5x l@*D
/*栈操作函数*/p-O:p G+P4W
int InitStack(Stack &S); /*创建栈*/I"}[-i8H
int DestroyStack(Stack &S); /*销毁栈*/-y&l1v"Cbv t z
int ClearStack(Stack &S); /*清空栈*/H0]-MC,k/z g C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
e5`4rNiU] int Push(Stack &S,SNode e); /*将结点e压入栈*/
5^Vp jLk0}#p#g int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
HKe?!C
"[l7]6vA._}D!p4Z /*表达式计算器相关函数*/
L+z"lw7{Y"cC char get_precede(char s,char c); /*判断运算符s和c的优先级*/
q q4x z}$t;@ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/{M?5O f,re
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/w FSg#b}"Vhh$E
float compute(); /*表达式结算器主函数*/
H&h;S7?"F5_&Q char *killzero(float result); /*去掉结果后面的0*/ bp g:[GR
%U/b[ g.z'g
int InitStack(Stack &S)
v-I5^T:["j)Jl {
6C.R4e\(z:[V D#O     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));"{ I sj6H-{o/M6oK
    if(S.base==NULL)'PU7oS xD:B
    {ha6j,NG'q:~:gJ*j
        printf("动态分配内存失败!"); dq%Xzz9\%K!~
        return -1;9w(Rm qz9?
    }
WPt\6~6EX,C e     S.top=S.base;w` E2[0Jhv4L
    S.size=STACK_SIZE;~$JH3K;\x(W
    return 0;!O@?8OtUEWwR
}h5l c5kh/m"u

Gd&]7UjS int DestroyStack(Stack &S)5aL!?/wrR*m
{/T \mG3HB:G-v
    free(S.base);
a$f] n1i7g~"xV,p     return 0;
M!X p.~e+f }X m My8_5J3xzu7SJ D

-d5ySi"ti`gOq int ClearStack(Stack &S)
'j0rM"Y%d6G?2v {5Y%z,A%m0?
    S.top=S.base;
:q;B3j;\@+Y6F     return 0;
-W.M}%C6C/o3y }c+D/YQ} X3O3X!n
+sa*?3mAV-l;P
int GetTop(Stack S,SNode &e) `5H#J#E;uq!c1}
{
4vw'M#f LlY1\%PU     if(S.top==S.base)%o[&E3S0V'Qe
    { [{k.\N
        printf("栈以为空!");
Y_6o/tg&\g(l         return -1;P3l9t m N?
    }
#uD*SmN t s     e=*(S.top-1);
Zi-F+~"~-~Xf?YY5U     return 0;?a!w,az%oEq
}
3\$?`vT^ Er
%M k,h9rd$gi!Icv int Push(Stack &S,SNode e)
+sr4aatU2QPb {
`+W(A^ h"S     if(S.top-S.base>=S.size);_6E-y^wgG
    {:f(^ye|-uS?
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6gnbh-Vm5t7kZ
        if(S.base==NULL)
.Y,P;lbM6B-c         {
7_nFf/p!g4dG             printf("动态分配内存失败!");
$eN.vyb-z)FN             return -1;
6kY$Gk!Pw)aH         }
W;o\"e?H"S2P5G6`         S.top=S.base+S.size;
"ZH p m9HK*m]7p         S.size+=APPEND_SIZE;lP}Z.|/~ ax
    }"Q0n]1Bz2uZ{
    *S.top=e;UU2H7idI8V6I1X[
    S.top++;
)O&\_3_n~U     return 0;
c/c4P"r"wU:g }n:S\V0`0J.F)i
x.Ze;az0Vi1@#cY
int Pop(Stack &S,SNode &e)
/Km"i+m(]5Q {
!KW tIt8PA ~o     if(S.top==S.base).en^b'Bhx
    {
X#{O%pu`9~1I&S         printf("栈为空!");E9R.`/K5M
        return -1;/]*\ ^ M%? GDr afo
    }A*J/F)f6h g/U8p9K9X|
    e=*(S.top-1);ss v-}yAI7m1g
    S.top--;
dr2[*u0J4}X?     return 0;-h.D-Y%^&?)to
}(R x(C K[U

fu s;M*UJ"L$UE+z char get_precede(char s,char c)
i{mG L&oVB!x {
l\1}8l2sbUA     switch(s)] d(^4w vx
    {
wd2f@prr+@2B*R'K         case '+':                 (DFq!`-X2n
        case '-':
1H7n*y2d Env*] @n              if(c=='+'||c=='-')
%U/E e8~#^ EE0B                  return '>';
A1{W Y)NX              else if(c=='*'||c=='/')1S+M+w#u$JG4A
                 return '<';
:C+v6gq&E9P"VT"w!v7b              else if(c=='(')
c(O!k7z@h7Z }                  return '<';*L"[)?MbV
             else if(c==')'),r&N-|%wi V
                 return '>';
?3DcB p_;jA y |              else
8gJm(l(C                  return '>';
.p,{,aWN         case '*':
iZz3TF:X         case '/':7[#[1AD"cPT]7R O
             if(c=='+'||c=='-')#ujb'm,~m|'q6kr
                 return '>';
+}9OK{^}t{              else if(c=='*'||c=='/')
m_,c$} ? o*ndxv                  return '>';P(a\X-g)Bp*_[
             else if(c=='(')l!te9PPeh d;R
                 return '<';
b~p3b7N5D              else if(c==')'),R4SXs2|*J
                 return '>';Y`Zw.B D^ e#fkaB
             else
3];w&x+|;v4^ h                  return '>'; me1N&c I
        case '(':s1J&Y&NWk
             if(c=='+'||c=='-')mC7d4z[D ]
                 return '<';
`.F8Y$d?              else if(c=='*'||c=='/')
x1WDtc;i                  return '<';
? C y1[tI              else if(c=='(')
XT-h K S7M?n                  return '<';
*N$W[8J.hb&i1y.Z              else if(c==')')
o7J s b-G Y                  return '=';
Y Z`m'e t G              else
S'q9^:O-?5p8X@Hd                  return 'E';&?$g.si3nz"d^Z
        case ')':
3r@8Ae$h0z*U              if(c=='+'||c=='-')
{$MMh+] N1C.av#BB3b6H3O                  return '>'; hwtW9{+S3Z$l$c;iz
             else if(c=='*'||c=='/')
im:lF;`X                  return '>';(Lh/d!bi)\
             else if(c=='(')
LtroX"W!p;o                  return 'E';,S3N9K f,\+V_3@BSC
             else if(c==')')
!^2a B9@ k                  return '>';
H&@ ~I1IF0k              elseK(t ]6zWs l%[
                 return '>';C7W]wa9S G
        case '#':
$`9?7Y;p|4Q              if(c=='+'||c=='-'),I(ToFT~s v
                 return '<';%?v1T8FI_l
             else if(c=='*'||c=='/')
N2z{^I l                  return '<';
tF_oM-U3|              else if(c=='(')6z'bs:A%^8AMNs2c4i%u)ah
                 return '<';
3LM8|}sf8KxP              else if(c==')')
:fTF:dk2OG [I                  return 'E';B5q4AI9\"B,Y)K
             else
yHV_P;f~bi                  return '=';
R:wL:?@_f         default:
G-e:IhG*w              break;"k.]R7z,k h
    }
b5oG*?8X-T8h     return 0;   
W oK ESR }i `1zF:O ^&e.s!o
wErFy-m~
int isOpr(char c)}e^)@/p6z
{
!}3[/ZCS     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')L_z.^!~_ZO
        return 0;!z1xV/`$`En;?,d
    else !Q:VO3T4QX4a
        return 1;
~*\Xc mWd*} n }
YgzF _-a2| k_9r/xd:s
X5?i;tMHX4xa,c;i float operate(float x, char opr, float y)
f} D_R#]#q {~:T!h5URq*[b3`F
    float result;
6@*own_I#H[     switch (opr)
$Y{;xo%PG y7Y\5l     {+H3Ghi+Fd*C!v*Zr
        case '+':
l5s_ Gz.}"U              result = x + y;
%f:|y6PP`              break;J5Osbeq+f
        case '-': lg+Rz:J*?tzq
             result = x - y;
HF%xId.p&p              break;@f1Rm1i{z
        case '*': (t |!]lyGD(x
             result = x * y;
)^FTbaO fM|              break;
nN5nwY+Z         case '/': ,c#uYV)qzN
             if (y == 0)w/x;x8|G!b
             {
)S v;}PUgd6E                 printf("Divided by zero!\n");
Y:q)Ul E\                 return 0;4bJdG6H0~5g){b
             }
2C Q#_|2|C*l&}+UD'U              else
d\$iS `2Q              {oOx3Y2c&h
                 result = x / y;
0F"xl;N'Kt9W,Y                  break;n3Q-R5ul"H^
             }*HD;u"O+ruZ b
       default: $_*I7|Ss"_
             printf("Bad Input.\n");
U9fK8w%o4uVT              return 0;:ou,f+so]3z,udn
    }
U _T%Ib1DB#Fg/D     return result;
9?/X7ki Rq^ }    yJg;`4Z A;F

g"D(uN y:Jm(h3I float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
*s0[p U{] {2O-l-\}pK
    Stack optr,opnd;
G:Vk P'T l4{[:`1Xh     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
dG:m2c!g%T,A[     char c;
8N7? kK2g)`W"h+o     char buf[16]; m/b _D#`OA
    int i=0;
I.EcvvSlq     8W/BK1~wK
    InitStack(optr); /*用于寄存运算符*/Lu3y4Z&B n1w&W'h'X
    InitStack(opnd); /*用于寄存操作数和计算结果*/
U'D(z/o B-n6zo1O)x     memset(buf,0,sizeof(buf));
&HDU!?9@*S&t`P    
D q;mui     printf("Enter your expression:");
AuZy/F         7G:KzSZ$`KW'ug
    opr_in.ch='#';D:nNB9w:UL otmf
    Push(optr,opr_in); /*'#'入栈*/
m/XO%U1w&Xh     GetTop(optr,opr_top);
v i1wIE'[4?     c=getchar();
,A @T;AK     while(c!='='||opr_top.ch!='#')
(f bp'Hs6~     {
6xQ,E9MK(G Zq         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6mFbmP ny K8O!z         {B,FEF;S*^ bG$j
            buf[i]=c;
/Y0T/?3f/A `bX:fpe,FY             i++;
u#ylK4M#K             c=getchar();
0q0N k&~*Mz         }/z |@/Qs:k
        else /*是运算符*/o)cGy-@9w3C
        {
By;@w/k;bsZ             buf[i]='\0';
QW t5BN.D8CeU?             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1X7O R Se9q{^;x
            {
$F[9~P;w&?                  opn_in.data=(float)atof(buf);xT^Q6](oGqnp/]
                 Push(opnd,opn_in);iz&e-X?u
                 printf("opnd入栈:[%f]\n",opn_in.data);U ?Y)P:lb/hr:x [
                 i=0;yvpZ2[sk
                 memset(buf,0,sizeof(buf));
E!@fa5df/VK#rMt             }n[H6tw`4Fgt
            opr_in.ch=c;Rt3cs,?Y;JD
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
&^r+]HJ             {
^qo p_                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
Xj/I$q9d$q{                      Push(optr,opr_in);_s}9V$M Hd5~
                     printf("optr入栈:[%c]\n",opr_in.ch);
D)M h+IK                      c=getchar();
$S4\OJ so3M                      break;
*L2]!j r){+E                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
OI!T[!`xL!Wg1N                      Pop(optr,e);
vbrPPmQ                      printf("optr出栈:去掉括号\n");
cfG@3@BR W                      c=getchar();:Hwu)Re[}
                     break;
5T f cI%R.iP                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5[ a!}A:M&_?Gwv
                     Pop(optr,opr_t);fg\lo$y L
                     printf("optr出栈:[%c]\n",opr_t.ch);"PHy ]K ~ [P
                     if(Pop(opnd,b)<0)@8wh,^ z.y*Uf
                     {
S'`K d-M7A0e;\g,u                          printf("Bad Input!\n");
l7xS:^"w+E9ivS                          fflush(stdin);/db#v5v$E%t.b*Z
                         return -1;y(?5O\)u
                     }-B1b'F+w4@e
                     printf("opnd出栈:[%f]\n",b.data);
j1cz2K6Wk                      if(Pop(opnd,a)<0)
%Q8G+E J/kX@ H]$e                      {
o.}7r~'M^t                          printf("Bad Input!\n");
eR+^{nM                          fflush(stdin);|&fV5T \f'cRI
                         return -1;+p-g3i:vru'j U?
                     }j\9I9z9S%W7B
                     printf("opnd出栈:[%f]\n",a.data);
)T-k E!H4AV r5u                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/~ }W#eC6?\J~*u
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/'LbMV8yeh
                     printf("结果入栈:[%f]\n",opn_tmp.data);/K9K&? S|v6{ Q
                     break;"`2|%p e cXv R K
            }3GM(V%a`g/m(x`5P }:U
        } A6Ek Q4]8s
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                !u$al)F&Y s
    }
&n{F i5p*T];M     GetTop(opnd,opn_tmp);8Z*oO'Eud h
    DestroyStack(optr);
6Pzk!a8bx3o     DestroyStack(opnd);QqAB.Ab w,s hK
    return opn_tmp.data;
W.s\w&~6P*qN;] }
}U2u2Y XR?#E%d] 8Kw1h)u4R ^9Y
char *killzero(char *res,float result)
5k"_k"[ ||0v%gc {
+N9g"`i(U S_     int i; ja5YJ'\ L-q t+{5\
!X sL{;va6L)_&Y R
    sprintf(res,"%f",result);
`7P*Mz;GD9UwI     i=(int)strlen(res)-1;m Z\!pC6~s
    while(i&&res[i]=='0')
s[k7RCy'A3BI     {
b0x,x'y7v,{pn'_         res[i]='\0';
B['g w8\&_9Z         i--;
6L7C3B ]? T     }cJ:Zd{B
    if(res[i]=='.')x0D2s3nZg
        res[i]='\0';
k2e+D9F]PKw%A     return res;cO([%^/K[)tb
}
-]4TpoA$KS0xu,S ]XX2ibe*_#j8d%z
int main()
(Q8]5?8JnNrCWe4C {
:I!Cl c.|     char ch;
f5XMG5X     char res[64];
~{-Lwg[9i     float result;
VQ]i~z!R     while(1)5? Oq Rz*z1]6f
    { Hc3Ix3\B
        result=compute();
8b3v y QS9NLi(T2^         printf("\nThe result is:%s\n",killzero(res,result));
UnrR-L ]         printf("Do you want to continue(y/n)?:") ;
/t7pF+}%I         ch=getch();
6?*p9`ce8R0e Y         putchar(ch);
,MYq,H l(bN         if(ch=='n'||ch=='N')
;K ^0Y9Z,?S Z             break;
K6C,M Q'PUyrni%lE         else4N7p*Z-^I@6S
            system("cls"); t KHE2X HY$I(eB
    }'F4d?{!Z Y ^Y
    return 0;wd(z9l?0vDB
}[/i][/i][/i][/i][/i][/i]Y u7{$i.mC,QPp_8Mi
{_4l0z-y&e mG5q
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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