捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.DP{!qWw~S6Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/h pV*JX
/**************表达式计算器************/
#E_A"kZ"x1y]i4j #include <stdio.h>
5`lA,bt[\Z #include <stdlib.h>;_(P+p/L&a!~%Q:E
#include <string.h>
1XNT^.U4^ #include <conio.h>;gj\xxEg
#include <malloc.h>
\*N1]9W gcIz#E 9`4j8t Z f*f%j
#define STACK_SIZE 1000Qb)szSVb2U`
#define APPEND_SIZE 10
]:k6C^!KR"H+be7h 0ZfH.kT M ~v4z
struct SNode{
+q~)Yp|K     float data; /*存放操作数或者计算结果*/
+m3s3{_2Nz$d5iD     char ch; /*存放运算符*/SW5b#v9_ c kd
};
BJ3B.O'IqGy8H ,Tv.J3S4Bd
struct Stack{
Vo3A1wJ;w`;o     SNode *top;
;V,m)L&n5~R#w     SNode *base;
J4J9b0M0s-?#w![     int size;
{ m*P}VCF~ };
} K[3R(tO#R 0g#]L.xK
/*栈操作函数*/%XE{5[9d2Pr
int InitStack(Stack &S); /*创建栈*/1ML5p)Y#K;bcE"e&{
int DestroyStack(Stack &S); /*销毁栈*/
M A1s;i`5V(c"Q int ClearStack(Stack &S); /*清空栈*/awvNF)h&xxP
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
}2_9b9b5uiM? kO*s int Push(Stack &S,SNode e); /*将结点e压入栈*/?2w;yg6LIV
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1Wn [r!]
~BI!dls%}k /*表达式计算器相关函数*/
b%H*KpQA V char get_precede(char s,char c); /*判断运算符s和c的优先级*/0_ l1E7LL @A mS
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
rKB3H&c4u5A/z float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3PJ,W(J~\1Tz
float compute(); /*表达式结算器主函数*/9p'Z2D`(^ b P
char *killzero(float result); /*去掉结果后面的0*/
9?-V:W8t1Gh
Q6Q|'O} int InitStack(Stack &S)if.a i Sa0E0}
{
M @Lfl0QY     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));!i a~i\%r3z|7e\
    if(S.base==NULL)~pE,w^(m2O
    {
-p-s U|?C         printf("动态分配内存失败!");
N%iGU.~7ls C\n         return -1;
@7fH1O.p3u R+s     }sa!mL,yO?J+s$I
    S.top=S.base;
@8aMx8i(v0WzX     S.size=STACK_SIZE;
Xvb!}7rN     return 0;*x(G M/q&jv)N
}
fI w l!JK pD j e O.NO4`Yo8dX]
int DestroyStack(Stack &S)
*zsTV Ji,A6\ {
,LAoLE'K*@g     free(S.base);
[ L0O}+c F     return 0;
7_(zCI`m2PS }/? ~+C1H1O"Sj3p

:Qv FjfRJ$@R1N int ClearStack(Stack &S)
l c o$m\C8w {
,WK7j/b.D     S.top=S.base;
gAi!c4Hk     return 0;{v%Ff.J#MO8^4W(t:}
}
i1i&N+y_;x }
4e9^yq1S[#pr int GetTop(Stack S,SNode &e)
MsZq$I*X {h se7Y4bw%d
    if(S.top==S.base)
1\cR)e m&j-M$r%u     {j+R3?P_
        printf("栈以为空!");
c X7G:V)R!mL*jQGde)Z         return -1;
?`%[u WB x     }
g`&jM mu     e=*(S.top-1);,V-Qtu7D2i
    return 0;
w%z(tg5R2i1cT e }F"|rWqy

:E{'j GHs3U/gr int Push(Stack &S,SNode e)w&a1i@/kLNM
{
6Ub#zKd#[G     if(S.top-S.base>=S.size)}^,K d ]q;qF,|U0d
    {4L9W+K9l8wN
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));!C"NP H$o7x
        if(S.base==NULL)
2A zARAiO [cvI9l         {ON4u+v ^;k
            printf("动态分配内存失败!");/n[Y/Q"Ey:G
            return -1;
.Rm4C@;h;w}         }
?'e y{ rcp&G1T$L         S.top=S.base+S.size;z0H{5z7k1n#I y
        S.size+=APPEND_SIZE;
;k^*C3a;| N? }]cj;@     }1sDH~X&Ud
    *S.top=e;
0`5p%i/O f     S.top++;
MkXIt,x*j     return 0;
zG!_I.jrB }
M:y PMDm
.j(r h(U"gY il int Pop(Stack &S,SNode &e)y:Z5zYc l~mP
{
8{ljlP6\Z     if(S.top==S.base)
:C)a:C r)k T     {
(DU5MG3izx         printf("栈为空!");
&sV6FH*A1b2y5P$}j hp x         return -1;
'@IXEg2B3I$G)]     }
`+K \In     e=*(S.top-1);~:k%A3y"U-B
    S.top--;LZ x ];x rQ/F
    return 0;?n.xb7b(Q(J(Q
}
3\#hdT UbU
-y5j0iO0^2xg char get_precede(char s,char c)B @aj odv
{
2GBhuB     switch(s)
6N2F%QJ)a#K2qf     {
b)](e B)dH ]         case '+':                 9Me"B#A*[5B
        case '-':6R)k)epP
             if(c=='+'||c=='-')*I8} m,r V;o
                 return '>';
s3L#_1x FR3S              else if(c=='*'||c=='/')[.?sq&g?
                 return '<';r(a%UAO2t {K-Q0p
             else if(c=='(')b5DDh P%f%g1IH
                 return '<';
-X4QM TwoR              else if(c==')')*bO ZCLbU's3J
                 return '>';
/usRA:}OoY              else k"OG'E.l Z Acw+xno
                 return '>';8I2ibJc~4y
        case '*':
?4Pc%_S;n y F         case '/':
[y!ai"k A&~d              if(c=='+'||c=='-')N4I*\Jh)l
                 return '>';
|w@FD^              else if(c=='*'||c=='/')1smf _!E;q)ff*v/U@Q
                 return '>';x ]/O%D%Z C*Pc
             else if(c=='(')xJ)@)gD'P
                 return '<';/Yx(m1z8uT
             else if(c==')')0{e4e+qF
                 return '>';l j%sTt1c-t
             else0Di!Hl8[e
                 return '>';$T5W V3j H P^&_
        case '(':U n/Ge^p
             if(c=='+'||c=='-');\aG6Y#_-]P
                 return '<';
r4s2o.YW:k ?2b6}%z              else if(c=='*'||c=='/')
/Oy|2V7?6v&\Z(R&\                  return '<'; C"Bt;U} H%R
             else if(c=='(')
'f$[+J5b0L0pR%z                  return '<';wU8H,Va Mg
             else if(c==')')
'g\oP2B~$RS                  return '=';#v{ho,gG$w j0o2X
             else
)td6EGG,Z                  return 'E';
5YMY kgL$K         case ')':Q yC;M[eF%_ Q
             if(c=='+'||c=='-')
&E"@0q-O-^!U$Y5A,q                  return '>';
C{ @c{ uR              else if(c=='*'||c=='/')oK_"l mz
                 return '>';
U5{ R-i;E K1D,r              else if(c=='(')^o,n}%{a$V
                 return 'E';
[%Ou"Y \              else if(c==')')
)M\/_k*dVuI                  return '>';
.HQO4eIF-G[              else
t.h0u#l0}]                  return '>';
r ~VOH:xH         case '#':
1Yt']bti              if(c=='+'||c=='-')8n+W;Le w1`z'YK
                 return '<';5i5V2X`H2C,QQ"y C
             else if(c=='*'||c=='/')iN#B)YFZ$\~(Z!T
                 return '<';
bDE^H              else if(c=='(')
t.d-e0j1A"D RZz                  return '<';2Rc9~Q;ez
             else if(c==')')
!hO6f)` HF"x:|b                  return 'E';
pdZ4}4jh              else4L'\ o$d+os
                 return '=';"a&Tp}hIHA
        default:
C[xdDh              break;
5\TA7xR3D7nx-A     }
E+P2f2b,[ V,@7b [ N"ST     return 0;   
,|F6z3EcR8B_B }
&B6I5Yx*?$n-w 3r-D.o Hs pyc I
int isOpr(char c)G}M`Wa7] XF
{CZ zt B
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
#kG'\GX \N0?         return 0;0N0t6@ QtX
    else
&~E*K,l.PpL         return 1;n;et,X/^7EIN K%a
}6g'PFf-d1Y

4f~^*Y$es c] float operate(float x, char opr, float y)
W7`n8wY_x\ {
8B8DQ'}h3N     float result;a aP^F
    switch (opr)
8{T k(s3ac     {L@(S H!bA{
        case '+':
e5~#G8AZ-J8h              result = x + y;
.eP+l;?|&v              break;-eO"I7m(dE
        case '-':
Y7{ K}6^f'U              result = x - y;`&q uJsL#y
             break;
\-ama5@         case '*':
0R&y Uh9q5y*b7c[k D;a)b              result = x * y;
\-E nW/\#N              break;
/Z~J\Qt9J@         case '/':
k/@[2d%G              if (y == 0)
+k)o[)cNae              {
3PI)n/{%ftQ                 printf("Divided by zero!\n");)w%Yv O$m
                return 0;L$[J"R(~&O1w'hwZ
             } N2etTC4WX"NW
             else
9G,a3ST'U              {
\+fJcl~                  result = x / y;
,G I?d7\                  break;
G2a(_UagO              }
(B6hH&l#^+K%y        default: %Z)s+b-d\h*Z"F
             printf("Bad Input.\n");
*I7O wr)IBC              return 0;]jJBz }*Vg
    }
0D)\M(|6Z7x0]     return result;8A@pue|)yU C7e
}    \gwje|7M%g"m
#^.xp1Q4qK@
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*//MxE&IMhBQ!R kG
{
Ez ?;M U+z     Stack optr,opnd;!RroF-~atZ
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;AtDu WUk
    char c;
3B!w U N+M     char buf[16];OLk@;? V D
    int i=0;
q:_-v`4K5I _ U     K[_vj+@
    InitStack(optr); /*用于寄存运算符*/
9f Xu8D@C [#x     InitStack(opnd); /*用于寄存操作数和计算结果*/
3xb M9z2vS7pK     memset(buf,0,sizeof(buf));;T J0B*?!b2a"H%TD
   
~zR/E w,Y^]_ b#X     printf("Enter your expression:");
.FQ$i1\Tj)P         :t7o[7x-wR QI
    opr_in.ch='#';
]1m#^9el9X^     Push(optr,opr_in); /*'#'入栈*/ JAl(D*I'Af j ^
    GetTop(optr,opr_top);!L1\+WN/eKnS x7q
    c=getchar();
;j}V2| le     while(c!='='||opr_top.ch!='#')
A.n b [-ta4D     {"h/w @j/O(]
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
't,H+K7T]-zZo         {
[4wfmsT2l3_}8r$W             buf[i]=c;%Y9K-Y6b$G-i;o |7L
            i++;
tk0Y2k&`k             c=getchar();BC"C2WXSy5A
        }z7|l&c8]:V.wKl
        else /*是运算符*/
)~!zzj Ekn)C4A!p         {if`v;vt v
            buf[i]='\0';
+l8Uz$K*L+[(y8M|y             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
o6s:i"R1ecT             {&l.zb j|V5fda#a
                 opn_in.data=(float)atof(buf);
^'U^:m"Sb f`uz                  Push(opnd,opn_in);YrW)AC0v
                 printf("opnd入栈:[%f]\n",opn_in.data);
w5e"E mqEe                  i=0;
5zY$h8\ oO_8G7t$V5Y                  memset(buf,0,sizeof(buf));
i-O`lb             }:]-_G J*i'Ic&h
            opr_in.ch=c;o Gpk&fl
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/)i"~ pv2t `%cx/G Q!i8U
            {
+Fe%I` {TZ[2fw{                 case '<': /*优先级小于栈顶结点,则运算符入栈*/2zbf\'z
                     Push(optr,opr_in);
*Q!SiMZ-^~lj$dW6}                      printf("optr入栈:[%c]\n",opr_in.ch);8r}g NYK{ GzJ
                     c=getchar();
.]'X7G4D3o*X }                      break;
'V%A`'sX                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
B+Ve^6@1K                      Pop(optr,e);Iy5? _*qv6H
                     printf("optr出栈:去掉括号\n");*eX/Ko+A#S \O
                     c=getchar();
P#h-h:aW                      break;
!Xq U` v/K9M                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/sPM3a8y&D:`6d2sG
                     Pop(optr,opr_t);p-p3`3A5k0}|'Z
                     printf("optr出栈:[%c]\n",opr_t.ch);p(?_ c+}%b\?'Hq
                     if(Pop(opnd,b)<0)
zk4_G'gn1aM%K                      {'w*a7LsQ6dbO{&Z
                         printf("Bad Input!\n");
neOTe}e                          fflush(stdin);!iz3e a+o4i
                         return -1;
\ E4Y[~q                      } ?+r5T YJ,[!MV)t
                     printf("opnd出栈:[%f]\n",b.data);|.{'C#G_Z"sH+L
                     if(Pop(opnd,a)<0)ME3q'F}t1tmZ3Z"P
                     {$\K ~g9SE#U]Cs
                         printf("Bad Input!\n");
[t qC(w$~                          fflush(stdin);}A]cg.Fg5x
                         return -1;\ v,[ \%u7q S4kp!z
                     }
/g'hb/So                      printf("opnd出栈:[%f]\n",a.data);
c)b&CJ1r||7L"L                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
&oY2SNe*b:F                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/hugd`#q*@-b X
                     printf("结果入栈:[%f]\n",opn_tmp.data);
s2QMIN                      break;
S \ k$g5R5xR Y             }
L5[4M;PMR4\         }
-`1me_6E%~[q(~ `         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
G2d4a\*PF.l&N"F;mr     }A5O!R(qM
    GetTop(opnd,opn_tmp);
pC W'cN@9J     DestroyStack(optr);^2{2bAu jQ })R2cL
    DestroyStack(opnd);2])v;w_kq
    return opn_tmp.data;
z+s&_/TKi }G ^ R[-c5Y8k
CW jO+P7U:~
char *killzero(char *res,float result)
dF4w%su9a {+DN!fr'^
    int i;h2iX;hjiQ.MU
t^&q(V;T4qaLv vk_
    sprintf(res,"%f",result);
(l6BQ*C!k r6zS+~     i=(int)strlen(res)-1;+sq8c5@Y
    while(i&&res[i]=='0')
jH~C]     {
|4Ycn+M         res[i]='\0';
FNxEj7[g         i--;-|jR7X-rjuF
    }5Y(Fr.Qp6w1c{f
    if(res[i]=='.')1XYXN;s%EhZ|$R
        res[i]='\0';U9Q,K]f8uC_.T
    return res;
\kL/h"T F \N }
F#jdl7m d
.z aN5P%}/BGz int main()
6e%}%s vK2J+fz+]7cKu {
&v)i*F&C0E     char ch;+Q3E&M"\!m1L
    char res[64];
A9ez6]%Vw*{     float result;
(X!W,N"\J4tw     while(1)Ao^'r+g(A:O8Y1D
    {0T/r3`[9U Ln8m
        result=compute();I1]cLG6y
        printf("\nThe result is:%s\n",killzero(res,result));
Q)xlsX2[9E         printf("Do you want to continue(y/n)?:") ;
m:s9u3utT%v         ch=getch();
/eL(Q8vAYk4][.[         putchar(ch);
%T#O't.d:BL!Li         if(ch=='n'||ch=='N')
i{ Q3_ZS/T2Z             break;
a0Y7J Q/[^)jF z         else8U#O:OdT*S;[5X
            system("cls");
K\Y9w+mFCIi     }D]Kfv(W C-qJ0Oo3R
    return 0;j-W/Wl0{A1T{ OI
}[/i][/i][/i][/i][/i][/i]xu5zM[ `

l}(|*|7J7C [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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