捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
p%B w-z3[ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
F^3j8e{o /**************表达式计算器************//{\2N1]-`iKN
#include <stdio.h> M9ZzsLJoXj
#include <stdlib.h>9J!l3z Z*uMF
#include <string.h>*o``'z4[f-?-p
#include <conio.h>&h"M&A"c&C!dY
#include <malloc.h>;w[p\t:Zu
F%M]c's#M#j
#define STACK_SIZE 100
9MVs*hxP #define APPEND_SIZE 10Ii2U:l6\%@6{
Ye}9K#y?;H3r?;P
struct SNode{6^1EPB^'I}['s1Y.d
    float data; /*存放操作数或者计算结果*/
N+U3yn&_j w \     char ch; /*存放运算符*/ n3d@8Ht9CTF1Q
};
#d"T)w5j%l9p o6kD lV&~9N
struct Stack{
^ t }VR+z"C-~     SNode *top; L2S9l;~0y B
    SNode *base;
q0h N:_\c     int size;
m^#mb4h[ ? G0Qk2W };2p2E)}'H&ji
E2~$W%tzs_{P;a2y
/*栈操作函数*/KC V%p_
int InitStack(Stack &S); /*创建栈*/?J s'Q|P g
int DestroyStack(Stack &S); /*销毁栈*/,Z mym{!AHh F
int ClearStack(Stack &S); /*清空栈*/
W'V3U1o'n/Q:u int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/st4\'@-ZE
int Push(Stack &S,SNode e); /*将结点e压入栈*/
vh0b},Lt-t3fO int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
KV:H7ar 4e%^u^"h.j6C
/*表达式计算器相关函数*/f'OF y$`?K;K*\(E
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
"Q{-{-Go dH int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/aYv;V,w](k\0s:I9S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
m1X$b f ?'Ee`K/@ float compute(); /*表达式结算器主函数*/fX W)F]$h#}p
char *killzero(float result); /*去掉结果后面的0*/
+|B Ilm0N-qD +QJ'U f~3_5y
int InitStack(Stack &S) aCc,Q t{`W7p"pR
{
fTn JhZ(F     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));2Dai YLYc,Q$R
    if(S.base==NULL)
fE Ug'?"n1@     {7SY5B pyE"S
        printf("动态分配内存失败!");8?X7f'AdI)Q
        return -1;,Jx+m rV1`H8tI
    }
KA/b G.@W     S.top=S.base;
4S K6I n&l3eK5c%a     S.size=STACK_SIZE;
-CX,m1w Q$Dp     return 0;
F%W2s"Ww7d W }R?SZ#^?'J)^B R

*XH1f,L;[,p int DestroyStack(Stack &S)
lM0ai$}9E WR {^0z6d*|;^mL.{s&W
    free(S.base);
['oM bh\uz     return 0;
-{Q'QSi,F#J9WX }d,nZUf"q,U

B#f+~#Z)deX int ClearStack(Stack &S)W&v@)]f&c1tOe t
{
N5ZA8n:~2z#M     S.top=S.base;7Oa$s WjSJ
    return 0; I_/fG&tAR O_
}J5L'A{KSL

*aLx}$v)v F int GetTop(Stack S,SNode &e)Xl&F)s!~{"V0m
{
)u*}+f h)J%K!PH     if(S.top==S.base)
4e{?v/N.\ ~ut^     {,G n(z&B~A
        printf("栈以为空!");
Y4s7r/T.]/W.B:We [         return -1;?xc MB%} o
    }]&N Y x9d7GRjU
    e=*(S.top-1);
'PSsB8h     return 0;vX(t._mb
}
oF GI`j} G i GhzoO@ ej
int Push(Stack &S,SNode e)
Xm6^~*z)E u*\\9x {V2W],@d
    if(S.top-S.base>=S.size)
mU$NQ*i     {
mo-rlD         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));d,v:QK cA v8_
        if(S.base==NULL)r|q5MT]
        {-m,r9a"RU[Nx
            printf("动态分配内存失败!");
:Dy*E8RB9~3X             return -1;
EB@cAF8CLF         }:n @2Xg$^]$Se
        S.top=S.base+S.size;
8NS-?t~4t`)D,L         S.size+=APPEND_SIZE;
w||yc-n#S-f     }2G0r0JJy9P4dNB
    *S.top=e;
$MX+\,QZ%]$R4?     S.top++;n)q {w%J^
    return 0;
G3b'OBl0@4@ [ }y:^}6Mrqn

AB#A6uH!v^-g+v int Pop(Stack &S,SNode &e)-J)M-GVkC%B
{
~ikR(F Fg?     if(S.top==S.base)j6D#Y*jx8cA0j9z
    {o,s"~,c+g bw
        printf("栈为空!"); j b.c ~;Nx$O5w'Vbb
        return -1;*spz5|Rv E dK*n3o
    }RPLqm3J0h
    e=*(S.top-1); `s+V$q'x \n
    S.top--;
w\!_R` a?     return 0;1_M^9k1V/z
}
;D5o8Q M@3Lp? y&n8x ]? m$r&j
char get_precede(char s,char c)1e&DNoM$z
{ d5h-qV([U3E.O
    switch(s)
c \7pQo(ch     {
RqRk0R c         case '+':                 
9mt [N-X.S7S         case '-':
e n'@K(]              if(c=='+'||c=='-')
w5iB?E?'n'K                  return '>';
0[X3E5h6Fs"]              else if(c=='*'||c=='/')
f.b jKz!mV                  return '<';+a4b*w'F ?8M:C
             else if(c=='(')
1M*EBR9gkAl!u6Z                  return '<';
BVk/Zi?4O^k              else if(c==')')Z`*yahD
                 return '>';0W7H.mEX^6w.q/TS
             else &U X'b:w A+u"[
                 return '>'; DdF:tE.KSP
        case '*':#P JIZ} L
        case '/':
I_A+HH4i [&G              if(c=='+'||c=='-')
.tLA%G&_D mG2O5~                  return '>';
x4Q_3j k%S              else if(c=='*'||c=='/')
y;[ G'C/^2W-Gb                  return '>';;?+n b^~
             else if(c=='(')
};\,x:st!i4e5dw-}                  return '<';
(Zc tfx%~_?K              else if(c==')')
#{0f+`6V1Q0Nn0^ |                  return '>';
"L@DR b-\9Ov0``.Pj#n              else
` w)@hL e!k&K                  return '>';
~$a]DD6z w9li         case '('::l4T {-t {!q6bHn
             if(c=='+'||c=='-')
;o0b8^&M:V#W Bw                  return '<';y R?dQ4\7iD$U
             else if(c=='*'||c=='/')
xMl {:Bs4r+sI                  return '<';,`#_ H [3X7N"A r
             else if(c=='(')9Od0R(s5bHO
                 return '<';uYS0S)y0L Q`
             else if(c==')')o lv_ yl@
                 return '=';
H.C;yK1IC1C              elseN,P5H+O5?(rm-E
                 return 'E';Y4A-v f}D'rp$n
        case ')':'wl2F9Yz'U
             if(c=='+'||c=='-')
verhvB{;D                  return '>';
'GJ^VS9[t@              else if(c=='*'||c=='/')0XdN$fWU*\
                 return '>';
x~0M#`hC^              else if(c=='(')
{ q+gMhrO#~3k c                  return 'E';
:k;fp G|              else if(c==')')
P'WC D(P|&Dr                  return '>';.yL3MBo)a O9Q)f]E(C
             else
2O9O%{ P F#N&c |                  return '>';
Fe)IX4Uj         case '#':6@,C&dgwf-]
             if(c=='+'||c=='-')
VsS.Zgx?5r]                  return '<';
OPl+YR:lsM              else if(c=='*'||c=='/')"v4T t"to'T`6pT(h
                 return '<';2e |S%\%Kp g)g(i
             else if(c=='(')
"IZ MC._2D(h _x_                  return '<';
s\`C6BZ"w%^~5y              else if(c==')')/c,OCvcZ
                 return 'E';i#r \7iUG
             elseB.V ?5e;k!`^:G[ yP
                 return '=';V"c-B,sM jH0d#e)v
        default:QZ:P0YylH~;z
             break;
&Zzv d,]W,O&Mq[     }
C(x6oIP[G)uW6X     return 0;   
+U0g6@jZ7{)J%c5Sk }8d#n)xN*C'u*T

-C)m$@y.i5Z a3F?&h int isOpr(char c)&t]3N D_Y)dLl
{
C NPa.t(RY!u     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')+H0l)Rg"D:v6]
        return 0;%fdMm*XE@!iC.K
    else
-s:d:^ZG         return 1;
|Hv9x ~;K1k L6m K;TY }2~1W?$Qip9\.]L ?
-by dO4l
float operate(float x, char opr, float y)
7f \#d;E!l,I,^'D@ {
lT#Z8M+aa     float result;7h(Tg8wRO/E p
    switch (opr)CzM a*E ^` {
    {
S*f@ [6?T'~;H7^#nz%I X         case '+': 8\+i cZ&X,J
             result = x + y;
*eG i"tXH5a              break;L!Hp F*m
        case '-': !G&e:@ H"cu }a
             result = x - y;
}}&Q]#B1}0]              break;
:t#jL6Py         case '*':
f7H5G rR,AS YjV              result = x * y;
#d:A6a[We0WfD              break;
9Y:{mW7G3R         case '/': 0~)J)fZ_@
             if (y == 0)
UsX?C              {
|2Wnj|)K9Mz                 printf("Divided by zero!\n");
? FJ9|&@#ea\                 return 0;
P;lHb:@(J{4i              }
{4zf-pT Q7`XeH9I              else)Q:?2J1L;kD@j
             {#c7uhwgp*]9w
                 result = x / y;
hq g&^8{ }4A                  break;
#U-ryb v:v9Y-~-O6p4a              }
0c.OHK|Ag Pp        default: .f!cVJ.B\1~
             printf("Bad Input.\n"); 9[1_ D!W(QbQE7?2u"L0i@
             return 0;'\5J6n0Yc$g{.Y
    }5{A*?!^0f:O8v'y8[ [
    return result;g5aWa'uAX(|:X@0I*n
}    ['@]|)l)`

_p(J:Y2x float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/DQ+WN'nv+E
{
[es~\~2R     Stack optr,opnd;#TS'n6t(o-c+]
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;-Gvh\}ccbK
    char c; C3] D;?6~ I
    char buf[16];
h!LL1P&w     int i=0;
*|Eph,rJ h E'T    
-~oy YZ H"XWxgB     InitStack(optr); /*用于寄存运算符*/A4@;G"S)TU1[&Jg5v
    InitStack(opnd); /*用于寄存操作数和计算结果*/
q6Y#sBEc~     memset(buf,0,sizeof(buf));
+A2}5GfE G rk     v9O/u+U~j`I0r
    printf("Enter your expression:"); afhZ y5e7j|
        3Y&?3t!e I3EoF6a6F
    opr_in.ch='#';.`a-G-vq)_5C
    Push(optr,opr_in); /*'#'入栈*/:{6O,A6y\f
    GetTop(optr,opr_top);
DB,eM!`     c=getchar();lkTA0?xd
    while(c!='='||opr_top.ch!='#')gZ8o3g`M-e#b m
    {
e D6b6a}         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
~D:J!n0{1W^ i7h|         {l/E$]'`5^
            buf[i]=c;'{)Y2[J)F]$KpG
            i++;
/{)|(z@2y             c=getchar();^0J d,PjN s.B.S
        }
&|Y1cw:a         else /*是运算符*/8p.aX;B*Y.[:s5u5t
        {:S~(S1YuP dz,C~/Y
            buf[i]='\0';
8r x+@$l n Y z3` E)S             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
KW?LDYu$l             {8VIP ag!c8pn{
                 opn_in.data=(float)atof(buf);
't;V2MAE} b:~3B/rc6s                  Push(opnd,opn_in);5bCei)hL K
                 printf("opnd入栈:[%f]\n",opn_in.data);5]fB,LTR5E4k
                 i=0;
)L~xIw sw[                  memset(buf,0,sizeof(buf));
8T:aQ#w\b^             }
W'gp0OaR9E@             opr_in.ch=c;
K*tQH;hg"}.n             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ qB!b#eN
            {
N$]X(St                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
0cp|q%T,_L                      Push(optr,opr_in); f#hB~q e}:_Ls
                     printf("optr入栈:[%c]\n",opr_in.ch);*lNzI$L `4N
                     c=getchar();@4m7cuHds{
                     break;'|)D"yV3eDSq;pt
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/2ssP2uVA[
                     Pop(optr,e);5uI M,O@boVF1[
                     printf("optr出栈:去掉括号\n");
%YUd |X*u({%Y q                      c=getchar();
$kq8S2GU0rE&r                      break;
7G#y9pG4W                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
`TQ9nZ                      Pop(optr,opr_t);
7\M y NU9A`B                      printf("optr出栈:[%c]\n",opr_t.ch);
5X A3kEs8w2oW,g1B~T O                      if(Pop(opnd,b)<0)/|.YT{!^5C&\7D
                     {
b;k@Xg ri @6w                          printf("Bad Input!\n");l_Jn"_+g3R
                         fflush(stdin);
J Sex.b                          return -1;
5K#A$MGkY)_u2B$ih                      }&|&iwwB:m;lf!gC
                     printf("opnd出栈:[%f]\n",b.data);
@%{:I&KJ7Z xKN1ht                      if(Pop(opnd,a)<0)ITgDi:^9Ir8{
                     {
,KM+v3x D_)\-?2l                          printf("Bad Input!\n"); RP SY[;Mv `
                         fflush(stdin);bY O0cO7XnYmyP
                         return -1;
6^%n2f\e                      }7y_G$`&u;K
                     printf("opnd出栈:[%f]\n",a.data);
e3m7LkDG%d5FC/G                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
q!s[yTkAr1b1GK                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/9_p[T"t
                     printf("结果入栈:[%f]\n",opn_tmp.data);9[+a7`XgUs B,m
                     break;
|@'r8@ A"H"q#hg/`             }
d a/M2N{         }3n8Y _l4|/q:f
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
{"Qe6v9|~@]&k     }
-h;a [1azAb'C     GetTop(opnd,opn_tmp);1E%COc7}u
    DestroyStack(optr);
*s6d i6\8C&^ h6O     DestroyStack(opnd);dP$QNo7@ gu O
    return opn_tmp.data;
;qt6a xy!Z8I-E^3}j }1LF ] A1Y*S&?
!e"Su1f!h5pI8l
char *killzero(char *res,float result)
8h/Lgrq[ c? {
'J Sw ? k%Y%d6R8Z!@4e     int i; E)KaVD

2_O:V(_2Qn.G)W)`     sprintf(res,"%f",result);
!h@-fSNM0W6b9u     i=(int)strlen(res)-1;
lj-~`*b{     while(i&&res[i]=='0')
g*w)y x8o"j     {{+~p'SjpCp%g:kT$^@/T
        res[i]='\0';4EXX+me*hzh
        i--;
K1s] A P ]2I,m     } |lW2^k
    if(res[i]=='.')
"zw/p(`[H^ I(g l:s         res[i]='\0';
ew$D` l4QlC     return res;
A/yx5Z6^|T }
D`nXc s
o^5}"~w\^ int main()
'V lq:Jg vr@Uy {[#M S/G)x:I
    char ch;)iJH&_,Z aF_bPxc
    char res[64]; ktA,C~5FSl9p&trN
    float result;
$K8fJ*Bzr-^     while(1).h7gC4\[&d%L2q*g
    {U_}L hlM)t
        result=compute();
-p7@3\7~|F'O7p:b.f         printf("\nThe result is:%s\n",killzero(res,result));i)Hk_X'b9Rq;m
        printf("Do you want to continue(y/n)?:") ;#T|ne M y W?z{
        ch=getch();
F*L:M9GWg-S$p"`9H8DSZ         putchar(ch);
%sgb7h ~GW         if(ch=='n'||ch=='N')9h#BX!vhh2Y^
            break;
d9SZ1N9p7f l'n         elseW~RuQP,_'x
            system("cls");
+yo;e)h*]8V!s#@8E     }
L[$Xk+oP     return 0;;QDDC7G'f3@8k8s
}[/i][/i][/i][/i][/i][/i]`6Lg"@F2Z%r~2Tq

-~{cH p'M6qc h [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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