捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
VL wB\ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
!Wm5| y)L /**************表达式计算器************/
I(A_D7C:|3i*kC #include <stdio.h>7m+q;~R(]
#include <stdlib.h>
}P~7P]%n|g #include <string.h>
K.QP0B/r K6C aS #include <conio.h>JVdvJ
#include <malloc.h>fIFOf
`6{GFK4C#Q9q
#define STACK_SIZE 100
/SQO/AIK nF #define APPEND_SIZE 10
s}-p^{$~&e S&o4}dQ k1Y,xb,Fz
struct SNode{E5P-yG9@u&`?f
    float data; /*存放操作数或者计算结果*/
(\)G"}t]~w     char ch; /*存放运算符*/6il*s3AC&J Ce1HO2R
};~5G,F9rk w2s

#b!K(W!y5i6A9{6a1K struct Stack{
%i;{ \H?*@"M     SNode *top;_Jzca6_$d3s8g
    SNode *base;
%Xy7i8L\4R     int size;
}? B^.@:B };
]7?^2e;f
s-T j|O-p } /*栈操作函数*/2sOR3cYcK
int InitStack(Stack &S); /*创建栈*/L%q`(t~:K2vN,J&M3z
int DestroyStack(Stack &S); /*销毁栈*/
}cOLYA3c int ClearStack(Stack &S); /*清空栈*/
}L;?Y7H/n2[2Q int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/\k/b5RV8BI@.p
int Push(Stack &S,SNode e); /*将结点e压入栈*/
-G&W)\z*h7e int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ Z N)J8|S7W

.V`%l@7I3H /*表达式计算器相关函数*/
#wqM] o,c5U char get_precede(char s,char c); /*判断运算符s和c的优先级*/[8hGw1_Re ?3o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
W,i4TWb\ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/~R3~-UL2oB float compute(); /*表达式结算器主函数*/
\!r+t],n/r*d!bk char *killzero(float result); /*去掉结果后面的0*/
\4HapTEJ 1j t;Y9V;h"p"l-N
int InitStack(Stack &S) V^TI6hFc^Ou
{ xL5n l%Za'[j
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));| Q@g3a9j7W
    if(S.base==NULL)Y8l'ou/p2T}m
    {n8]WY;F5P iw
        printf("动态分配内存失败!");
q'Hk/J!g+q X         return -1;
0d@Gpi8e P     }/U6xQ]hXIk X
    S.top=S.base;
&m3b(cC?7@0s     S.size=STACK_SIZE;d7K6z v/sj}0_h d
    return 0;)NC6w!JB#{
}
A&Mh0BX2M mao HX "K9B-jb }N.Y]
int DestroyStack(Stack &S)
U7j%bD$N {
e2~"S Z2Z*^]i     free(S.base);
z wY(_p{     return 0;&N5QC(f%mm Gg`
}
"a&w\V`V
nYQ!?X l fZ:~v I&Z? C int ClearStack(Stack &S)
W u ^\+wDV B {
.Z1Dr2s*F)wg     S.top=S.base;(@ j8en2|*P~p
    return 0;$~1GS%Jl7S*NZ
}Iu-cw:t9` G bk
P.n9[.a h*{;ic
int GetTop(Stack S,SNode &e)/e[g1OyAEb:|
{/| sh3[~P\L
    if(S.top==S.base)
0qQt!c3W x1?&~     {-U`[2wrZ
        printf("栈以为空!");
5`L_ FVgA8{`&Dc         return -1;%Q:Sgnh6]e3EH
    }(YArS9U7ZR
    e=*(S.top-1);
z&zE&`*lT     return 0;E$g!j5zBhthY
} p2b4q!S5H
wPm!f T X)Nk'U
int Push(Stack &S,SNode e) eQ.QNe"S9RsZ
{
@L6q t0c]     if(S.top-S.base>=S.size)*i$k.q,T"R t a
    {w[B4\,Oqh
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
\7Ez7Mv c         if(S.base==NULL)
M*Z5C ~/G         {
+o)O3hS r*{F+q             printf("动态分配内存失败!");
cqU,v }a\X             return -1;
zN7t)KfY{         }`0?:S FyT `d\
        S.top=S.base+S.size;-gI7]4^^7WXUNP
        S.size+=APPEND_SIZE;2q]5mz}@^},Q
    }
:R4[]+n4@*f6i _     *S.top=e;
C5l_ t;xh @Z     S.top++;P5? ]"j6Trd
    return 0;6^rc'LZ
}
bfO)?_:i0Le!s'h!Q L1n%Q
dT.d.U d)Yn.g int Pop(Stack &S,SNode &e)ieG5d(Y!qMA(F
{?:i`'WQ,x
    if(S.top==S.base).t0sSQ5O/V&d [?
    {:c{X4xB F$\7U1X
        printf("栈为空!");
J M:Fy8s.{9}s         return -1;
vg]g?8x"T#VCVd     }
0P#G~j-T9v$y(C     e=*(S.top-1);CkI9FX'v
    S.top--;
{"{!?"{&JY;y     return 0;&}g w.W~+uR@ x
}
cG9o/D9EY r9U 0@ e:d6e*[1\F`4w"Ro+[
char get_precede(char s,char c)
w!OO,fA9d {@:j#r8q4T$b$H;X G
    switch(s)Y3vfl+W1a*LP
    { b;F a:[(O l
        case '+':                 @[:Zmk
        case '-':
-H7~Ofl.ZO(G9p)E              if(c=='+'||c=='-')
a[ k-^J9N!y                  return '>';
3CX4\2l3B8r`4W              else if(c=='*'||c=='/')
jpH4D-p4M                  return '<';4}`'c(]L6`
             else if(c=='(')3z C`p ^5^3\1Ku
                 return '<';{X8K n,X T
             else if(c==')')
J7?)a:Fj!Wo                  return '>';
2L,]yxCC iy@              else e$R&y~ b#mg/N6]+b
                 return '>';
d3^*lN;_,^-{3E         case '*':U){6A%W5p `-[R
        case '/':YF#O0xMN?6l\U&L
             if(c=='+'||c=='-')
9\@p Qt(\E                  return '>';o6U$H)g}T
             else if(c=='*'||c=='/')wPzo~F
                 return '>';ycv Xy,n `I
             else if(c=='(')FG2e z:m5e w
                 return '<';3T*|;?#|*Yh
             else if(c==')')
u["L4|*m:C'T-L                  return '>';X ]#I6K4Atyz
             else
9v:u#V+_u)s                  return '>';h`q g/`!eS
        case '(':#r5nMb0C
             if(c=='+'||c=='-'))q(TZm `
                 return '<';a|*A$Tai8{2su`
             else if(c=='*'||c=='/')
BQ ?-VC5y)a,o                  return '<';2z(n7fF*yPl
             else if(c=='(')
9J7Xa%c:MV,tCN                  return '<';*pVDP"y7rW y
             else if(c==')')P0n'{3{?"efY[
                 return '=';;X;et7|)_*f9^f$r
             else*[Thx-Rn"y]#X
                 return 'E';'LF[2M` m
        case ')':
2b:e;\X6VWl^              if(c=='+'||c=='-')k/uf0w.N
                 return '>'; Q?f0Os
             else if(c=='*'||c=='/')I7u6d&P'x;pK
                 return '>';
6F7Wrxj&W4N              else if(c=='(')s*c N EA3J
                 return 'E';
w&I)k }$H On              else if(c==')')5} qfS3fA/O#vcU
                 return '>';1\+d"KX^/Z0r2a
             else
L^P4FIIF8Vr+PA9{                  return '>';7uoi]7l
        case '#':-R0^` [`c
             if(c=='+'||c=='-') DnAm:WxOi"i
                 return '<';
]q:T5o r              else if(c=='*'||c=='/')_m~:z{$x5XD k8h
                 return '<';
OH gOdO#i              else if(c=='(')_QJN~
                 return '<';
F+g9o9N4X              else if(c==')')7i.kY!E;D n:uE
                 return 'E';4]%Ku*\4Q#d%m^
             else
h H` ]0V;r/n\6i                  return '=';%L&HO8tb
        default:v2B q~7Q
             break;,QU0e9dc4J7XA
    }
D9~*G4r+z~W     return 0;   
bqOia#k#q*[ }
,E;O mk/x)N&{j[
QZ8k$V$`b_ int isOpr(char c)
@W0T&[[L8c { eZT%c6l,c
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
P+T9O\7k1}2NQ         return 0;\-k!M&c? {Ty
    else 9o dka*c"?ek(K
        return 1;mG ERZ
} [8d \9~ oy{;B
n ? B&]BB [u%]
float operate(float x, char opr, float y)$^.TWIBW'g-| I#o
{%gSVpGp+O
    float result;*y?wj%M)XT
    switch (opr)v |hH-_mh-K
    {h c.}xI'|gV;sZ
        case '+': m9F [Ez%f#e^ S
             result = x + y;QiC:p6H#H
             break;
:S6MO,Y ?~         case '-':
XZ#g:o"Jg              result = x - y;
p&a&u&J0y4^'b-H9\ r              break;"XL;F%FYSR,{
        case '*':
,q8pH1u_0u*r              result = x * y;?D%pd^b9l!LM^
             break; K8rq C1R:F(Q8L*\
        case '/': $^:?Z@x!@.J${W
             if (y == 0)o/bx!un f5\8P3`
             {
$A,a*fZ4j                 printf("Divided by zero!\n");pZKABC~M+j
                return 0;$biA"} OA9wK:I)W
             }
x/x6@*@-B1tE#S_              else
_Erx7[{9z'_5po              {
"c Lf'MRI                  result = x / y;
:EB/S{q B0y/kwD                  break;
)R6Eh zMmM|#e              }
Z'ZPick uo9D        default:
Q5t?/P;X?x(U-y+}              printf("Bad Input.\n"); -TA.n m9WN%^nN
             return 0;!AOT|'n6i
    }
LrA x6E]O:n3D     return result;CVL GF D-E e
}    g ?:ov,D2|v'Z6o#W
3Y&G OA X9q[5fp$T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Tl!M VaU {
'm1d;d`E|     Stack optr,opnd; C2?YG:\Fu8D
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
z2h&FM] s wJG&m     char c;
}{K9M*nz     char buf[16];
o7E1^P"C6zl     int i=0;z2T ?n3g^o
   
1?K8l3bOL     InitStack(optr); /*用于寄存运算符*/K#sw6G0lgy
    InitStack(opnd); /*用于寄存操作数和计算结果*/
/_`J&}!^.}     memset(buf,0,sizeof(buf));
WxOr:R-y q(z$^     .y3UiG[ v/[
    printf("Enter your expression:");
!Mf%KrC apL         /a(G${%qX[}k M
    opr_in.ch='#';
a eF4r3i5o9T     Push(optr,opr_in); /*'#'入栈*/,`'B/A Fj#H!DdBC
    GetTop(optr,opr_top);&Zb6`aJ+~j$o!~ T
    c=getchar();I5lm*hUh5|
    while(c!='='||opr_top.ch!='#')
2{-z_dGM pP0b(d d W Q     {
*C Z/V|f#Z*s/po         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/'@cy4h,G [bw
        {pJn W~:@g5Uc
            buf[i]=c;lI'C'Z\;l M%X D
            i++;%Wt\p(D+eZS
            c=getchar();1};TPh7U RtV
        }
N {1g S.UU8M         else /*是运算符*/
.IvC(Sgr:p5Q         {-\}q~1L#Q mE
            buf[i]='\0'; F)~n/[aa-s*re
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/,]:A%\Y V.c;r F2tB
            {&YFCv'b'u7E;n{
                 opn_in.data=(float)atof(buf);?)Xt_{b1mL9d
                 Push(opnd,opn_in);Evg'^H
                 printf("opnd入栈:[%f]\n",opn_in.data);
h,K~1n*z9C&tL:uL                  i=0;3yqE"L{s
                 memset(buf,0,sizeof(buf));[w"uA:r/Yn)oK
            }
)D:L;b^|!Mec             opr_in.ch=c;gI/u ay&r%uT"\"_
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5zi5toPl9?!E;L(r             {/~8n czo0w9T
                case '<': /*优先级小于栈顶结点,则运算符入栈*/,r.S1x;L!Oy
                     Push(optr,opr_in);
|5u s&?B?/g3},a                      printf("optr入栈:[%c]\n",opr_in.ch);
)@5dib+O                      c=getchar();s am:@J;q.Sg
                     break;
A;x'j#q } ~)S                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3^;~6]f w3@9P                      Pop(optr,e);8bdvB8x&X;q~
                     printf("optr出栈:去掉括号\n");U+~u+VbzhE!_
                     c=getchar();6HtM;K E;G@bC
                     break;'Xjs#u3k"x,^I
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/3TX R1_!^7nBp
                     Pop(optr,opr_t);
?4A%O.\4zV.Ct                      printf("optr出栈:[%c]\n",opr_t.ch);L2d"S9`!gZj5y
                     if(Pop(opnd,b)<0)
jM"I6@-DEe                      {^:MP` f,w-X
                         printf("Bad Input!\n");OOGg^6Tk:zB*O
                         fflush(stdin);6Iq0~8\2U iz[/QW
                         return -1; V FrA m2w?8i
                     } C)k|iA8xQ{l
                     printf("opnd出栈:[%f]\n",b.data);|:geTNU
                     if(Pop(opnd,a)<0)6Hr9xzM2E~"u7Pu
                     {
,k&H u.I Q2Sh6t*u_                          printf("Bad Input!\n");
+q0m'Z#z,J J)a                          fflush(stdin);9hD {wPX&Z,j
                         return -1; N@Q!Y }6d-s M
                     }
.I Rs9n,Hdb"c                      printf("opnd出栈:[%f]\n",a.data);w3IJ'dW_-i
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/n0ym,hY:Zv
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
G6A|,RP1yV.FX                      printf("结果入栈:[%f]\n",opn_tmp.data);9V1D+~PcM`T#~
                     break;^$w,IY^ E S
            }
YI/e5t"A5l         }
PS6v1u6~Q+J:^Q;q         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
6b{f#J6g     }
7E8n])p [!b     GetTop(opnd,opn_tmp);
6\9~5R{$|y \S     DestroyStack(optr);un MP@0T
    DestroyStack(opnd);8`/bE[@u+h)]E7z3h
    return opn_tmp.data;O-In-m"v!JWk![
}
"Z ]1M1q{1hvV4NRZ#U
o$_2j)o(Am char *killzero(char *res,float result)
+O5FU1Nd:LY,w {
*{ |~ I0z6QW1F?     int i;+heROVsX5I
XIN!M2l-R
    sprintf(res,"%f",result);I9c.u:F&@|
    i=(int)strlen(res)-1;
ll#BS tgw6v u%v     while(i&&res[i]=='0')
V3P-w"J,t!g/c     {eA+jFW!r
        res[i]='\0';
![-cd!y;oi         i--;!B {yIif"R)T
    }@-MxcU~ O W ^
    if(res[i]=='.')
0t;Pp ZRq         res[i]='\0';
L^Z s&H!y-Q IO     return res;
}&aN;C-WD!x~ }
L4^ A@,~d5a1q |?:G?2V9u\b s
int main()
u:k9yRs7j%\ {
S)G"WDGcb y.yA%`#b     char ch;O$X"OK"t3d%J
    char res[64];4i"[*qA{
    float result;O%]7i2O WM0v
    while(1)
|p&DuV4w/y     {
2oE,`#Cm6W9N         result=compute();7k D(Y't5E%E/r7z X W%u
        printf("\nThe result is:%s\n",killzero(res,result));:M1@X)^fS G*Q
        printf("Do you want to continue(y/n)?:") ;
;t0|1WC1z3U9i#^@         ch=getch();
W6n)pAj4AV4h         putchar(ch);
p7ibz$K r         if(ch=='n'||ch=='N')
,\+| cKv             break;
2r!f1Xd&O:QnU         elseQSb Y.?V$_
            system("cls"); {!D4d#@pc e
    }
4vr4~N?`!Q+c     return 0;-iv'A"}5f
}[/i][/i][/i][/i][/i][/i]u'u,n [d#z [%?:@

'Y(l6qw6h%PTl [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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