捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
W,Qo%F$f!nB0A 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
;_:_6Fx x(f /**************表达式计算器************/
;dI3n JC7@a+q #include <stdio.h>~:_e0x9e.Yjdeb.K
#include <stdlib.h>
'u3nM Yof1h*X #include <string.h>3OW)hWf~t A
#include <conio.h>
hN4ige bCje #include <malloc.h>
~/YWG7l#w
$h'P ~AT Lu #define STACK_SIZE 100
6T`2X0s@M.X #define APPEND_SIZE 10
*F t@ FoYn m fL"jatZdU"Ej
struct SNode{
oh[ux.b~"J p     float data; /*存放操作数或者计算结果*/
c |?&M"i(f"Y     char ch; /*存放运算符*/O-}f]aM
};? t pZ9i _.}&e

"iE7v%r/i`0v0q8Wh struct Stack{
UNN~3X J E&C"~9D     SNode *top;
.V_)F [Q-s;?@v:E\d     SNode *base;(S*`/o1X9z2]^ D3z)g
    int size;
k&vh0J WG };9D4C0IZ] _do
3g{Sa2T
/*栈操作函数*/
oS(b(j!v }?u'P8} int InitStack(Stack &S); /*创建栈*/
D O7_3y `2v int DestroyStack(Stack &S); /*销毁栈*/4laB3m fR%\*x;y8u
int ClearStack(Stack &S); /*清空栈*/9k%aSqRu9Q/K~
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
!xUP0} Ye0~ K3Q1o int Push(Stack &S,SNode e); /*将结点e压入栈*/
W,l H"`zD int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
A}L-Z.t
D)k$Ir_O0K^!a /*表达式计算器相关函数*/nbgD(A(jn
char get_precede(char s,char c); /*判断运算符s和c的优先级*/?4yz%EP FzJ)a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+s)j5[7MT float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
0MKQYu9G5Y float compute(); /*表达式结算器主函数*/
.GK2\-gg0O J}_-bK char *killzero(float result); /*去掉结果后面的0*/ Ixn'q"i.q:l&E

Vo(r.h5l int InitStack(Stack &S)ru*o;coSyB
{
A"\?"_f'Tm,\(b     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
,bgIe-oT?"h n s     if(S.base==NULL)
JaA(|@Q     {TWJ9E*P%MyB D
        printf("动态分配内存失败!");9^XL$C ?#^{*B+^ b;o
        return -1;
2I\ MZc&{     }@;Tdj-G}{ W4}
    S.top=S.base;c#[ nN-`"Is'jl:Yi
    S.size=STACK_SIZE;d}qu/nR$t3R'N}4E0rD
    return 0;9H-x\ }C
}(DV[/GV,[N%@

'h_d(OOH.s int DestroyStack(Stack &S)e)\prc-e1rA{
{
#F+A4wJeLf     free(S.base);x4e#hh(zy W"wS(]
    return 0;(I `I$rs6f
}z7I-o._5A Z|
q#M Cn&{D"_*r3Y*E~
int ClearStack(Stack &S);C%@1O R.H/\2@ eR
{Tm0R7D+H4ocl0P
    S.top=S.base;] U&{2x,j` y
    return 0;
(B[q6hc6V1a }
u.PJv+B#hWy(i0{
1im [ [i int GetTop(Stack S,SNode &e)1Iv3C]*v!Z9K ^
{F`'qU;C8Wf
    if(S.top==S.base) n{1[fOAt
    {H,s2[{)P@v ^9]
        printf("栈以为空!"); A4[^T+aY
        return -1;
R*~V4n%UT     }
OV$X[O-~u @ k     e=*(S.top-1);
P[ Heg;i)?7h2Y[     return 0;'r4W-nK5O
}
+y6_5ib g F7{)r6Md3H$E C
int Push(Stack &S,SNode e)5K*e!F9fj(o4^
{4Qk;d?){
    if(S.top-S.base>=S.size)
2DW#y"U;^#Q/dd}E     {.AL3a9wj;G'z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
b/Rio,lxh         if(S.base==NULL)
y(x{x)z.C$QY         {
H+GI+d']             printf("动态分配内存失败!");
4O\ L8z!I             return -1;
8YV$I.e.o2b/S4Ftj hE         }
1X6K)K+zXL         S.top=S.base+S.size;o8G#w1\+Z
        S.size+=APPEND_SIZE;
4@4gi)}"K\In     }
3k@7@ [z     *S.top=e;
)[_4UCwh6MD Z     S.top++;
"Oj ]g t}t6L     return 0;
C F'ck]b5aY#m }J0l)F]2g7Y!w

R\$a1`/_uU!r5[ int Pop(Stack &S,SNode &e)
3it b }/dgl {\+ll%d2]7}1u{
    if(S.top==S.base)4z'paQ"~N5ftU"r
    {
B%G{e0G5?0\         printf("栈为空!");
Z nb?6z|         return -1; h$I7oQR*g pO0Q
    }
wT%{nwj6z2Xpi6\     e=*(S.top-1);
Bbo ZLZ     S.top--;
.rNS g}GD _     return 0;'|6Q.{7qE#H*Ix
}
U:rj[\)OyjtD
.y'lw UJY6qMy GU char get_precede(char s,char c)
k8PSN!\*v9c!K&J {b"I,]1G6wk
    switch(s)
'Q_)]R4u6\"B!b'n     {
#B6G/qi!] ?$Rw ^         case '+':                 I2H+n8~7D,e
        case '-':
n0xYX"fQ9~              if(c=='+'||c=='-');U)zlx0b
                 return '>';.\*u j!^:|"D{6yB
             else if(c=='*'||c=='/')(Jrd6Nd{M_
                 return '<';
y(^$D@zm)s-w#T              else if(c=='(')I%U3mj5o7v9V_
                 return '<';ss6}3D@5JY,Ki
             else if(c==')')2}\ C I MA\G
                 return '>';nS+Gum,|8a5Zr!k)N
             else 0ZS+]6`;j {U
                 return '>';D1S5AcbG }HCZ
        case '*':`@Wm2xG[^
        case '/':
7\:L"b s+{ v VN              if(c=='+'||c=='-')
'B:\ z9v v9MeRk0qt"} H                  return '>';
P[c0t9BLfQ q[              else if(c=='*'||c=='/')
'Zk,X$YZ$U7m)Q                  return '>';Y {i/n*S\L:Q&kU
             else if(c=='(')
G^~;| e'U-VT S                  return '<';
j vWC']9{E,~.R              else if(c==')') n8I%v:^SQ3S6J
                 return '>';!N$F| E#RI|
             else
Li1VOlJO.}                  return '>';0N{9A L5t(|4hy/AH
        case '(':^$tCM r
             if(c=='+'||c=='-')
7Bqx%S6fOz+U,lu                  return '<';U _dq$oX,U0u,Gz}
             else if(c=='*'||c=='/')1I:Pc3i~*j
                 return '<';&Wi2@ a5uX
             else if(c=='(') Kzt)dUao
                 return '<';
/v4OZ,RP$l0NM              else if(c==')')T4s(Nw.N#Z
                 return '='; u?Av(`X'K
             else^1Z4^,j*vY/S(s
                 return 'E';%K0\$@wt;Wm2H*Z
        case ')':
"YE/A(PO)oX*[7ix9D              if(c=='+'||c=='-')
4Cb{T8\}^                  return '>';
%Q'p jK/nE j1C              else if(c=='*'||c=='/')/Kq3q^6i T
                 return '>';Qy E^m^}
             else if(c=='(') xz2\~M_-C!K
                 return 'E';
P+A1N7oB8Tp4QN              else if(c==')')
,f? ze0fQm b                  return '>';DRZ6u@ L;W@&E I
             elseE QP K aI G8bi
                 return '>';6|O-hi:^.K[|
        case '#':etP0I`P
             if(c=='+'||c=='-')t3|'J q4P%d
                 return '<';
OqMu$cXv              else if(c=='*'||c=='/').[)XYHBR
                 return '<';
e6T!A"TE              else if(c=='(')
6X9k)U$t3e'W                  return '<'; s \1p"| v-L \
             else if(c==')')1QW$t"C[%M)^,q
                 return 'E';
6{N"_ YI              else
Dc&n(a["kS&\*]                  return '='; |3o F%w6FU$d5s?
        default: ypMz~8?.L
             break;j*YGGld
    }
.m.b^9sz7T~     return 0;   
|6YY!x ix;M }
"Z/CNm fi#a b TGrz
int isOpr(char c)7i+^1_6K:T{#p
{
[Jf+HS     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')*Gxa;Nf(\l `"N}'P
        return 0;
/m3MER OT)I]O+u     else
)Z Wzvd^q         return 1;
SG8Y$r"e/{ }
Vk%E-X {6`ok6qo O2W b0q8e
float operate(float x, char opr, float y)C.\x T[ Ft7v
{Es;E0a8y:J dm
    float result;
F#xM\2X     switch (opr)MnfYQJ6b
    { h`/\*A4fURY
        case '+':
;[H-^Ss-IyB              result = x + y;
#o^0g5d(ra,B              break;
h!`w,t8o9tZ         case '-':
4Br;w g;HQYF              result = x - y;
x J9W:e(eE-Z              break;
"GsC t.l _qH"UM         case '*':
BC8`1u3h$V              result = x * y;
RI7y c:Hxa&PbC              break;
'pHP? e8Y!_U         case '/':
8z0g5Y;qTb$v)Q              if (y == 0)w(Si+{.p
             {
N5h,k8_:A\x6k                 printf("Divided by zero!\n");
:zv3}@+E,E(b                 return 0;]%M(o0fr,s
             }C0wR!Q@p_3y
             else$XW XmNWmi
             {d8jrPTs0y,Q
                 result = x / y;
:wbq7L5}!lT [                  break;#hR7U$~\$X+Z%y*\3f
             }
v5]z^%q4T)iH        default: 5^Ze:A a3iy
             printf("Bad Input.\n"); S%\ i7U~ jg
             return 0;
z v4r5_ s     }2q3t*Z{{3{j
    return result;4}OJ|"GBX2Rsmn
}    A g#D1Tz{/wK/@1ce
)n*wy%? g#F!y|
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
/u2n:`1A8OP7x#C K1Vr {
ah(i;t/PM0M     Stack optr,opnd;
;\/@ ],S(e)C2P|     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
*r)r6Qcq+o V4b     char c;
Za.D}w/h M     char buf[16];X1`)e7A u
    int i=0;b8wWOp4t w
    c6I6eG6` A%{Y1g
    InitStack(optr); /*用于寄存运算符*/dZlW6^/ZY
    InitStack(opnd); /*用于寄存操作数和计算结果*/
1A*zLS4A]+E*E     memset(buf,0,sizeof(buf));
%P+?o9uc    
J6n[:h [,rk A     printf("Enter your expression:");B)m)Px8LT?
        kHjj/j/u1j
    opr_in.ch='#'; d-Q@auf2v v
    Push(optr,opr_in); /*'#'入栈*/
#X I CttK     GetTop(optr,opr_top);
.@3bSPJ.u~4X(z-A/D     c=getchar();},K%E$dcx
    while(c!='='||opr_top.ch!='#')Naj2Vc)j0RV%`
    {
v o7Gm$US[         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
v!B b\w*FK w         {ZLk'F9A0r6h
            buf[i]=c;
8?G"}$sY3Z%U             i++;
jK(Vi v,L             c=getchar();
s9|N|`8B4PO&Q         }e8` I1v#r?Aw j'Z
        else /*是运算符*/SyF$T]+Q q7WYB9l |8s
        {Be$\ji X3C/B Eu
            buf[i]='\0';
'X'uk](ke af             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
{'c`|~mX&r             {n+c{oj3@'d:j
                 opn_in.data=(float)atof(buf);
kK)_ n"N uG                  Push(opnd,opn_in);
]?`)d k }.J;HFc\                  printf("opnd入栈:[%f]\n",opn_in.data);-m"r&oCs#[ h?M
                 i=0;
&Cp*^@5B5E"j&fA                  memset(buf,0,sizeof(buf));-b/@e-h ]Bz1h
            }_j)@ JYh4E
            opr_in.ch=c;
Y5~8I YdG~$\I             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
Z(u/I2YES             {zvj \ al3gG4h
                case '<': /*优先级小于栈顶结点,则运算符入栈*/"sw3qt3t2L
                     Push(optr,opr_in);i L~ P^"di5k(S
                     printf("optr入栈:[%c]\n",opr_in.ch);WH8yXaD7\/I&r
                     c=getchar();
O"d{`dp                      break;
+|4t K7C!t                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1f![dQ+Xsj                      Pop(optr,e);2K3T@JEk
                     printf("optr出栈:去掉括号\n");9l-K'v#l|'[ s1j7A
                     c=getchar();m9u(?HvP!MY
                     break;$VcTUw
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/p J Znq4W o
                     Pop(optr,opr_t);
l7MJ:viQK,~@                      printf("optr出栈:[%c]\n",opr_t.ch);0w YUa"@:|U\
                     if(Pop(opnd,b)<0)/ff!j+|)] s2?d
                     {
-p0BO d&be-H"dB`                          printf("Bad Input!\n");
(Rze u/\0L(Z                          fflush(stdin);
t\CY{q2L:_                          return -1;R8]AS+K)yx&P ` uC5L
                     }
5~J'Cc {$M] tLx                      printf("opnd出栈:[%f]\n",b.data);7i#R'_| F ~(T
                     if(Pop(opnd,a)<0):p$_)m8i9r7ay:qF4WAe
                     {&W,gh/e6H/j9{
                         printf("Bad Input!\n");
5F2H)Z2~#Kf                          fflush(stdin);:GY6p"Z0[i1[bT
                         return -1;&x2Kg \{1}-i-v
                     }_m6Y*A$cA/}
                     printf("opnd出栈:[%f]\n",a.data);
9xpO6Q4V gi H                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/U9^Q6k"a~8t
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/RI?M-Aq t"G
                     printf("结果入栈:[%f]\n",opn_tmp.data);
V6P+t\N k.T|                      break;
$r_k;_4G             } `K0p E8M,Y
        }{5d*s6X ? KM0J
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                zn\]|DLF9q
    }lu+Im*oj
    GetTop(opnd,opn_tmp);-r'_E;UX9D
    DestroyStack(optr);
"W,aQ$P*j     DestroyStack(opnd);(Wc,e^*}x(Jue
    return opn_tmp.data;V-G3UJjRG/~'c
}$s7F*b"O q-Zu}1C
%S AKG/G{$M
char *killzero(char *res,float result) dk#a0DG0M8_
{8n r0j4[K
    int i; U'|Xn^ Cy'C

'~%Dxx b%B     sprintf(res,"%f",result);
D;r4BJ}     i=(int)strlen(res)-1;"T3[y+[a)[-TT
    while(i&&res[i]=='0')
P$T.PU[     {9sl/R ?%Vpk m
        res[i]='\0';
/N~9[ H8ttx9M         i--;\n&s!u*bT
    }
I;q#V'~["[\kQ     if(res[i]=='.')
O-QO{+Z3Od@h){         res[i]='\0';
srB*_.^9{^     return res;tV W L l5U^3w
}J;U*H$?;w%X'_!W
#n3^,~XNr:gJ
int main(){i~'PC~L
{
(n7h k4ZI#s;S!S     char ch;
$M tr-TOA     char res[64];#} P7b\2Nw R
    float result;
r3K,sb:P!k     while(1)
N8HATJ:f.?;z|$~     {
h nJ`{3C2L         result=compute();
'B6` J6\e E O         printf("\nThe result is:%s\n",killzero(res,result));
B+k!Ul&z[         printf("Do you want to continue(y/n)?:") ;;x/ZA!G(uN%hz O X B
        ch=getch();EM"G2A:nY)\Z4L9C
        putchar(ch);
I3b9b^W"]zui{)Te         if(ch=='n'||ch=='N')
6fX ]+iYsn             break;Nc1@-gY6^&d
        else
9OFfFy`             system("cls");
~7K]1A~:?#k     }2@"~q4R:N ex
    return 0;y0q2U1PH"| }
}[/i][/i][/i][/i][/i][/i]
%c7dG.]"vo0O nB HqR6M1~&]
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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