捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.@ }7MAXCWSn
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= ReRb} u+f:Q
/**************表达式计算器************/2rPTt2@!c8oV
#include <stdio.h>G)z Z g] C:l|
#include <stdlib.h>P9]a n3Ux;NK
#include <string.h>-U'w6U\Z-B2Y@!@
#include <conio.h>O:Mz Rfd
#include <malloc.h>
1^ ltU a9Z;@Pb N .U!j2p3rq2P
#define STACK_SIZE 100
o)}zC0t KM3w #define APPEND_SIZE 10
h6uTt ov}BL %dP |-`g%Z
struct SNode{
u^:|e&}     float data; /*存放操作数或者计算结果*/
__!B-Sm'mw4U     char ch; /*存放运算符*/
c!X w;MG w(d Y };4v ~p$`'_6St
[ b5XL6u,b
struct Stack{
Z1x_$@9[9^"S;H     SNode *top;
5D!|k h-W3j%l5E;G     SNode *base;8J:y,OF LvbO`
    int size;YHB&O L-a*b9B
};dH Ry1} f'|h_n

M:I6V6jP)Tp.m /*栈操作函数*/r O+L J)S'J(D``
int InitStack(Stack &S); /*创建栈*/
%\;|T)yh3k.[ int DestroyStack(Stack &S); /*销毁栈*/
ekVz_\~hV int ClearStack(Stack &S); /*清空栈*/
t `-Qi0x?{ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
D/|YQT!I-m int Push(Stack &S,SNode e); /*将结点e压入栈*/
|v/R9q$B!H a4cv int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/*Ck KG~oy GL-g
7w`7I9H?"cb&YM
/*表达式计算器相关函数*/
6Xg6a#G3S]|4o char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Y L vH+kSD int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
1x`K&T7C(Q float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/'E0K'G fc*P BMz
float compute(); /*表达式结算器主函数*/
1A+fEs)? char *killzero(float result); /*去掉结果后面的0*/ )c/XM8ek%\!w0]N1D
Z,~ Y3X|[;B
int InitStack(Stack &S)~bOo}C6@Uf
{9N"ZN7XiB I
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
5JKF!Req{+k u Z     if(S.base==NULL)
LOA,t2vo-f{&f@]     {7Mb$ee*C5J
        printf("动态分配内存失败!");"mUo],biG,g8^.V
        return -1;!rn.T_;V H[X
    }
:B'TI(D+E2l Y(C{U     S.top=S.base;
X@:R v9g9@ D"q     S.size=STACK_SIZE;)T%RE/j-aD,t].C
    return 0;xi.};nQ2s7V$p'v
} lnsO+]'^%X9S

K(P-^yi int DestroyStack(Stack &S)
.v6cX:`gKxUM{ {
*GlX,Fjd t     free(S.base);
8b8y,}RR3F])\     return 0;Ap)P7A uGxht"c
}
L0Cb W2tm?.]B
l l,i H(_"S U int ClearStack(Stack &S) ^*n#a"h)F
{5YZ%bqH
    S.top=S.base;
rkRXJ.X)r     return 0;x{2e] i V
}
4v SE o3\-`r
A+U1p,W"R int GetTop(Stack S,SNode &e)5ZP|5PYR4J7H
{,w{YV$z0U @}Q#Id
    if(S.top==S.base)1tih {4vG.zo
    {V1|e#z-VW/eV
        printf("栈以为空!");f&W)XZZ2?bT#@q
        return -1;
n;VsaH/Kv+J     }
` i|ua5n     e=*(S.top-1);
&]"X9a8Eks     return 0;
/thr7u+H0|'fU }HW g@3dPZ

X*E0j\r"B^0^z]0Jc int Push(Stack &S,SNode e)
L8dT7hFz { C#W1H:fK+F@
    if(S.top-S.base>=S.size)
(f4Qp/}2Id@e     {
6rq [9@-i#q4k         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
z&pGD$Z2O         if(S.base==NULL)&@0_6aJ `,A)q
        {Sv#j,{z XK R{
            printf("动态分配内存失败!");
0XR7l1m#}CS-C'P             return -1;&vT+KL VS5{2@
        }o9o/| PjoFhH
        S.top=S.base+S.size;x&lG^!phC
        S.size+=APPEND_SIZE;2M[+XT:V5N4C
    }
(^~.Zt0u5[2\     *S.top=e;
.k,v!?(W"Vq     S.top++;
#G"G yh9tLk&U     return 0;'RT dK)^"a9C
}
g.]8M0Z I&cJ 5X-^%aH-N tUCKL*{
int Pop(Stack &S,SNode &e)'og,H6uk W
{
1K*m Z4G[ vK$[     if(S.top==S.base)5u6Rv7O!Ee(x M0g
    {
c&^:pM3Fe&gY.o         printf("栈为空!");&I.b ]e-_u1V+N
        return -1;
R R*qD4{6|     } P/jv:|zs
    e=*(S.top-1);ei6z AfB)na
    S.top--;
-X bS[*x GZT F-U     return 0;
W$ArK5w-oO }
U8wng Ny{1g)u
9Z1c2vv!r~ char get_precede(char s,char c)
IjF5TC'UZ {
]ic~5J EGb1H     switch(s)
j-u'`a&Z4W:m D"|N     {&y#s7sG}P^Ry
        case '+':                 
'ltwcxiH7x:I1_W         case '-':Ri6z-} ^ ^ fWY
             if(c=='+'||c=='-')L.Dy#CW!Ex
                 return '>';
@ sH | l^ XH              else if(c=='*'||c=='/')
1F2os?c_ T                  return '<';}[0t+[sFO)q X w
             else if(c=='(');}U*PS1xr$L
                 return '<';
D)hq2W:E^              else if(c==')')Iif7yp4[-X,N
                 return '>';
!zek+zmq0n              else
:ZZIcT$n                  return '>';'L2B uu9R"x]0]l/u9i Q6Pb
        case '*':
-YLQ;Vjm*D         case '/':W7?'MsC b^E!W k
             if(c=='+'||c=='-')vt vF&j5J!E%l-ju
                 return '>';
.d p(X;U&H;D z              else if(c=='*'||c=='/')
6m[+l({,nn5Tsc                  return '>';$L M,cG'ri*E^
             else if(c=='('){6eQ6`%c
                 return '<';
|S M A}              else if(c==')')s7E'~ x%X fc#m(\,?(V
                 return '>';
G.Su$E@'C}              else5Y}#Ge0@.H;S8O
                 return '>';6p5I N\ j ^m
        case '(':1H#Z ^2}8Gv^*A4E
             if(c=='+'||c=='-')H3SgCal+]K
                 return '<';
9xw+P7N9Vr              else if(c=='*'||c=='/')
6a\t#D TzC F{;Z                  return '<';
h:Vld zX!N^g              else if(c=='(')Qd`8b)y b
                 return '<';2`"IyTA
             else if(c==')')u!sU Y0S!B/?Y
                 return '=';
T;Pn9[ uysi              elseq8h,a;Z9~T4Q
                 return 'E'; R$Tu aG!j
        case ')':
0X+b2J;iV-_)_Ta#p              if(c=='+'||c=='-')IT:r;ldv)p@K
                 return '>';O8@7DA O E
             else if(c=='*'||c=='/')
?3@ y$G5SIZ                  return '>';N5L sX RSH M
             else if(c=='(')
1YkpW1}0}                  return 'E';
L-C!|zWk              else if(c==')')%w6L8F;rHby-Z
                 return '>';
XDB9hIW              elsej)G`'gM m
                 return '>';g9h3F0RMV,^
        case '#':
DkJH~ Z X!_#d1`h              if(c=='+'||c=='-') S1Gg.~%i&[xV vDD
                 return '<';
zN&W0gH2@"Q              else if(c=='*'||c=='/')
R$B,A#x@}                  return '<';Dgywc sy"R/R
             else if(c=='(')
JO%X4W"KM                  return '<';
D^$\%xQ1U|,D              else if(c==')') qI}$n2y
                 return 'E';
3l{$M)R(O{:T,l              else
Yg&U3pK'r#_ A.z7X                  return '=';
vFl.U5wC8bD         default: r-qPIP.j
             break;"@] bz(_;BI4Y7Gr
    }&TB4Y5bS1EL
    return 0;   
*^C#R%Q {4LJ7zM"f }RG3X1K,R(v:S$c
m-w)N _uJsS |
int isOpr(char c)
7o ND%B'E!d {KR tH u:Kj:TII
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/H#M'o%j9Jh r_;aNe
        return 0;,cn s$g WUN0W/|.DM
    else
w/h#qj5G;p1U8_         return 1;.uV,C|r(G
}o(Q(u7@xx I
jW)d;Ur!R
float operate(float x, char opr, float y)
;Xa@9YJ } P:h {q [L3Rl${R @f$gc
    float result;
V2o h;IJ;nfm5@     switch (opr);YI ICG9O)G Z
    {
9uBqQ~Gt4~^ S         case '+': (t-L*?g mX,qH
             result = x + y;o9V]e9K A!{
             break;
*}'v*Af?9W7Ij;YL/w         case '-':
:JgYrZ x\Q1~T              result = x - y;CfK,f?9XT~
             break;
+NJ6O%D*]         case '*':
^"@Wi!~T              result = x * y;Dr|+YqUq
             break;
"Wz0J+ca?Qa6O!P         case '/':
D8]'AuLg2p M.ia              if (y == 0)#Q`q+Vh@ Q2i6m)Z
             {)FEiOK fl*ZeHC{
                printf("Divided by zero!\n");
h2T3x+_&^,B5I1Nj                 return 0;*hTBup;y!W
             } dT5~Mx!| sh
             else#oE8_Q2MP
             {
O^B+x4m3~                  result = x / y;
9o"C@-C\ OGol1e                  break;
h.jK+z*[KHzi              }&n)H*q(|oFX
       default:
O SRN B2Y2N              printf("Bad Input.\n"); 8snBS/c)~]P
             return 0;n.Zv/C7W n[[^g
    }
B4IX,{l"k:p     return result;} W(o.y^^iL
}    &cC0[re

y%q4x3P8V},]S/e float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
mApb P$J,^Sh;Hz {
F~m`g]     Stack optr,opnd;&r!KX:W7Y
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
,~.I#uC2Nx-nd&]     char c;
XtsvC     char buf[16];
(wTy6C)ir     int i=0;
'Q/? Q n1_VG yQ^pY    
Se'wI}     InitStack(optr); /*用于寄存运算符*/
3c"N'^ Ox6t"x(^1tT     InitStack(opnd); /*用于寄存操作数和计算结果*/
Hp^X'N1h     memset(buf,0,sizeof(buf));
q#O D T8M     @ mp q3XmH
    printf("Enter your expression:");
]v+^1Z6[ Y V^-f^         "T`2]2h?_L!d HMAs
    opr_in.ch='#';9C#?zS^
    Push(optr,opr_in); /*'#'入栈*/
,?Qs)dLO\d     GetTop(optr,opr_top);
H;Qz8g)c:Ga     c=getchar();
c6d{f Q5w     while(c!='='||opr_top.ch!='#')_2SvP"D @-R1{ sy
    {
gHU8Te_w)Y         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/Z-@6w*md2U*v$q
        {cu1v^rA C
            buf[i]=c;
~1n%gi!M             i++;C0};c;m VD h
            c=getchar();+NQy Zk(R P
        } D-a JN)m
        else /*是运算符*/~t2f"\;ht?
        {"[E7d6b4}Ly
            buf[i]='\0';
{6GM*m.HY             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/Du M'z4`
            {^,R Ce#Vx?
                 opn_in.data=(float)atof(buf);
LMp:|\l?]                  Push(opnd,opn_in);
P6h{ ^;H\7ywS                  printf("opnd入栈:[%f]\n",opn_in.data);
N8m;z[ B6tw6`O4j                  i=0;
B7D#|S.I|                  memset(buf,0,sizeof(buf));
@"s8K)e+}E             }Gh&t?%mk
            opr_in.ch=c;5r$p Q2~v%h)DW
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
{#Q']vbl-t             { f@.G:bx R
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
_p"{:NW} t"l                      Push(optr,opr_in);
8aA\LkVW$n                      printf("optr入栈:[%c]\n",opr_in.ch);8G[!d:[$@kW
                     c=getchar();a3`i'A f
                     break;j_r#W,|
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
eHhh'M@9czx%z1J                      Pop(optr,e);
| z)AL(BeTkS                      printf("optr出栈:去掉括号\n");d s"UPG` K] d
                     c=getchar();/fI(N6t1O!D
                     break;Qq SX:P`H4V$V lf
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/@ Upz T'Z!W6e-O*X
                     Pop(optr,opr_t);
V6r!D)p8P["s                      printf("optr出栈:[%c]\n",opr_t.ch);$lE h1Lk0x'D
                     if(Pop(opnd,b)<0)
6Y!@)A&hQw4k#SPX                      { i.{ Y5[+R'| V%v
                         printf("Bad Input!\n");V U#NuYJ#X
                         fflush(stdin);
B:b_Tq:D+N                          return -1;`B&VvIZ+\%`
                     }C2}$r_"OY5V X'O,cR
                     printf("opnd出栈:[%f]\n",b.data);:sg l"Kr,o
                     if(Pop(opnd,a)<0)E8}5] ot-@sc'\
                     {"dj'qQ.t!_"_\7L
                         printf("Bad Input!\n");
osY8sx m                          fflush(stdin);
L;gqb j}W xt"H7a                          return -1;^GJ+yAq
                     }!kP @} K%Q0O"U
                     printf("opnd出栈:[%f]\n",a.data);Co A7E!|
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
(w8]"Z Q)a                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/,KW1\3B&`hQ6qd
                     printf("结果入栈:[%f]\n",opn_tmp.data);
,[9m_5mU j z'P@                      break;
PH r|cp"P             } Ps![q+R0P
        }9O8oG2~/Ae"tX
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
(C5^A.x"E-zS:[     }Yv5n:^-L&cZ5d/r
    GetTop(opnd,opn_tmp);
n:G.]zR.R]     DestroyStack(optr);
HN |%Zi'r     DestroyStack(opnd); xY)E$cR
    return opn_tmp.data;;n t3NXG
}'iwP/Pa~2m
zYL9~b(wY
char *killzero(char *res,float result)dJ:Z;nJ+Q/|"D
{
T3sC9R8gC4WG}     int i;Y,i}K&W
i(xt)h`O
    sprintf(res,"%f",result);
#~b5y,Lj R2l K     i=(int)strlen(res)-1;H$W g'l*NT
    while(i&&res[i]=='0')2D/|[g7[
    {
u4_2R"F$w"Nh,} `+X\!]         res[i]='\0';
5d6^D V.H OYK E Y         i--;p,B!SMo \9}k#a[
    }*j9Q/d.zv0V
    if(res[i]=='.')'x)lF-p-d ]
        res[i]='\0';e?!h5Ds3W$_p
    return res;
L0FYR7O} }
9sl#ooF3XN+]2h2Q ;xW@IGc)Imz
int main()
0NX Q$q%R,ow {
h5GlF@     char ch;;f6ix+F!s s\:}
    char res[64];
o9T0k"B [*}&p-~l     float result;,^k9P2\@n5M4G
    while(1)
f^+rf._.A-b+Q     {"i%\&W9g R
        result=compute();Z6{{~$\ NTu1C
        printf("\nThe result is:%s\n",killzero(res,result));3Fz"W:R H4F?1@ E6j
        printf("Do you want to continue(y/n)?:") ;
0Z A9N:x6C2Iw         ch=getch();
F.|KQ.b%@         putchar(ch); B3x:FSx Jd*F
        if(ch=='n'||ch=='N')lQ2b6jX
            break;
A.vDa8|\ {H `         elseV F5X0p*o t/c$d.P
            system("cls");
*uz \SMu     }k:kMv;wW
    return 0;#ZbM"f2Y/`.`g
}[/i][/i][/i][/i][/i][/i];~:I:m;s&] v
$[r1K0a4Q,?A!Hbia
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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