捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.[!rW.~Qs)R-hL G4EI
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=*a ak)ewQ
/**************表达式计算器************/vke)L!K
#include <stdio.h>+\e3Nb}9Q
#include <stdlib.h>
9Vx]n wx!G #include <string.h>
'@e?BF;j o #include <conio.h>^0n,J `,@!E/y
#include <malloc.h>fEh qD6bu.y

F3XIh2@%I0g #define STACK_SIZE 100TGJ]mJv)m
#define APPEND_SIZE 10
/\wra@#cS
SYI h@1Q U struct SNode{
#M8i&rfGod     float data; /*存放操作数或者计算结果*/V)h+T"FtuFh
    char ch; /*存放运算符*/
W ?i U uATH };
hH/`\3]K+|
D2C!w2P:]0Rb struct Stack{
$qZ _LUI$M$d%o*Z     SNode *top;EO$AP_] O
    SNode *base;
]7_\vIah&t     int size;
J+C$y(A#r)h8c M_;d };
*k3ZMB:Z7I!s@?7Z@
zsz5]K7c n m /*栈操作函数*/*Re/^'L ^
int InitStack(Stack &S); /*创建栈*/
'p|/JU!^/K2o P Z BG int DestroyStack(Stack &S); /*销毁栈*/MN;n:Qd;F$J
int ClearStack(Stack &S); /*清空栈*/[7?\ik C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/)RK P,pea+d!w
int Push(Stack &S,SNode e); /*将结点e压入栈*/to]oz ni
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
ed|I~'~#[hIn a2WBg1^ g~]U5b-d
/*表达式计算器相关函数*/
P9XQ.eb aO7LN char get_precede(char s,char c); /*判断运算符s和c的优先级*/'}5`T'gIL#W
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
rT$H)_q1l float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/%bB,|+sLTtA
float compute(); /*表达式结算器主函数*/.}A{%upt7U,H{
char *killzero(float result); /*去掉结果后面的0*/ !e1muQ*Egn/L*L#}8{
I&|U)um wxs
int InitStack(Stack &S)
.F1K.S|%v zIE+I {
q o"B&c6`7~%I(omC     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));a;GM([#W\1Q0\
    if(S.base==NULL)
%A5n)Y9k(x1| a1a     {
tK)yX;_$E^         printf("动态分配内存失败!");(}#Kb,jQT*~G
        return -1;
7[%b_R4_H/e     }
"{5l go%{'ym     S.top=S.base;^0z`]}wk
    S.size=STACK_SIZE;"?-n.p?`0c{4Ir1z
    return 0;hEw,rCBJZL'|
}
@"e1^/BxL}U'k:F3u
4}/e7z'`}#` n/] U%b St int DestroyStack(Stack &S):b!L+p)A~q^'a`
{ku1_b0B)M3a5o.oe
    free(S.base);q@6c:\ d'A:|%x4j
    return 0;M%G(Fk;O^^%@
}
rDI;XU
+@2?U;TK9} int ClearStack(Stack &S)
Zy@#pen {U.o.J&L$["A Tct
    S.top=S.base;
P c:y:C)F%N     return 0;
A/C6O4jW!DKh1m:G+}r.I"~ }
2R7]b!Sq VT(C mN,@m5{3p*T G(M
int GetTop(Stack S,SNode &e)1w$@ c4B$F eK
{AS)K5r,Qga4U7I
    if(S.top==S.base)
*Q1RO/y.x8];I |Dy     {Y jz^} aD9l
        printf("栈以为空!"); P+^5t6o/h*|2ILv
        return -1;-d#Lr0K H ?
    }
Iuo5C*H!n"X&?!C     e=*(S.top-1);w i!LPw}@a
    return 0;
$Bjm| ` }
-R0F%Z!` x5U n
h"c^3KCC` int Push(Stack &S,SNode e)
e(p;E8w7|dR {
9cgm;CA Z'r     if(S.top-S.base>=S.size)
7V,yPnc&X#Q*X^Q     {)T-~\9hl3R
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));M \*a kQ"|(x2P2u5r
        if(S.base==NULL)vH-L*S_"C yo Z
        {&B'q V ncU
            printf("动态分配内存失败!");
5E!aB9Y5u3ROK)y$Z             return -1;
e/yn,@8n5i&s1u:C7cv\C         }^y[)DE`4x
        S.top=S.base+S.size;j/y5uF%UX
        S.size+=APPEND_SIZE;
$J3^,X o!gf LKN9m0r     }
r @QHN9R!Y_     *S.top=e;
'f2Xg6{4?6P]:Z ?     S.top++;
A*ty w IP-Lvi M1Q     return 0;
6Kk`D$XO'l.e }4xmv*h!zP
TC(Z'f/F(um+I\
int Pop(Stack &S,SNode &e)
8T7c!Z.}&f6@ {
u(A2D ^W^N     if(S.top==S.base)
x [E"D8C!Um     {
;u5P$Tz6]V         printf("栈为空!");q6K `-^0i1js'q!yo0B
        return -1;uT!o:[3Ct:g H
    }
(_{Aw C$Ag/w     e=*(S.top-1);.{&Z?8?lv\z$W-D%d
    S.top--;
w&\ c~]q I     return 0;
2YN#o4l HR }pR |p EJ w
E o wJ`^
char get_precede(char s,char c)0x5B&o/z^ p%r
{1b1O"Oq:K}q
    switch(s)
%c9WN4P8b0te     {@,R1^ v HYP
        case '+':                 @:aD-F ] l0v4yo
        case '-':
0\!hE3ey              if(c=='+'||c=='-'))VC$c-u o
                 return '>';
b$a3i*Fi3` h['d0Nt!b              else if(c=='*'||c=='/')
~;Z` qZ"XA9q'f i                  return '<';4SuG-z8e/iFf
             else if(c=='(')k%ZY z r\:r(?
                 return '<';
)M#Njp'Q              else if(c==')')
VH1hh M"J4^0C                  return '>';
1X&\5B _'r)@Nd              else
mR0yvW)DsK2f                  return '>';
U }!mZ9J2q         case '*':
'Sgm+Zf;MgM7N j         case '/':+Y Z l0W A6A f.R7X,M+]2\
             if(c=='+'||c=='-')#^w{*v?"U-Ib
                 return '>';3jP5\:j,Q-d
             else if(c=='*'||c=='/') |q#g]RT]
                 return '>';$G+d%["ji2O
             else if(c=='(')
)^H(x,PF w                  return '<';
G K2~Ju`3y C%li              else if(c==')')5Vv8B bD7Kr
                 return '>';
Dc [M ` TMu7y              else6b:O!A-M6F7s["I
                 return '>';)Rq\'a Y4F!]4Y
        case '(':
p$T,ysJ(l] ^              if(c=='+'||c=='-')
~-E-d f+e/w?                  return '<';2qD$t%I1RqY
             else if(c=='*'||c=='/')
a)wxC+I` @                  return '<';_M9O!~-N {6w
             else if(c=='(')
{'dV~0}J                  return '<';{ z6y.V't;C7x(aI,q
             else if(c==')')
,c$_Fx AG{                  return '=';
|~cl@.N              else4ro*jM4jqf^M i9|
                 return 'E';G!l h o?[ S0e
        case ')':W C*W9p\U5l/l
             if(c=='+'||c=='-')[q,k+d%J q| DP+n
                 return '>';m"?!J p.K&E
             else if(c=='*'||c=='/')
Lwa'wZ*ZPZS                  return '>';O?OL:z+|;R
             else if(c=='(')
Z$niv!OK;T6p1Y                  return 'E';L|!O/j~.y3OExUt
             else if(c==')'),f%s%V4c0M!g?7Hq
                 return '>';
t f!pGpNx W              else
;CWq4LPn i                  return '>';
^Bp{K4[e4\         case '#':
x,Y/tPP              if(c=='+'||c=='-');cE^%Qm+{j8u(X
                 return '<';
n TQ1qzo%j              else if(c=='*'||c=='/')
%a-f"O9Tc e-g.u                  return '<';
~WX`[zwq7}2n5{              else if(c=='(')-HjC(yq.w.Z
                 return '<';o2BjWce B,o@h
             else if(c==')')
A7|Sb[Mv'Q                  return 'E';
6Of8f}/lb@ ?C*?              else
%gt7EA5q`%fI                  return '=';%Q @,@g7@
        default:
.N d-U1z0H)F~q)Q              break;
.Kc0f_*mk1`     }
F+^G7])i6ZC     return 0;   
!f E(Vi u:_y } ` s$j]ue

S @Z*}E2W0k int isOpr(char c)
0R/I_!@xGdxef {
!T|A7}g8y E#P$F/n     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/x&?S&? `)K{4~J
        return 0;.?0?P&{h4|
    else
7[A:@k(}         return 1;
jD&@/Pi/{R)}+D }
)to&^X$JI }nA Q h}bF _,V0^h8n4RY
float operate(float x, char opr, float y)
D)pJYOe2S {q U5tC Arx
    float result;NHM2`E)] @*{
    switch (opr)
^@,ce&m6g     {VC8pAiE
        case '+':
8s:SUkI8i)N"v2Y2g              result = x + y;pp&fY1viF\,i
             break;Kv ZD-q
        case '-':
s'rA4OS2r.z{d.w5Y&c              result = x - y;$|#\1[ i+^&Z:C
             break;
t&Z-a8l(N7b tb         case '*':
,m|} J`6^d              result = x * y; \)z-C!S4o{:w8fjE
             break;Q^`9RLI3JNqX-\
        case '/': G bJLPKM5BoC
             if (y == 0)U }CwT#Ky:q
             {
EfWq,x+['Hc1J                 printf("Divided by zero!\n");5A"Tf+Qs^~O`
                return 0; PK1^w l @
             }
^ ]l0N"l              else
.mGJ)Hv t"[              {
]6YJQ"kwq                  result = x / y;)ex a?L
                 break;yhD X n#f+a,C1U"@
             }j7~}Gop*J
       default:
D \x+v c\'W              printf("Bad Input.\n");
ih\1n#s'n }              return 0;#Gp)U[ |%_&tBn
    }
u#|u1P ];x#c9{V#@/] {     return result;'\'X3H1V{V+K T#qhK
}   
g H)B&y%} i4Z Gnj9{;Aj
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9i6Z#VG GEZ|,q {
4}w%F't Y     Stack optr,opnd; ?S9ZL#Z*\ YOy
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/k5Z;bk.\|K1JX+_     char c;oo3}/v3e4Y5o
    char buf[16];
9f0{ a&h }Qu     int i=0; [8{%r@ k
    H)o2\Iw/g _3N,\2K
    InitStack(optr); /*用于寄存运算符*/
x}2Pi3U     InitStack(opnd); /*用于寄存操作数和计算结果*/
j.B%c \!t*TTfop     memset(buf,0,sizeof(buf));N^WL3dJ
    `I%Hw^$v [2k@k
    printf("Enter your expression:");}-eR'{ CV
        :lgx2Kiq
    opr_in.ch='#';
RnV/m Y     Push(optr,opr_in); /*'#'入栈*/z*U,k+txb+Kh"l
    GetTop(optr,opr_top); }/bR5IO*Ur0Q#q v
    c=getchar();0z |Q%c"_7w&v/C
    while(c!='='||opr_top.ch!='#')
A9Y7Qd4s3h1Q+g     {l%|&F!y)Z8w Y
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
9|`4C&Snpr'y         {
a$WP0v6re0g(^f.|9{             buf[i]=c;,}6U o.e"g
            i++;
x0aIr]eo.}l             c=getchar();
i#xp"YA9lx,DF         }
9G a9o-i'Pmc9mt         else /*是运算符*/
^? d3v{7[#Pz)VG-G7zB*F         {
h2O|:RR             buf[i]='\0';sH~/B!M[ M WZ|
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
XV2IvD@ AlC0^             {6N1ad2mJ;p~
                 opn_in.data=(float)atof(buf);
(^E4ir#`2YL                  Push(opnd,opn_in);$k'C,bM%JC
                 printf("opnd入栈:[%f]\n",opn_in.data);
!^;{UuK5C1z                  i=0;
z$HjsD B                  memset(buf,0,sizeof(buf));g`8NU!N3Q"W1H!c
            }&a3[O b^6U){Y-X
            opr_in.ch=c;
#ymfT-G7oH3}5y             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
|R!fa+z             {
e'W1_(S8kUhpej                 case '<': /*优先级小于栈顶结点,则运算符入栈*/l4xe1ih
                     Push(optr,opr_in);)@ R R*JO#Q_0S
                     printf("optr入栈:[%c]\n",opr_in.ch); p GNl _ DR&Mx
                     c=getchar();
)L%R/rp,sNVE |                      break;-{$FxNW
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
-{&B'u,Bg'S!U4i                      Pop(optr,e);+I]-P.[8X g3I#mXs(e
                     printf("optr出栈:去掉括号\n");
5o9v.lO3@2Yx(Ki                      c=getchar();
Jy*W-ET ly                      break;
O1jQQ"T1HP                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/7?x(m;s&t$X"Y^$V8W
                     Pop(optr,opr_t);
%G5R JPz"R2T*cr                      printf("optr出栈:[%c]\n",opr_t.ch);;{y:vj"W;y$]
                     if(Pop(opnd,b)<0)j2}0NU ?1ot0U
                     {
R%EYa C8{ ?;{Q@                          printf("Bad Input!\n");
!?S%k-{_PuV                          fflush(stdin);
A]k,g9XdAP6z                          return -1;%S-AWT.Q+w cuV}
                     }Ca7S@1ObU%S
                     printf("opnd出栈:[%f]\n",b.data);(`0o:m,G?A.{-Z['G'Cz
                     if(Pop(opnd,a)<0)5| MH*z8Rsuo[7k
                     {0t2HS@8u+Bd
                         printf("Bad Input!\n");v(h)Vk(j7C~W
                         fflush(stdin);&x8_ `rg YHos1Z
                         return -1;
!Ku _,yx6{%b                      }
M1t6W'V(i6P_ o)p+{                      printf("opnd出栈:[%f]\n",a.data);
i+c I~,t                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/yt1]Z#fAb!t
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/\y V O f&R
                     printf("结果入栈:[%f]\n",opn_tmp.data);
*f9`m$PlG                      break;
y!~E5Su             }y0UD3|9Sed{
        }
M h I&{#YIy8d         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ^d![} _h-E l {
    }
"Ar }Ii:d``     GetTop(opnd,opn_tmp);&v?GljZ2m;e
    DestroyStack(optr);7]#o1c+Pp-qFB
    DestroyStack(opnd);
OeftVxmB     return opn_tmp.data;+PQa ?y:B
}
3S} ^.XC7gv sTy.j \B kn/{
char *killzero(char *res,float result)
rNGT'j/| C c {\$l[.XM7S
    int i;9Zk1e } m*[p%DL9~3l
9CN UX;l h
    sprintf(res,"%f",result);z,j AA0QA0Z
    i=(int)strlen(res)-1;]!b#A.fTT1l
    while(i&&res[i]=='0')$U~+O-I)\-G7`u1m)d
    {
3W:x)w"WD:e:M         res[i]='\0';{9KUh"B/Q ^
        i--;
#pA_z'M'x\     }
8B0a!|0LG     if(res[i]=='.')
d^0C0U`         res[i]='\0';b)GHr5N._&b-N
    return res;
.o;R]#vDX }
LFk Xl\&q M Z MOsN.R \
int main()
gu~S"ay {
1}5I;V ]oA     char ch;
h7q2Xf.Wp!QC BX     char res[64];
5ix'KDHJ$n L     float result;pk0aVR1M2C+\Y0t
    while(1)
6r|/u9T3kN2fX(dW     {.K;AtC%[s
        result=compute();(n9k5i&|2\8Y3r.kJ
        printf("\nThe result is:%s\n",killzero(res,result));L+^5b:C(M1of-t
        printf("Do you want to continue(y/n)?:") ;'~Y9H @*r o0D
        ch=getch();A'dWG9^8|;?
        putchar(ch);
Uup*[&R3Z$T&]v7y         if(ch=='n'||ch=='N')bmaN^+S4x
            break;
&e wDH\zg{n"h(p         else
QUIe"su&vub }             system("cls");J6Le%V`
    }
g H8S1tS&y"Kra     return 0;
G%U3gx!q.` }[/i][/i][/i][/i][/i][/i]
}%nTd [
.]4E#@&f(R'`+Pq4\ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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