捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
y{d"Ef$iDA 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=.h'y7d9{K%~;T1d*E3b
/**************表达式计算器************/
~9DtMk:R P #include <stdio.h>
)\O?Y"j'b #include <stdlib.h>
Z0pX9a(BVgs #include <string.h>
"z7Iy]DF #include <conio.h>.^ eRz j1F*Kh7p2|5bPn^
#include <malloc.h>_wLP/m@

IKX]b #define STACK_SIZE 100/U @~c)e0d
#define APPEND_SIZE 10
:J"d}k_
2D0vZs&wn struct SNode{
A_]%fCn9q     float data; /*存放操作数或者计算结果*/
5le K(U h*W/m(xU     char ch; /*存放运算符*/S(Y6|c.oU
};4?L)B(h"E(E
a D@(jv-w eh
struct Stack{v8{.p[]a)^
    SNode *top;o~G5B5B}%^&H
    SNode *base; Fo ESl
    int size;F UB:T2yR~j'rtj"ay
};RV/y9co

%J*T NYo /*栈操作函数*/
^9^)DP1A,h]Om1I9F a int InitStack(Stack &S); /*创建栈*/
'O4v.?@&hrP int DestroyStack(Stack &S); /*销毁栈*/
`,EPq Ya int ClearStack(Stack &S); /*清空栈*/
Dp5R1o-\5}\\SD$] int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/h!k%O5Hb3?{1R,N s
int Push(Stack &S,SNode e); /*将结点e压入栈*/
S{3H a"Q6R ZwJ1O!f int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
E3C'BA#O&N orkYl
SRu0j#W'Va /*表达式计算器相关函数*/9V"w'T Vy j
char get_precede(char s,char c); /*判断运算符s和c的优先级*/B.S:gmh+Q(SQ{
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*//Jjg4G,y"Q2m'^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/A#Y2A6Jz ~
float compute(); /*表达式结算器主函数*/
8rxj$y#H char *killzero(float result); /*去掉结果后面的0*/ *kDKeJ

[O2WQ|h int InitStack(Stack &S) IU8Kvz8VeI H
{(mBR/Y/_$}jn
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6l;|2uv U.Tr0HA5rq&j     if(S.base==NULL)
G Y f#B6M/a2f     {4c{oj-NW.]'u `
        printf("动态分配内存失败!");V_-BZTfOD
        return -1;
J-@!k sv:jB     }
.JtXg&RM{ ?Ne     S.top=S.base;;ZK0yvdH
    S.size=STACK_SIZE;7Gc)P(O [4C i
    return 0;A^#bosO5x~
}
s_l8m b^ i
4P Q ic.n c0l int DestroyStack(Stack &S)
~(n7xNVM&~1P[:S { Al:~/g G
    free(S.base);
WJ!jUbN\     return 0;
jj B2Q2O4I`-lO }g hM$w+W*r5Z&d

Zv#V q tv%q;CN int ClearStack(Stack &S)q9b-Z Z ?:f
{(L4p8vch&]L
    S.top=S.base;
.C5n8g6S@;L`/H     return 0;
;Hg*fj{c Kz }@ \b!@F1GJ
]iAE,ia
int GetTop(Stack S,SNode &e)
S5}-i)HZ3V {
%{)H9zF(d8R'|X8?+t"om     if(S.top==S.base)
$`@"{'Ua T2q~*Y     {6T$F qc%g4Zw;N
        printf("栈以为空!");
,}8`;}2I?+fI2E         return -1;-xs FT+HA
    }
LW d/r9C le^     e=*(S.top-1);8f.Fl;\.Hkd k[t2c
    return 0;
fbU'|7n }
*iR1GWg}g9J`)]
A+JHCM int Push(Stack &S,SNode e))|w ?P%r3Z!v
{
dH?:fkU6p%W-@ \ g     if(S.top-S.base>=S.size)
?mDO!_D ?     { ud.v%~k$@,\+|,?d,j)I&T
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));A(]YU/K8U,r
        if(S.base==NULL)
.k(r;B5Z(iz@W         {
tQ\5dk;C             printf("动态分配内存失败!");"@0S$s;l"O7I{ _1U
            return -1;!EK8_%b?+G}
        }|.L}JDY jMI#S
        S.top=S.base+S.size;
ymEG.X L*X         S.size+=APPEND_SIZE;
Gf^7x;^j3h     }
e1he\o0H     *S.top=e;'v!cw.E0E,be,Gq
    S.top++;'[5Z'I7UU3AiO2cN
    return 0; K1q&w{4_+UGC0{t
}\9G@Q+S4P p Z v,V
7Al;l7G}D;xA
int Pop(Stack &S,SNode &e)%jz |i|*e
{
/C5V;F YF;Jx     if(S.top==S.base)
)co&l6{H{9W     {
D*| hA,r$j }I         printf("栈为空!"); a Uc t(sr
        return -1;;q'i'h [A~+u0s.iTg
    }B5`eTr:D_c
    e=*(S.top-1);
IK.Q-rJ2P0Z5B     S.top--;
$u7H7vbVo6K1n     return 0;5dS.P8FlQ
}sL3{#@i.F`*?'ya
7o+dQ&d KGq
char get_precede(char s,char c)QE;r0i6pb
{4Bd7t'KO%A
    switch(s)XxeL@5PN$G P
    {;i B'a0wR$w)gU
        case '+':                 Q.qE6}Wo|
        case '-':/qn"t+L:U T w
             if(c=='+'||c=='-')
M:t}?ze S                  return '>';-uK^amuro
             else if(c=='*'||c=='/')
n3n#bzMV                  return '<';
EC3A"mP;I(|k              else if(c=='(')
!h&y!w&j5mA%m!o['}                  return '<';Q \v$^rdC
             else if(c==')')
-V5yY!eGI9cOe                  return '>';
FW'XrA+[RK              else
9p$`nN"uMf6C                  return '>';
O8}n2ox#P%S         case '*':
Z0P2Y |Z8e#]BS         case '/':
%Y0k$~E\7x(no(rY              if(c=='+'||c=='-')
U%~+Y V$wA-WV                  return '>';
{}4Y7nn sX              else if(c=='*'||c=='/')P AD J+YrV8L'@E
                 return '>';
hy!TjD6b"qld4i%O              else if(c=='(')
TFJL/^                  return '<';?;kFDtSx.} a}S
             else if(c==')')
\S OtN                  return '>';h}ysv
             else!}X5vcUY2YA
                 return '>'; }`p*iI+mk
        case '(':MH8r6K Vo+C
             if(c=='+'||c=='-')] tx6pU_-`"FO
                 return '<';
aw-a&Q!|W8J#l*}B2O              else if(c=='*'||c=='/')
2}9h,vJ+i FyV                  return '<';
ip4] B&qa7S              else if(c=='(')
%W'y8|c*W:B                  return '<';
H#Y+rO CJ8~~Bt              else if(c==')')5l2m L|-}*l
                 return '=';
DM-`4Y'|J              else
({ VMy$|~!q                  return 'E';R:qw"v |y*t
        case ')':k,yw!@{K J h b,NC
             if(c=='+'||c=='-')3\ C6MGr HN l
                 return '>';
&{N*@*t&k              else if(c=='*'||c=='/')tA:F6i8w`0oqQ(I
                 return '>';\L.V"Q#w,zU!z
             else if(c=='(').xjr;yg~"b
                 return 'E'; b2wgQU
             else if(c==')')1`#S/P%L'?7Me
                 return '>';.?*l4M hq/I
             else3KxgZ.C$Y
                 return '>';4p:wo ? Le{
        case '#':J%A*F6{U0iE'z
             if(c=='+'||c=='-')V,K^)Ci }`6_'^
                 return '<';$}7EHq7YWI6p
             else if(c=='*'||c=='/')
z%X;[2I7f7}#a,} t                  return '<';
Rb(C|(Tgv              else if(c=='(')`!U NG4pEo
                 return '<';
2P-l Mv~0Le              else if(c==')'),o-c_&V'B:Y@H
                 return 'E';
A n'bjmD.a+`y              else
f Jm5x'l d|7P                  return '=';
8M arp4FcB4I*Eq0VW         default:
2Lt:l:A` ~j              break;e1v/cL2q
    } }P&sz M0E
    return 0;    XeO-^D
}
1BW)t2h y5Ho (X&}%~!` \$qDdnt O
int isOpr(char c)x(fz||_U _J
{j5^+H b6X/h
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
,}q t ~9l         return 0;.hYI%_v%zC
    else
2}6C-e#W{r1E         return 1;:r,`@M+ED
}
`fQX N"J !FsSC F)J
float operate(float x, char opr, float y)
~*Apq? {
u@0~%vp3D2w y     float result;:~2BSX/U
    switch (opr)r"WO0lO)}Pgn
    {.Z)]{ ?;\$L
        case '+': oN6e?/_oe
             result = x + y;(RzDDA){
             break;Oq+{)bq byV)EO
        case '-':
n;MA.`n;y              result = x - y; lnp&_0?
             break;
A t8gA"w;i"W%D,P&p%^         case '*': R|vY5P E(sqe ru
             result = x * y;
O*W$Juv,z8u1s6HV              break;
Y wvn/tMV ?g}         case '/':
!I%w1dm.C-}'wAhv              if (y == 0)$M6G.O%J*i+g1g
             {
'W0q4AW,ZM^,E                 printf("Divided by zero!\n");
;k$zs)t.Kbge                 return 0;@o moQ2b6Ek
             }
:E+wVQ+at#yJ{              else
$_S ?oqH;`d              {
v)]z&Xp6DPI$K2f                  result = x / y;
gPSy EAM~.b-_                  break;^Mws*L?&H#v8F,J)Fe
             }
|.A(uB.Bn O&` K        default: Y.nGC\ ^+_#d
             printf("Bad Input.\n");
LPb.W3a k1|-Z kw              return 0;
` jb/QLO,Mx     }#h-a4r,p'e Ay
    return result;s2N)C Ph"kR*YFB0@
}    5g'`K d;Z4jru`f
,nU5MAA,W
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
e$S2Vo0j4A$|pe4m {%YN/rc2eq?m)j?#A
    Stack optr,opnd;
d,E-cCd sL*eM     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
kZ6E'u/\ n P o     char c;1~/yX$|4jkj
    char buf[16];
U.HY I?,x%n4h+z     int i=0;
EM6AK'HR    
!l(q#bn;`     InitStack(optr); /*用于寄存运算符*/#yj;S6^ F#N
    InitStack(opnd); /*用于寄存操作数和计算结果*/2sV\IZ
    memset(buf,0,sizeof(buf));
*\ y,rC"a!K)_z     @Q i{,h%B
    printf("Enter your expression:");
H]&c,Z.u)q/s         
j V6xF1L0nt     opr_in.ch='#';
/_;A%m9m~     Push(optr,opr_in); /*'#'入栈*/&w!r~BZ5E H
    GetTop(optr,opr_top);,Jjl^9U&J${
    c=getchar();7}e8P6yeT},L
    while(c!='='||opr_top.ch!='#')-B{.k^;{@K#m2x-L
    {/@+jAh7Y
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/q#D%w:v%G0F
        {a5z.L*O#\9HX
            buf[i]=c;
cJ+G FRW h             i++;
8p9grRY%u|'RT\             c=getchar();,~T"\"gg \
        }
4rVKF+?8j\ P         else /*是运算符*/e j$Pb.u+Y
        {
1W5|'_a$CA             buf[i]='\0';
N(Q Huk             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
`7c Vn3Cu             {^ pM#^ Y-s G,N;Dn
                 opn_in.data=(float)atof(buf);
k$w$p6bF tW$zt:T~                  Push(opnd,opn_in);,?;b.U [)g1P![GY(g
                 printf("opnd入栈:[%f]\n",opn_in.data);)t.}5I*I+~I
                 i=0;
:g G7RF#~'S8GO@6R2J q                  memset(buf,0,sizeof(buf));\Hs k^sU
            }!|2\C:a6X4T~/c"b X%|
            opr_in.ch=c;,rK M2S5`-Chz)U9^
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$`Ra%pJ&V-H             {
}.K| gq[$T                 case '<': /*优先级小于栈顶结点,则运算符入栈*/kt!x5W$su
                     Push(optr,opr_in);
%X"W c*j2A/ki)G D                      printf("optr入栈:[%c]\n",opr_in.ch);
D'L o4eM1L}M~0L2W                      c=getchar();
:^-cA6xX cin4Y-RW                      break;
y.P'C?$g;T1U+n%p EC                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/#K1pk N] G l
                     Pop(optr,e);
J)vR'McmBi                      printf("optr出栈:去掉括号\n");Tm5K Lt3Bg(I
                     c=getchar();
Lg@1X!FG#Q                      break;tI:S5[1P Z D MA
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8mFiPB
                     Pop(optr,opr_t);5i4y1`#Dwq
                     printf("optr出栈:[%c]\n",opr_t.ch);
0]W]azu}5I w                      if(Pop(opnd,b)<0)
;O`Z K3k\                      {){$L"b6e7?l*Y
                         printf("Bad Input!\n");
7C+KH K O"h&{m-[W                          fflush(stdin);;a M]j+a5Vu
                         return -1;2tH*k0B+RD\d
                     }
Y:{}/C@W                      printf("opnd出栈:[%f]\n",b.data);
9xQ(j%i2s-\5x                      if(Pop(opnd,a)<0)'J!K_]6av
                     {*w8p;u"o!E)L n
                         printf("Bad Input!\n");
^s}6XL"z t6PX6NS                          fflush(stdin);![t$B1i2H!@
                         return -1;
uA"VZx w3p~pB                      }a}~'y az7|;_]f
                     printf("opnd出栈:[%f]\n",a.data);8@*v6|6klp+z XO
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1[:X4P {$F6tn3QRc
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/B6dkM#UR
                     printf("结果入栈:[%f]\n",opn_tmp.data);1eR6F*i?5Y'B!r
                     break;7i/JCb7wE8Im
            }
j0a^`!r/U&v4A         }
w/S8AJj%Y         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                %d/W}.?7d k
    }U0b&D5iq
    GetTop(opnd,opn_tmp);
9l}` n3Z+E0n*ZX     DestroyStack(optr);
`O9k4VZ     DestroyStack(opnd);q7w7P Ug
    return opn_tmp.data; @jqBp
} o+~%P.C$_4O

4P'g I.M8_"^0ar$K char *killzero(char *res,float result)
4{y:VD1ki3b {
,GTW jBEn mm     int i;5On+o7p`Ej
[1_KJ#n$?2g/}
    sprintf(res,"%f",result);$LK"l XFS5L{n
    i=(int)strlen(res)-1;,PK&I,t)]x
    while(i&&res[i]=='0')
_:i7m:u{!y:t7b     {
4k^)P;r&aJ%H7B7D         res[i]='\0';
m0N%r c(V~~"`         i--;N \ Cg8Z fJ7G8j\
    }
;z0Qj ^R8R`xi     if(res[i]=='.')5q$uO5S"V|+~v
        res[i]='\0'; T.a@1]k9b&y h
    return res;$^| ~m Y{*w7k2KK
}9c @)W]hG

W*Y7@zr:`v int main()9k5O*GX$|o
{ R gU&Rf-~P{ zY
    char ch;
[g2j&E!uK     char res[64];
7Ml'|!i1IoE)KT     float result;
#MET3|/df#`(_~     while(1)
;kO-\+P&L     {
_0P7HG/J{         result=compute();
O!g@ T srdb?'m y         printf("\nThe result is:%s\n",killzero(res,result));
Adk(M2o4l(be ye         printf("Do you want to continue(y/n)?:") ;4r5q;Bw9R FrZ
        ch=getch();3Qm#cT Z_,WB"O
        putchar(ch);%UrG/\dJ.uF
        if(ch=='n'||ch=='N')7Q&jFM.s ~h`
            break;$Y$w ^ [` _ |Q
        else2g f7H`eVY,|#j
            system("cls");
0TaGo{7F     }%F`_A EK[ {7p
    return 0;
C)w&u|+wf-OI'G5U)] }[/i][/i][/i][/i][/i][/i]
h5GzG%f#qpJ b g1joR(@h*yO
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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