捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+FM x/c_|,d:v 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
7s vuvz-u~`4?@ f.Q /**************表达式计算器************/*L^5ad&V)ly` l
#include <stdio.h>
A4BNoJW,L iL #include <stdlib.h>
0C1ZYY@F #include <string.h>b Fu?8j*t \
#include <conio.h>A(C*G2?pjmw
#include <malloc.h>
3G-x)d1zx d0s!?u
KzK}`I},p'l0wf #define STACK_SIZE 100
hD:m|0rS #define APPEND_SIZE 10
aE:[P-q.C'H-K U
Q*E#g$Jo#ZX struct SNode{0`\ c/X_x
    float data; /*存放操作数或者计算结果*/
\&x5jZO R9[     char ch; /*存放运算符*/
)}'sE7[/}.A[)_/z };cU7{*NikO

k&|l)i ?6M{ struct Stack{]5B5P/oj!K9x
    SNode *top;o)SnpL0b0JnB
    SNode *base;
.Tp$g!B*t0`2[!l}:k     int size;
X3OaPXbEV KGx };(yL2N4gY0f"g/b8Y~
ldy+G.J1k!O
/*栈操作函数*/
#Oc ifI,T int InitStack(Stack &S); /*创建栈*/
$Ip Hs^#u$rRZA int DestroyStack(Stack &S); /*销毁栈*/ vH(Dom K+bVA
int ClearStack(Stack &S); /*清空栈*/ QKI J*b1y)g$v Q
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
IlA1l7SZsj int Push(Stack &S,SNode e); /*将结点e压入栈*/
{`b5so B]3H int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
fq g2~`7uk
_'f){.k[3A dK /*表达式计算器相关函数*/TrX%k8MwK
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8RzD1S;VYM)K8l c
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/x] q&t0W4Rt(_
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
e,M o,Z R float compute(); /*表达式结算器主函数*/
Z&t0ZO zi8N ]eR char *killzero(float result); /*去掉结果后面的0*/ EY LH^tseu
t,Y0u7XW6\ C8Kg"Ee
int InitStack(Stack &S)Ks0q2m7E6rS
{c*L AWTN
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));D!? e R%[
    if(S.base==NULL)
"V4X0Tu'v!{;j'Y$H$KqZ     {
2p5|onu!S.^nFd         printf("动态分配内存失败!");FyJ&v p |6o]
        return -1;3W_Zg~'?L*d5J&S
    }$N e.X| F2}"p
    S.top=S.base;v Z d \'R
    S.size=STACK_SIZE;
%D3_$LApQ`0N0`M     return 0; W if,]9G?S4_
}v6b N o0k z

W%@w;M0B9vT-n\ int DestroyStack(Stack &S)
L7`K1_^6G;m {
:I#t q??9a.K'`     free(S.base); pbExH
    return 0;
6b8F4zxRy }
1S!xj:_*x1X mx^g%X W6[$Z Pk"xQ PgxF
int ClearStack(Stack &S)$]d[!\&C
{Z I!W$?cYp6d@(j [
    S.top=S.base;
N ^ ~!Vn,`6H     return 0;4T/gu6QcP+E6Gv^
}
O]*]2W` g/qW`F bb
int GetTop(Stack S,SNode &e).KOG V]8RU
{
s;[H;BCm"_:l     if(S.top==S.base){C9u fpR4Y9h
    {
$X-yi C(Nu)K5~]Q         printf("栈以为空!");
mb9OzS'|1X)@{         return -1;
+@eQ9n6_ wA     }q$}(r5GB/bRN/z:r
    e=*(S.top-1);
xt!` Pp Z4~ SC     return 0;gL7jc$j6NA,`
}
2P5T.q7p:p 1p&u m t6T[9\P
int Push(Stack &S,SNode e)
E R qM4]J7Q9G5j%M {.aq;T bsg5`
    if(S.top-S.base>=S.size)
D9V'sTx     {
#F:Zk6d iK"eu-a&_         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); l,x0D7a Gq(@3["P
        if(S.base==NULL)r7|;L3Jm$V
        {pF|5x"g
            printf("动态分配内存失败!");j5bwu G8]
            return -1;!i*y8F7Da$|Q w,d
        }j(nb!Q:x#e6a+\
        S.top=S.base+S.size; ZRt,` Y&`C$q,jE
        S.size+=APPEND_SIZE;:Lh*}G b g3nJQ
    }
^7On0X0ti)Y,^[2H6U     *S.top=e;
S!Wc;}/U{-~e$`'h     S.top++;,T`5xS }.Z
    return 0;
O-E%D t@7^q }
K4Yi,j'd(F*F` U
5itL\%X%A int Pop(Stack &S,SNode &e)
xYz4iPNK'T"]*O&L8v5I {.]$x:m+}R+?
    if(S.top==S.base)
~%dA9r6uE     {
.]|!k&AP4j4y         printf("栈为空!");
*ug+FCI/L9R         return -1;
O+]2_L8x&O5f     }
4k8jUh EmU~;w%^     e=*(S.top-1);
|2`3CD!_{t     S.top--;
#J%^%X/Ru     return 0;b T7j&G}h F R
}f RS*gp&~a [
z5Z:cJDd Z
char get_precede(char s,char c)8e%`t N\!X5T+EM
{
4}W1T${ n f9V[     switch(s)
0`9Cv o3xK9U#d}:A     {
$u|'B6M.R1n         case '+':                 az2A}2R
        case '-':
h5Er3Z*y&T              if(c=='+'||c=='-')
x F%OBhJnK7s                  return '>';*]/X)k~YT*h smt
             else if(c=='*'||c=='/')3[T,?^B*bQ
                 return '<';
&Y7y+j0O(`-h!Hj              else if(c=='(')
0C p0l+O+o1Ya n                  return '<';rE#]6S {&\4H*M
             else if(c==')').A9]0]cITl%[;A
                 return '>'; K}m'iA4G(w
             else
"UR HYyRXo%Y8U5b                  return '>';
D&P$JJT'`         case '*':
-GHq6^0S         case '/':
-\ H)aO`0~)x+R              if(c=='+'||c=='-')6C%}-_9q Y0@W;U
                 return '>';\w#sV @6d] RI
             else if(c=='*'||c=='/')
Pr-L6y#R/ve#@ B#Is c                  return '>';)WV H dc%p/Y
             else if(c=='(')
rKJ*O(U5V"d                  return '<';
RbZY-b)MrA              else if(c==')')
3A1r.~c-JO!z                  return '>';
k4W v(U]IA+q              else!|i1ddT6Z6_8i/Y
                 return '>';5DM7t3VjZ
        case '(':
W2?d pqc];xH              if(c=='+'||c=='-')
HrT*H G@#jz w                  return '<';
/_!nQqY#[              else if(c=='*'||c=='/')
`6m(R6c&r+c                  return '<';dDEJ p$B;|o
             else if(c=='(')0k\G?\
                 return '<';
'J4]w!q;A:fRl              else if(c==')')
j8o/o\2l9LB$?;}                  return '=';
Pt"? pVqW              else@ K4XRE KF
                 return 'E';
M)w)[iEw'W.x7G?         case ')':
*y*J"aBx^K              if(c=='+'||c=='-')6~+AD)GD:F&b"d
                 return '>';r;}I o GqA'O A U
             else if(c=='*'||c=='/')
*d3XJvR                  return '>';^0J1x w}7w
             else if(c=='(')
eYT]/tYG                  return 'E';
c-F9ib C$z*F|F              else if(c==')')
!Q/{J8F ?"g1k"Y h*C                  return '>';
7rph g r&BoD              else\$j Su o
                 return '>';_$Ex s$|5ti
        case '#':
R;\1k-ekK              if(c=='+'||c=='-')'W&] _F6tN s5K'jd| _M
                 return '<';\ \'o[uM
             else if(c=='*'||c=='/') NL`q!c/p%Xy
                 return '<';5^ Bvkt&`+EK
             else if(c=='(')
4`q].H9w&Am$K                  return '<';S XeE d
             else if(c==')')#zc:x.K \1x
                 return 'E';.Eo:M1\"u ic
             elseO%_aTG
                 return '=';*o q$n{@ N
        default:
g}_4aR_Zy-WS              break;
"i9t0k t7}+@     }.rM'b*^2c!n/[
    return 0;   
9EZ?u0x8f })nt aL7n X2Y&n

.k$oQBeu5J int isOpr(char c)
5a8yC2A q {8N%O)^+eMn
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
!K%eB)j\[         return 0;A*yV;H)R E
    else
+fhUA[         return 1;%c!Y#\[UKt${ w%~$W
}
'O$LK8Z9n+n]
J4c VH+^/m;|+y D float operate(float x, char opr, float y)
)ULHeJfa ^ {
LuxFy     float result;F4v6XhGP[(sW
    switch (opr)
;ZDb-js*b5X     {*f_.qyh-Fw
        case '+':
@'}rI7p+fY              result = x + y;
;M@L$O|9V              break;y `%OK{vJ
        case '-': FkO],gE
             result = x - y;
\]q ? G"B              break;7qp-H0gF6|x
        case '*': #o;XmhjO~
             result = x * y;Mk&C0\3|0uZ7z
             break;
u:h+A [#g [8^4Y6M         case '/':
)S9^kS$U&Z+k              if (y == 0)9{C.b;mJ1kJ2f"~
             {4C;O7IkJ"[
                printf("Divided by zero!\n");p8SR%Nh"U!U }/{
                return 0;Q#?3R m {
             }H)jY-UY&K%\
             else} ~a~fOyF9mA
             {,uL8p!f],|+Rb7GRX y'[
                 result = x / y;
`n el8D5Y                  break;Ky;z+N b$c
             }
n%oy%FlK%vR!|IW        default: quXPq
             printf("Bad Input.\n");
9B7r^*@8q?              return 0;S^|#z j
    }_(S'a8kXJ JpO[
    return result;_${&E-a5|+NX,BNU
}   
}@~2P U$R7P
}} `la5d float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8BI+faSG
{
Ix*K(U8`     Stack optr,opnd;
d4_ u-q|VS}a     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/s'k a v0Q[]{     char c;7c*h^3F8^"u
    char buf[16];
#S!l3x h*mL&Qw     int i=0;
&jK ]%`I GW+B$R     8vElj#G
    InitStack(optr); /*用于寄存运算符*/bA)Ph7K3npms)Y
    InitStack(opnd); /*用于寄存操作数和计算结果*/fB#\lM/D$}+x
    memset(buf,0,sizeof(buf));#Iz0nue
   
l;qx2m!]O8~+N`(E     printf("Enter your expression:");3~5k)j}^ n2tR)V6k
        *y ^8cR.T]%F e
    opr_in.ch='#';P*b+A/y"W-}b
    Push(optr,opr_in); /*'#'入栈*/
vO7?%\IsbX     GetTop(optr,opr_top);
9\BUxTa3tU6r9b     c=getchar();
z.i6r s/y_H&u3B     while(c!='='||opr_top.ch!='#')
? XH7ura     {u#a ^ T4|+m/\~3n3^
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/b/e"RiZ/jzW%Qc
        {
5HD'v7a,g             buf[i]=c;
!F+zD/S/U3mb             i++;
5b0]#S#UGw|,M             c=getchar();
A.i&Gv"_2A&k         }
T~$Sw}Z+}         else /*是运算符*/A3[!{MW`#]~D
        {'gD:T(qm!X
            buf[i]='\0';'|xP2MN ElN
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/o2@:YB z'G_M h Z
            {
KT x:Ee,M X @6B:J                  opn_in.data=(float)atof(buf);
)p4rVu&dSD w                  Push(opnd,opn_in);3hQ*i]!\4F9N&u)g.Qt2g }
                 printf("opnd入栈:[%f]\n",opn_in.data);"NG,r [Z{r
                 i=0; W"G&H;f,oao@N
                 memset(buf,0,sizeof(buf));T rVSNC _av)F/e
            }
s*@"ne6u3Q0^{Ui             opr_in.ch=c;J/[!e;r4LL
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/dD!I!}]x
            {
f&jvUHdhOVN                 case '<': /*优先级小于栈顶结点,则运算符入栈*/x3T$J Sy(L+W%A
                     Push(optr,opr_in);H|R W5FJ q
                     printf("optr入栈:[%c]\n",opr_in.ch);
V)K!ro^\'VN9l$J                      c=getchar();
7jh^EJ(rT.SB S.`                      break;
RV-q {.z,c-P4X8q                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
,~G]%} |,Qoz'`V                      Pop(optr,e);$IF#e h0sy$Lj @4g.m
                     printf("optr出栈:去掉括号\n");
?n2T6[h}L {                      c=getchar();
@"O)g\l?/{                      break;sv'b\ p(| C
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/OFg|0Za ^
                     Pop(optr,opr_t);}@@0DK9B w%H
                     printf("optr出栈:[%c]\n",opr_t.ch);
$ULZ"H&jcJ\                      if(Pop(opnd,b)<0)
"Qw:c;k.T_0tACX                      {8gX4q{ kZZ]^2w
                         printf("Bad Input!\n");;A ^nf7L.UH
                         fflush(stdin);
'\s6^ J2W,z}                          return -1;
o,z;`:_ C6x%d.u(G0u                      },bFMg(b
                     printf("opnd出栈:[%f]\n",b.data);/e*Q a J3b
                     if(Pop(opnd,a)<0);c*Uo$D hk\:@
                     {
\s[+iu2`B                          printf("Bad Input!\n");
*NH D%@3Ik-zL#H&zW                          fflush(stdin);
9Gk"V9_:L$c$Q}                          return -1;/rx#r3|N*}
                     }1x'|6@$m+U.]*go
                     printf("opnd出栈:[%f]\n",a.data);T;N5R*G|
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7Bd$o5Q[+~0H;k V4~                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/c YL@2}P5v H
                     printf("结果入栈:[%f]\n",opn_tmp.data);
dV-l/I"T4]1aG                      break;v"x)G VK)_
            }!? }1a w@q
        }
4Wj.};X}B%r         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ([?@5H`J&t,}+J%j
    }
[0o:G1otlBj     GetTop(opnd,opn_tmp);vi,B~KLUZ
    DestroyStack(optr);1Q2~"P3jw
    DestroyStack(opnd);
O0["`CY5i     return opn_tmp.data;9rmxzY7OwO\
}
sB kk4c"U _I&k
uQ N&E+H}E{v char *killzero(char *res,float result)
0X3T(GG{7K,K W {4UNUn;HV^,UF
    int i;@J-R Q$| `f3O SX$s
'G^D._Zl,P
    sprintf(res,"%f",result);o"vY}4s ZR7~V R0t
    i=(int)strlen(res)-1; r!_7G m4F~j9j2^ l
    while(i&&res[i]=='0'),Y,a ~4\A
    {r`ZY;f6_%O)u
        res[i]='\0';
li3Y3jgg         i--;
!A$uBB:GK)F     }
tM_D8a/Q     if(res[i]=='.')7Z;la Q&Sv ya1Yp
        res[i]='\0';6T1|![[;b
    return res;
E ~ ?&S[FQ }'Nbu`!meJ
%Xqi&P-]-H,s
int main()
B6c[z_` {
6Qv\ V!F ~p     char ch;3k} Q4H C'am
    char res[64];8V8b$hRq"T WS
    float result;
F0t)r8c8`F1|#E     while(1)
aO:{#~*cURz     {
"^ ?/] Z6Qx(^ck         result=compute(); xJ7G`7j N;z/``
        printf("\nThe result is:%s\n",killzero(res,result));
C%c,U&s.g@2O/w3e         printf("Do you want to continue(y/n)?:") ;'{ }o#E4A FL
        ch=getch();
1}${.fuE7QB         putchar(ch);
1d&Nq-Mm!pa|I3ug         if(ch=='n'||ch=='N')
'sF PkEj3XZ9t             break;C_[ F3XE
        elseC;KCjQ-_*q"AV-I
            system("cls");(d x,nKV)Vji
    }
V1oV%],ec     return 0;
;d,R2s {,eXJ!E1w }[/i][/i][/i][/i][/i][/i]
2N I1{"~ S#X
#O\.KfCDgj [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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