捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6l+a6k Dq7W Vk9E*b
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=J+Mxm`#?4d
/**************表达式计算器************/
(a2M&| s0pC3k;z #include <stdio.h>
+] y:E,H+Vn`W!r'\+L#v #include <stdlib.h>y2RPVf
#include <string.h>|FoE5Cl
#include <conio.h>0I,|)zz2mn~ S
#include <malloc.h>
&SbKug /d r"oUB0? e-a
#define STACK_SIZE 1004w~(C3AJ+Gx-\
#define APPEND_SIZE 10
\[b@1b.J S(cQ3o:Y zz+p
struct SNode{
&C'W8WY5^/@ s J     float data; /*存放操作数或者计算结果*/)Y!snP%i@R
    char ch; /*存放运算符*/Q3oR]VV Xp
};
3t-x;Dw`M7~4U %K9CI,S4R8]#D"~
struct Stack{$|f1Xye8v)uU e
    SNode *top;
Z:?`,n9k&W     SNode *base;
x5~e$ktY2M     int size;
:} f1\kmBF D };
i5r"LT_2O$M\ } QKt7I#gd%`Yd
/*栈操作函数*/-c%n/~)o3C#k;z*{/d+fU
int InitStack(Stack &S); /*创建栈*/6]nd-Y {&Y-rW
int DestroyStack(Stack &S); /*销毁栈*/
r-U"G.Dj.q int ClearStack(Stack &S); /*清空栈*/ {_+l2t^
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
a R]z(_2J"m int Push(Stack &S,SNode e); /*将结点e压入栈*/
/_iIp$@?g[L7gu int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
{$Pv{0e H~Q
c%G W _0z!K7qix /*表达式计算器相关函数*/fS)Bcp1]R&u#L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/$d*X a1Eg5Eba
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
)U[M1n_H Z float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
l:fU[,k/|d float compute(); /*表达式结算器主函数*/ Uv~5Fm%L-N%{"rQ
char *killzero(float result); /*去掉结果后面的0*/
7K,h.za4s ;^%z5r"u {0^$u
int InitStack(Stack &S)
8e3XE@-X{C Ln1eQ3i {
SPft |'U     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); l^+N:z7FW:i,n
    if(S.base==NULL)7[)Y*L }[q/Jk
    {
-X%h{#H U)vW         printf("动态分配内存失败!");
"vtO^lu \6d         return -1; }3m5eZt
    }
|p$~mqG     S.top=S.base; T fg s-e
    S.size=STACK_SIZE;
'F"t1@:n}.J0zAt     return 0;
5qFn9]or/s*k }
z8}-x nUd"K%[!l/_0x
uv!|0a'e;U L[d int DestroyStack(Stack &S)N2hC/p.T;uY&nc2b
{
e/ihkx? d`     free(S.base);
'QM C `a9o)R     return 0;%u_;Fo,L9GG7g5UJ ~B
} WA\v4eh4v

,dy+FO3Ia int ClearStack(Stack &S)Z#Ow rur
{oAO)aBJB0`
    S.top=S.base;k!TjWO0y] ^
    return 0;
#qv0@9M*v.^uRl }kyZd"F8YW

'a\c hH(`pL int GetTop(Stack S,SNode &e)hpW`h dbE^
{na%W+a?}
    if(S.top==S.base) V:DyfD
    {Q*rwE8F I6AL
        printf("栈以为空!");x-cm*ke`}'p
        return -1;
h#^3n)^ C:|-Swf     };H lk[ ZH$g/W0J~PN#d
    e=*(S.top-1);B3Dp*Kk
    return 0;
8HT/Bfy-V!qR,M }
y;@C%A5mI;d
t?A Ep)V int Push(Stack &S,SNode e)'TlPc8w Y1k
{
@WRcD!ir     if(S.top-S.base>=S.size)'\J-?*VefBr
    {4K&V }W P'Rf-VkD
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));e'Ad/MON
        if(S.base==NULL)M(H2V:r{WE3H
        {
^B:c%S TL}V             printf("动态分配内存失败!");bK%^7R/s {c^~?3QE
            return -1;
RF(f!} V(T         }
4?3u;z k1@BH         S.top=S.base+S.size;lP G/wR)Xf&j0f
        S.size+=APPEND_SIZE;
1o![I{K0J     }z;c Lv.zvJ%s
    *S.top=e;#uF#O3E"m*OR,^
    S.top++;
#B`]sZ[     return 0;!K m}zswE3W4OcQiW
}
xi fqJ
4mL5^?Tep int Pop(Stack &S,SNode &e)$oHn4N2DF
{ O| w1lP6[2y9W
    if(S.top==S.base)
~r7@2ujx;i`)u%Pj     {
+_D1KPp3Q*] qof"S         printf("栈为空!");
gj ktc6zZYr         return -1;
[*hL(Kr6~MD     }Y3mG%G,r:NbnS
    e=*(S.top-1);
IHca6K/G.p3c     S.top--;
Mzj Z[xj     return 0;
m`]h b'] od|'} }H#SCrr/U8x
dJ'Y8AD&O+U}
char get_precede(char s,char c)
uL$m8bJ3TF {
J$z\ u$} D     switch(s)$[1nm\5|^)F;v
    {!d6]:t,Z#W._u
        case '+':                 
D y']#Vj$d&i3Ka         case '-':6Y4E*KLT{O#^
             if(c=='+'||c=='-')
$m,Mw:Tvp(D^ d                  return '>';7i4U9m,a*i0`b
             else if(c=='*'||c=='/')
\*G0joI2{!W                  return '<';RT(H[SU8c:z
             else if(c=='(')
N)m'yM!B'EB/{                  return '<';
!btvXt}-e2y              else if(c==')')
b K/ut7e/Yg                  return '>';@ Z8x |$Wp1L
             else @*`0ws1SZ
                 return '>'; l\1](AQ![ M
        case '*':Rg+T5fx
        case '/':xWp};v:Wp$G*K
             if(c=='+'||c=='-')
@.B8q4]_{;Q#j                  return '>';
T6P~mN2V              else if(c=='*'||c=='/'))W V;E(R Pp'`
                 return '>';
?.hP l]              else if(c=='(')
[sEI7l"l7ge                  return '<';M1h-g:S EZ6`
             else if(c==')')
ag0nt}2g                  return '>';
6m v8u\+A;K              else'I7U[1A+w7RT#D
                 return '>';
qsLB*Gr5\d         case '(':
$m$p!cL y.]R              if(c=='+'||c=='-')H u |3B8a
                 return '<';|+rdffM'L|7W
             else if(c=='*'||c=='/')Kiy$Z^7T&a[
                 return '<';|3~7x&e{ x_ s"QM
             else if(c=='(')
"U!w+k m]-@+B7Y                  return '<';
?0iqoX dZJ9t u              else if(c==')')
?P~B:J#R ?q                  return '=';
7y-Gwv5u~4H              elsex`OB K U3^i Y
                 return 'E';)E[ k^f-L
        case ')':
6er?2a3p9`)JOF              if(c=='+'||c=='-')
3@4s~,g*bTTZ                  return '>';)h'wl/K OH$C(Mh,c
             else if(c=='*'||c=='/')
j:p+Qd:G K                  return '>';
9T F9Hz!E$Q;M1z              else if(c=='(')
(Ua6Yy@                  return 'E';RQ9J[W
             else if(c==')')
eW+FO|*ij                  return '>';
*H-l"ok:Wk"zFLA0K              elsei,[,@8_7JJ lG
                 return '>';g/\/^d;b!?5i
        case '#':u-S:~d X,`9I
             if(c=='+'||c=='-')
9v Sm:B7|C+vEf                  return '<';
6i)jaKII,hM.r              else if(c=='*'||c=='/') UR~#}R
                 return '<';Zg6Ff8@*yg;gDE
             else if(c=='(')_c:u3XHk"z'I
                 return '<';l$P6e5Nley
             else if(c==')')
H ~ ?X{5^*`/E#p                  return 'E';
'C"zr a1M y*P"i              elseaKE%C!B#} M,@*g
                 return '=';
N+\/P)bT.d1m R~~         default:
w"pA[#CB              break;
ok-u"M8OUg c     }
a+S Q hcZ@V6O     return 0;   
J]L(H%Yz;r }
)vv9G%CM,j$? {,_*ZY*Wc@8mZ
int isOpr(char c)%u _dFB
{
J3CFN^t     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
$@4k{3H$ci O+P         return 0;
"?I+S3R*{CW     else
9W3n;z|G?-SPJG!L         return 1;3p!V%T$f!CK@A+c.tt
}m IX NGk-L.A
t [aCH
float operate(float x, char opr, float y),]w MZ4Ey [i
{
q!G F dH8n     float result;
?7rL\V4{3jSU     switch (opr)
;o%~4o8rV,IV*o     {
,l UI_1u8a3_+BZ         case '+':
y;Y(Zaa ^iA              result = x + y;
?Sqc)BZ q1t W$o              break;
?6n!Sp5ORD K}K         case '-':
,n,k3A#\%{4m.AV              result = x - y;y Z1i'QB)?&U7a f
             break;[?*xCAH;o6R
        case '*': 5DdG@ tw{v
             result = x * y;
Yn+cR'?6JF[-{*o)hU6N              break;'J-mZ#dC.OA
        case '/':
Y^0q+[:^A0f0h              if (y == 0)
9^8k8? t|/KQ0rk              {
B0r Wc7e                 printf("Divided by zero!\n");
+@r2O#[4Q'F:FM                 return 0; G&x?+P/~
             }
?r{6KP{`Q              else
;j0J${ULe              {z ^ F1~kL[
                 result = x / y;:C!x*hjc,n8e.Xd
                 break;
(^ l i`M;Mw              }L0lJ&Er[
       default:
:d \'^|dP1crQSw              printf("Bad Input.\n");
N(` AouZ&ka0g              return 0;5SE6{H8ke+^"i
    }
Xv;z }1U8W~` p[     return result;)x-n1FK;b6XW
}   
$RP:d})UC#wG
(wv F'IMW9`)lh float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
I|/B;X"E5UQ:?7uI N {
eBy0vdb     Stack optr,opnd;5N*Y"A/khM&rX
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; ^c:iU5?9@
    char c;
I.I:cT/w;Hf     char buf[16];/a;V5s2P.h*g t
    int i=0;
R]\U9kHYO~    
d3@ k5B.x\9V,zm     InitStack(optr); /*用于寄存运算符*/
7a_;o z"a_mh(V     InitStack(opnd); /*用于寄存操作数和计算结果*/ Y tF1W x:a"Q+d`
    memset(buf,0,sizeof(buf));
*UQXD)`6B&Qj(R A|;C    
5a]S}]     printf("Enter your expression:");
G`}t:@Y         5X2h$bxg
    opr_in.ch='#';9f ^_#`em:Qg/u+aEA
    Push(optr,opr_in); /*'#'入栈*/
s{;l#}*i7I     GetTop(optr,opr_top);
3b`@1@U.dN[K1g     c=getchar(); tDQ[r;exV
    while(c!='='||opr_top.ch!='#')0S+CJ2O$Lc)K5X:`
    {
.A;GP4gB eg         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/'v| {N*N GH
        {)xh(C?[5C&?
            buf[i]=c;,hn e(Qe`(lM
            i++;
$wDm]UfiY             c=getchar(); \E\7^)]
        }
:S^#Z)z2lxd$E         else /*是运算符*/#{"V)cSC
        {#zs!k{1m K
            buf[i]='\0';&b3f{N~q
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/|9{)Dw Z
            {
a a t$pE8}9I                  opn_in.data=(float)atof(buf);%qFxz0I9^g`
                 Push(opnd,opn_in);
;^%Q4^SH6Dr2O(H;U+P                  printf("opnd入栈:[%f]\n",opn_in.data);
~ uUahPd G                  i=0;
-~`d,{ ~                  memset(buf,0,sizeof(buf));
#z^[5`Z+e             }
L.?.[#e L,e/g             opr_in.ch=c;9] A!bGj%aQ)NP
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
z/R;m)NIjT+?             {
6Nwt\ M r hd                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
X.T A4L3Mv                      Push(optr,opr_in);q_ ]R'r7xfi
                     printf("optr入栈:[%c]\n",opr_in.ch);
ak!Vc8qC8a$S                      c=getchar();
p6FD p/S*U"T(G                      break; ALp)iK6V
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1}0@/F`0lW+H
                     Pop(optr,e);j\'svOo
                     printf("optr出栈:去掉括号\n");
h)nLV*?e5|                      c=getchar();7a Y jdn6O
                     break;
e(Tr3e5F{                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
/y4T+o(Mtu]                      Pop(optr,opr_t);,X!KcDwL6l"D
                     printf("optr出栈:[%c]\n",opr_t.ch);;~v%Uc|`:j eSm
                     if(Pop(opnd,b)<0)
a e W){J,V                      {
a]-]E cCt6c(rV                          printf("Bad Input!\n");1R Oe}A,wv
                         fflush(stdin);U8Q*@ AT1o
                         return -1;&Tj W'rW3T#p
                     } x+wm*q3Nm'r
                     printf("opnd出栈:[%f]\n",b.data);
$ld _0n6mydf                      if(Pop(opnd,a)<0)+{KBZI$r4y
                     {
bf0Z5e ?!qWi                          printf("Bad Input!\n");Zg} ?$_2S8w.K
                         fflush(stdin);
+V5H+`g6Gy                          return -1;
f` e6LJ$n:h                      }2^ W3Tm&[iD,Zr$j
                     printf("opnd出栈:[%f]\n",a.data);)R,mt9P7k\3_!h8_
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
/BnV9l@                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/B SQCm'@8Tw!W
                     printf("结果入栈:[%f]\n",opn_tmp.data);(Ks/w5E#?
                     break;
*t!ZXm'D/G r             }
\/mQL(@Y         }/@wE];n@
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
p+y@| k2oq     }
| Em y y\;m     GetTop(opnd,opn_tmp);
(?v?1y5Rd#h     DestroyStack(optr);eK"yJn C"u(x
    DestroyStack(opnd); vh T hw+l
    return opn_tmp.data;
NH;QhtZM!]um }
+R'f1Q0Ay.T
.z*c7B6Z3dy:L char *killzero(char *res,float result)FZSr/?h:X3|
{
v&mZ@b%o&N'G6J     int i;
cQK7qY+\z
v m-xU$XE     sprintf(res,"%f",result);'[j2V&hM a
    i=(int)strlen(res)-1;
2~@*h&sf8X^9o|G Xz     while(i&&res[i]=='0')
9GnEs+T(E5R$q_ R+}     { ?){o-nup*S0Y{"Z
        res[i]='\0';9f!l4ZK@mA
        i--;
e px"m,l'P7B,Y9u     }
"FTqG _m&p     if(res[i]=='.')+v(FW0m/@ah|G&f
        res[i]='\0';
C1fV/^#e     return res;~FS%yol2G2UW
}'Pd4@*V2he+b(m
,R2ND9kM
int main()
C*cwvAg {
o3J};R hJ3T     char ch;
'C)S,Ir;k)@/AP     char res[64];1[,U%\$|.x sANU&?
    float result;
D$fQ/g)~8^ Y\#e7? m     while(1)
U0i#E4VD8n     {JO:`S%Z"WUqjs5u
        result=compute();
1z_&?~0v G6s         printf("\nThe result is:%s\n",killzero(res,result));
#gF{6^EddO4PY j         printf("Do you want to continue(y/n)?:") ;
ExE J3JGj         ch=getch();tu(~:j6~1M1m
        putchar(ch);
m7P mKdg&~;p+Y}J         if(ch=='n'||ch=='N')
)i;Vo-Rb;j%a z2sP9m             break;j|N3Ed5a B%?q;{f
        else xr,X(?-Mf:|e9@
            system("cls");
q"G8u5rCs[     }p!~1?/ZCq
    return 0;
n8~tb[ }[/i][/i][/i][/i][/i][/i]7@(ep I%R#Mg

Z9hw @j8EM7| [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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