捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.L:Z t}9fE:x'o*E$T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
W'\ P5A$_:lKi$N /**************表达式计算器************/6_*Z.{+~z` V
#include <stdio.h>t.k+e-R(L
#include <stdlib.h>d!N\ m4wh Y(B;h m7a
#include <string.h>v'Y7{5gG[ WX
#include <conio.h>9e/E\:j.J5q-t+p
#include <malloc.h>
Jh'RT#Be\ZX(Wq
Kb.V$D_+\2V/p #define STACK_SIZE 100
QLH }HBv2^ #define APPEND_SIZE 10.|'K\1lS FB#N9q&_

f1y9\:u4y struct SNode{
zw$X?(Z(J     float data; /*存放操作数或者计算结果*/
[ n5@W8W,S!X(b     char ch; /*存放运算符*/
#_2@4FZW#p(CB6r }; JXL)A2@Sl e
,Up e OeL
struct Stack{"[P~B#X6z @n
    SNode *top;
J*AH8rf     SNode *base;9Bo s&Y]VQ;g
    int size;V"?],nF+A
};Qb6J0J L p

7?;d"lv+so /*栈操作函数*/
!S&Ugo(i)eS int InitStack(Stack &S); /*创建栈*/
"drI l8I;Y\ L"t]lgf int DestroyStack(Stack &S); /*销毁栈*/Jzo6u7C&u;J+[
int ClearStack(Stack &S); /*清空栈*/Y js1okX
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/a"t`2q)?
int Push(Stack &S,SNode e); /*将结点e压入栈*/u fi:? l+Gg[
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
PM ]J9lze1TyzD
y+G Q'Xl$P:U /*表达式计算器相关函数*/-D&jE3oEe*`\R
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
in%]9L1U9S1lO5Z int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/CY AS2T6@q*].]t
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
;M(M6\!]Cz.RS float compute(); /*表达式结算器主函数*/ i,j:\VV qV
char *killzero(float result); /*去掉结果后面的0*/
.Yx!i'@H i3vV
;| hA$v Z int InitStack(Stack &S)
N4t1nQ} {~o9V Din-@*x5O
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));H m0O4_/mG*yA5e
    if(S.base==NULL)R4cQ:Wt6c \H
    {o6Ce3K5ZsB
        printf("动态分配内存失败!");
2R*\;f:KH;W         return -1;
U~1Cc5`*c{:QA+L0?     }
0d%Tr/[ kc     S.top=S.base;
m I"` YD     S.size=STACK_SIZE;
rG{7T2@(hu Zf$rH     return 0;
We[ w5A E }
d8C DDIxv CG&aH,Q4c
int DestroyStack(Stack &S)9vp.H)fjk
{
&}!cx&I)x1\     free(S.base);ky6b Y"^ \ h
    return 0;I-^8`yd0c
} qGqT"OW'Lz

E2\r9eLilX int ClearStack(Stack &S)n^dgQ8RU
{
/nl0p"tw     S.top=S.base;{CVA7Gh0Y rf1a
    return 0;vPTF7Yk3?g
}
Ed u'`kx#v.pl? ]6Y Cp/r6a+b&x}@
int GetTop(Stack S,SNode &e)
*w-{8t-I R8TE9F y {
%\P ]8E8_#p?     if(S.top==S.base)'N1Vqn?:p1[5B
    {+k(s8E4[8h` z8eyP(G
        printf("栈以为空!");b y*[q~2~V_
        return -1;u-u `B8Ln d~
    }
;|5ns*I%F*e3~     e=*(S.top-1);
Y'`+ve i)t$qd     return 0;]BC-Yt~
}"d7Zfi#MNy

EZ9K&y,gY JT!J xZ int Push(Stack &S,SNode e)B(kjfJu2V
{
vJ_U(@#_5k(`     if(S.top-S.base>=S.size)
,uW]L6GDJ1v!K"u2^     {*W v%?4a-G'Av
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));W2Z ttT%f
        if(S.base==NULL)'[}`%p+u%^
        {
HH0W l ISBk-W3m             printf("动态分配内存失败!");
e8|#d8j4o,x `             return -1; a@5jy$mc3u
        }N\ ` F:?9S$\ t
        S.top=S.base+S.size;
g+v:?QT^n         S.size+=APPEND_SIZE;
@&\)|-H0l3}9ln     }
*{?`k#uM.is4X     *S.top=e; ZpE?w b~o
    S.top++;U7~ M;Z K%?M8]&Jg#X
    return 0;5J.J&`5]"yYy
}aI4e'D4n}1`p
6F,BCE I6P~4~+U1?w$`
int Pop(Stack &S,SNode &e)
uwD:Q}!] |"jf {
q(YW l^     if(S.top==S.base).C bOfS4j
    { rmz3D&@T!E/v
        printf("栈为空!");
C(E-m9Y*L2g2Xv%U         return -1;#HX}3u"}\&H)k
    }
K5R:b f*Dh0e Z     e=*(S.top-1);
f8t+~1EM^ B+w&c     S.top--;(lS8x S/AjBR
    return 0; \ f9aBR8k
}.K| B$L'UX T
'YS I:F,Y$Q)r3gl
char get_precede(char s,char c)GV^iQ+j.WR+X
{:J_8i^%J
    switch(s)N*dV.OXCd,Pi
    {#cW\h'_C9Y9ma1r
        case '+':                 p9l|D;k3vXJh
        case '-':
z(@'_~ u$O              if(c=='+'||c=='-')
+j;J7niu i!z'fl                  return '>';] b [ G n eYbNd
             else if(c=='*'||c=='/')2V4un` yW%@h'N\oU
                 return '<';(B`:l$nH~
             else if(c=='(')
,p zPf'i'q(_3NCU                  return '<';
WDsrN\VD              else if(c==')')
.MO%qR#t s/JU                  return '>';0a&{nB%n4f B F|
             else
as ^k:D                  return '>';#@4y{_{7L6X|
        case '*':
*N oU }-D6R/FO         case '/':
4Ra*eYe              if(c=='+'||c=='-')
I Q#G{%q0{                  return '>';2_8_q&| Yb6U6w
             else if(c=='*'||c=='/')~)L8kr8]$oB4qM
                 return '>';
qVX}AG              else if(c=='(')
H&p,V;}y hS                  return '<';
``m b9B;to*J              else if(c==')')j b8AH9A!U
                 return '>';Z B4KAmQA
             else
la}7O7@ c,p9a                  return '>';
5{"t.UR0s         case '(':
n \%I5iX \B              if(c=='+'||c=='-')a\%U _%L
                 return '<';A6~9I7?p3R B
             else if(c=='*'||c=='/')
4L Vjb`B                  return '<';
X(JL0nspg&Pt(M              else if(c=='(')
(g;c D/U K(}                  return '<';8Kl P7t6Ni7~;\~
             else if(c==')')'U4U;v3^`
                 return '=';b/\5o R$Ib&O} t
             elseJ KJ%V.R)N4yt
                 return 'E';
,h5Y-vGm aDx3jH         case ')':#j AW%tz\:\'K9r
             if(c=='+'||c=='-')
-r_\no                  return '>';
Dl-l'R3hh'?Z              else if(c=='*'||c=='/')
:[r/wL QE\ z(h                  return '>';
AT4Td+V L              else if(c=='(')
7u G-@J4~WIO.E                  return 'E';/JM+\P(mi^{
             else if(c==')')3B)ik/X|_ W
                 return '>'; y0YC M'fk
             else
1wW rK6a e B,A                  return '>';A{!JzF'R6d"f8Y
        case '#':/].U~hA~;]+o
             if(c=='+'||c=='-')
^}'aDM                  return '<';u*w!b.D6i n K*Q
             else if(c=='*'||c=='/')
'rN:?{5]2ffF2R1gD5m                  return '<';2j8K9Z y~#xh{$m
             else if(c=='(')
w.jo1hyR(uR$X lz                  return '<';
[ e;Z E^_Qi~8C              else if(c==')')Jv-IQT"dg-ktiH
                 return 'E';&UN1ja3TR f
             else G%N o's{HY2X
                 return '=';
(Q1oNwcG;E         default: idZ5]0qv']+DWH
             break;xR~^'B],@ k9H
    }h0{u:EB
    return 0;   
|+D |'Fq/O0O-S` R }
T5_$W{/F3q:NyeS5\
vh+{ LiDG6F int isOpr(char c)
hVv Sy {
e)?&}5Mj*nA     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')n6]'xmg;[/e
        return 0;
Kp7V9M$WG9SK     else C'r;b_[(C4gUX
        return 1;F!m6J*q/s
};|Vx!I/R VI

{&X/A;_ t float operate(float x, char opr, float y)!L*w q+}P4}
{
GW+B(wh$l3?     float result;/Ua/G7J f
    switch (opr)"lV'B~+d4jFU!W
    {]3O{%KxDu6\-zV
        case '+': Xf@ g;A%U~
             result = x + y;GR)D xml
             break;
r`P4a$|/|f#o         case '-': U8{-u2s]/@ Inx
             result = x - y;
;Ybha5thV              break;
J&ZU;?PSB6MA         case '*':
2BM;[|)U\p/b              result = x * y;
#Oeb*A)vr#y-YW              break;
Eb }K1I1z T.fg         case '/': SeUGR1f`"v
             if (y == 0)
,}_det.y Z h              {:N.|4J:sEm7zm
                printf("Divided by zero!\n");
BY vB:{_bp                 return 0;
z'| i4L6u$NF              } g\`+ThA
             else
'J.[@Y]X*^;@              {"Ok7U%T$Mda#FdU m ]
                 result = x / y;,_^_7B'iRi/y
                 break;/pQ2Sk.Oy
             }Cx%K?y~c
       default: 5^C1hl\-Fa V
             printf("Bad Input.\n");
H:^iI] _+XU              return 0;
| m.|L:M7G)j*x:u,`     }
J"gz [)u"V$GQ     return result;
$mm t#B Sv }    XY mXY;@
v)i1a1ry
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/7QTLx,{
{
-jD2O0P%y@b&U5cR0?R:v     Stack optr,opnd;
} f'OdL.s5n4l     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;:[+W FM J Zx3JV
    char c;l5KCl y&E QY r
    char buf[16];F(r(RU#o&I{$i^M:M
    int i=0;8e4U x Mo.Bf1i2E|
   
QD.l'Dp     InitStack(optr); /*用于寄存运算符*/.n"Qf3T H
    InitStack(opnd); /*用于寄存操作数和计算结果*//Cw9DL(bf'i9C
    memset(buf,0,sizeof(buf));
_ s,{Zp#`y$@     YE f6B%K
    printf("Enter your expression:");G3e_.S&yop
        
%Q+W ~ZdR/Y!G     opr_in.ch='#';
W(o?NY&G     Push(optr,opr_in); /*'#'入栈*/
)A*p]}dbY,s     GetTop(optr,opr_top);
;SqINF     c=getchar();-] hCN1d)J.l9|
    while(c!='='||opr_top.ch!='#')
oa&F3Tt@     {+T!giP^z nz Kq O
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
Iz$e7|3ro%e ^         {
t+\@ H^             buf[i]=c;gV;B5v&V3{
            i++;!z1K.fGAp$h
            c=getchar();aO~(Y7|2l0N
        }
1x \KV `Cf         else /*是运算符*/,U4[2i9]|+S5L4L
        {
{?0r`*H(\             buf[i]='\0';
+W#l'iP]'\             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/?V.\5Lz*M ?
            {
yt+n`0P2x&ZH\OG                  opn_in.data=(float)atof(buf);
.\e5a_ _ D                  Push(opnd,opn_in); o URNI3pT]E
                 printf("opnd入栈:[%f]\n",opn_in.data); ex!a8S(n*qO q{
                 i=0;
I5Fp4^3s;M                  memset(buf,0,sizeof(buf));D0{wc@n,zq
            }*j qc)NtTn Rj
            opr_in.ch=c;+}c4n)Y+{a[
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4] oeGy.J2O             {!r-S0c-wWj7?
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
8k*]9cy.G;{#qX                      Push(optr,opr_in);6r7pg6H n!rK
                     printf("optr入栈:[%c]\n",opr_in.ch);
q4C&`-iH fM                      c=getchar(); \+}D@^Fy7q
                     break;
4YKl'Vq n k!yF                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
D``)\\&D`V u                      Pop(optr,e);
,YC;R0I(Sd                      printf("optr出栈:去掉括号\n"); ](o%P:w5^J Z+^ D
                     c=getchar();
)B[9f5VO%n                      break;
sg\7{;V_ ?U!@                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
'g#xkq)K9N$I.?3W                      Pop(optr,opr_t);'c.BF,UQ#R
                     printf("optr出栈:[%c]\n",opr_t.ch);ag {{{
                     if(Pop(opnd,b)<0)Ta1U f x4[
                     {
/c&V1v.e;@(_ s                          printf("Bad Input!\n");V!h8r p? |ht
                         fflush(stdin);
/A_{e#P.TBO                          return -1;
cN"y x/o(s                      }pk2FK%_
                     printf("opnd出栈:[%f]\n",b.data);K,dQ(K K4q K
                     if(Pop(opnd,a)<0))lM"xYk7| l \
                     {
w liut7e F                          printf("Bad Input!\n");
5P%I ri0V#I                          fflush(stdin);
j3u(S5Qq                          return -1;
kCy*[#D.\5gL]                      }
ps-r:t HuBi                      printf("opnd出栈:[%f]\n",a.data);3{J_R d;j}] {
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7Lk%`*Cp
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/8Q.|i GJm8A G
                     printf("结果入栈:[%f]\n",opn_tmp.data);
S}6mC0Q?.^*z b                      break; l{ KGz8j%|Z}
            }v8kPdO6iE2t7XX
        }C6V#f2R*I1~4d
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                Ik;X,cs7[
    }{wg!n xcjZn
    GetTop(opnd,opn_tmp);(uP As/^itUj*s
    DestroyStack(optr);v'z*]tm$O,D
    DestroyStack(opnd);@)u4ss }\m.h'n
    return opn_tmp.data;\`Q^ V/vliF
}b^Fr8JGg e C
/X/a6uA;Tu A/L9bG
char *killzero(char *res,float result)*[F3`0P C~Q'`I
{
&GrRF2b_,\&A_     int i;&y`2AJ$e SH?/RQ

-v(S@`t~M     sprintf(res,"%f",result);
.w AeE2h     i=(int)strlen(res)-1;
j4~n!c&`uf     while(i&&res[i]=='0')[e!P#~ {GwP
    {+zi.t.XG:RyV2c Lu!k
        res[i]='\0'; q/[,J/}9m~Px.S
        i--;)}"T:}-ExZ u)h&^,A
    }
9`(u:Z,Zx{     if(res[i]=='.')
MP'QMR$X{Z         res[i]='\0'; \G \L[ n.v
    return res;4cQ~7nD)R aX!~
})Q QV;o#] M(g
U&t]-B6A
int main()
9?%D@#c,xe {4^ Lr-Qu*A])zN$q5^i
    char ch;
/G }Y(V!d-e+\     char res[64];
\$L%MQ:o Ft1qz     float result;
1\1C(@9Y!~&gI     while(1)
6C/S7G~"bGHg     {WFCyr] Y{r7b~
        result=compute();
N;P3b b;Q;R7y         printf("\nThe result is:%s\n",killzero(res,result)); ~X9]T\%h8M
        printf("Do you want to continue(y/n)?:") ;J.i/AP@-y([_
        ch=getch();*r2K!um[:W/s?\
        putchar(ch);lmy C+^hh
        if(ch=='n'||ch=='N')ja n,r C8u+E+l
            break;#]BVtVUC
        else]&P G/N:K"z(cO \
            system("cls");8| hl3V7Kccb
    }
n#J9mU|&g[`s     return 0;
mu3@dh+dWk#|I }[/i][/i][/i][/i][/i][/i]
7j)P\&_&P&~P"I-n^g +G0^A2WE'O.Os
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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