捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
vA+m5p l 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=]GU+{r0j
/**************表达式计算器************/
I+xq*T\!K #include <stdio.h>
2i*m{"zkG7K ?N #include <stdlib.h>nUn"I7]5L+x
#include <string.h>
a"| FTFD1EA(Q #include <conio.h>
%JWK(l9Rj0m-eZ #include <malloc.h>Pz6];D0Rb/Z3j_
B$bN;OW/rT
#define STACK_SIZE 100
0AP V6^l3M #define APPEND_SIZE 10
8hK1T o)\ R aL:^,OG"Xu zM
struct SNode{)Uq*fPv'S
    float data; /*存放操作数或者计算结果*/|f(F6}M8M
    char ch; /*存放运算符*/&jHV Ts.K!I"}
};
[[!kZ8~:x5F H8? &rX/HI.C&k
struct Stack{
NP \/w$I9pU     SNode *top;~V#}9DlW
    SNode *base;8vfM}0NY*i`lK
    int size;^)iZR3BrR/T1Cm
};u8a ?V3R#_Y

VuEF'B9A /*栈操作函数*//B7D+E5Jp$l
int InitStack(Stack &S); /*创建栈*/ N?*fR4e9t
int DestroyStack(Stack &S); /*销毁栈*/~P3~&U(n _Skd nJ
int ClearStack(Stack &S); /*清空栈*/7|,HHD[r
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
f`jf#r3T9J*N int Push(Stack &S,SNode e); /*将结点e压入栈*/1J!FWgP o#_q6?s
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/z,`,yGA6E.`*Y)Er$Z?
GQ#YY {,n{ N6Y
/*表达式计算器相关函数*/%Th#olp&ZJ/H
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
_ z?b8U4|.\ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
1k y0^P1POz?c float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/jc"p/O ~#@(Qg;fNf
float compute(); /*表达式结算器主函数*/)V@5vb}
char *killzero(float result); /*去掉结果后面的0*/ 6n9Y5L5Jm sE v%OJ

pb"t)T6l,Uu!r.S`W int InitStack(Stack &S)
7QwF0L^4b {
3k6d0_'o#k\V     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));&N.Q a:C?
    if(S.base==NULL)
%f rT(~sw     {
,?$k3F8^ j&|Y         printf("动态分配内存失败!");q4{/g [A S sMhB(d&H&z
        return -1;
+C#fK#x+Li h     }s'b V d0Xw;p j
    S.top=S.base;
9s$d(J$K.F5D{8? u"E     S.size=STACK_SIZE; i]w0G-U9M9]
    return 0;
\&hZ9j6q6F'?M }
m)K(f{0Iu
^ MCY`t(V int DestroyStack(Stack &S)
$t#V\4m3a"d y {9g7Y~)U4@Tt
    free(S.base);d0Va+K#@Z_oY
    return 0;%c0q H \\b\m
}
-uH&rDn
%[o!ajG;D5PZ T int ClearStack(Stack &S)%T7p"{4K5_}*bh0n
{
s:m2|g&M+Hn1B     S.top=S.base;/O oSNf2w f6b5o
    return 0;c t p#^ks
}
:[m2A#ny
R-U7|xbYl!t uB$a int GetTop(Stack S,SNode &e)
ZwAN]tgB8Qk {"W"}T)h o
    if(S.top==S.base)Z0g\1\:~/K Nt
    {
~ _ ?tEG&~uh.C         printf("栈以为空!");
#ySutc         return -1;
*WKW%Q9_}| U]     }7FY!KtOeQM
    e=*(S.top-1);I_2bchYE
    return 0;
{]m0Q2G6b8{)JJ ydr }B0P4a-p8j]
?ZFKL@|
int Push(Stack &S,SNode e)
1nB1}3Bf@^!Qs {
h1jO-J,b w     if(S.top-S.base>=S.size)
PS5{LAzr O     {jV$n Q_H)^gF
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
iagCMq SL         if(S.base==NULL)
bQ8Ro@U&{"l         {cuR xg
            printf("动态分配内存失败!");
cltn/L H#t             return -1;
`XD z,a+@+Q         }
/T0Y0D5nH         S.top=S.base+S.size;
?-X J?uA;S'Z$mJ2^         S.size+=APPEND_SIZE;2h;`%H)H:?j^(DKpLO
    }
"w Po U0}&C     *S.top=e;&?MUA7[a
    S.top++;p%l:q e2e3XL6j"M
    return 0;8M6V/tI$lU0]/e
}wX;kM,Q:i1O9A

g8c$s ^/i int Pop(Stack &S,SNode &e)
5a&NRV#C%F {EOVJ#bz7\
    if(S.top==S.base)b t4W/s"m*[)z,d7q&[
    {)L2N*VF w
        printf("栈为空!");
,Jy&U^z,o?B         return -1;
#gA7rg$jO+E$h     }
J-Qe SW#T~     e=*(S.top-1);,d h l;I2ST5c
    S.top--;
ON@8Zlf{h:@'Mi     return 0;2CaDa1w1u*D
}_Uwv*u+\!c Q
"Mg l U\F P
char get_precede(char s,char c) lJX T9^1qZ ~9~
{-jae%cb
    switch(s)
w[t^'y[     {
5o;AX3H @ c         case '+':                 
;|j1f nQ+K'U         case '-':
H/X.Nb,J)H              if(c=='+'||c=='-')1N \ M$fJ#sZw
                 return '>';
*Q_L'C yJ-e G              else if(c=='*'||c=='/')EvmLR,FVJ)t
                 return '<';
d-{2m r$PG8GG              else if(c=='(')&^#y;c!Gzw
                 return '<'; om[|zj
             else if(c==')')
{*V F1P6g                  return '>';)V"X5b/XpnlLcx
             else 7oyG5P6hK7R^o
                 return '>';FKG/P6j%K fi
        case '*':
v C#f[G4p         case '/':
xHa4RP?g8H`t              if(c=='+'||c=='-')
7~s;tY Dy                  return '>'; e3O#I | W'J
             else if(c=='*'||c=='/')$a Th7RGx
                 return '>';
TgU%e:We.Ug[T+i              else if(c=='(')
s!M f:jY6p4P&r                  return '<';
U n-a%H fus}b-A              else if(c==')')
'u,IL@"j$N's-D                  return '>';
mf,S(rV)I;qo6Or              else
({0M([$ew*s*@0Q                  return '>';)dm|.z%JO3z
        case '(':(UT{8Hp Ng.j
             if(c=='+'||c=='-')
;R C0B,R+^ Y5m^jqo |                  return '<';
c(QT_Q              else if(c=='*'||c=='/')
*u8k!@ wno                  return '<';
%uY![Xc|              else if(c=='(')#URzWL7p'k(ph
                 return '<';
7wIM#i R"B-kq1l              else if(c==')')kicw/Q
                 return '=';:K+t \uL6h O
             else+b"ON2F(|Elocn
                 return 'E';
6`Sk"aJ)?         case ')':;h5Xh1X6TO
             if(c=='+'||c=='-')
I/N#Lrg3OlV,?                  return '>';8_Z"u&_A9GG0c\_W-v
             else if(c=='*'||c=='/')
uy%\3\'w5f-je2^%\                  return '>';
eV5lmT9N              else if(c=='(')
(qy#E5KzV                  return 'E';wY.}!@$Fu4wsP
             else if(c==')')4g|.T Bq lQ]
                 return '>';4lo}Bs8y)D
             else
,\mBv;?'J/R8P Z                  return '>';
^X&o5?Fu y,@         case '#':2x/j%V K M2_
             if(c=='+'||c=='-') Ajy+r3Q"a_,z
                 return '<';
xKNM3o i _I              else if(c=='*'||c=='/')
u,s+IsBD-U                  return '<';
SU!Ar@n![9J.ps              else if(c=='(')
)DB%X.I*Y)C                  return '<';ShtG+{:q I
             else if(c==')')
*P:p k+|)y&j8} D`                  return 'E';
nO7@\+r/f$d,f              else!Qo'SV0kzGEw#CY"z)S
                 return '=';
/K/X7wox+uq\         default:8BT"[.YB QB8O
             break;
(h(p!Kw A j|     }o/z_Vu f d|
    return 0;    1H`;aE-V3a`
} m4UbB.E)I3pp4Y/S"G J

foX.N rXRR int isOpr(char c)
#R7PM$|W {T{M(fP
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')y"r#mY,q%X,c A&t
        return 0;,\n9?1a[&O0[]
    else
0|O$U4a1~         return 1;)X\nsq
}
5AdUoQ8d#A)O Y7xwV \4VJ K R
float operate(float x, char opr, float y)@;F:R }jU9~#q_X
{5s2\ pXD(o
    float result;J!E^!r(?M
    switch (opr)
P X/U:Fv?     {
w.Gryw8]         case '+': 1uc2x)t.A.A` Z
             result = x + y;e&_,@7U)b.s/C6o
             break;
)[4a~&y`7t         case '-':
:jfq5ZG9M/P)w              result = x - y;
F1qdX"n&`,|i              break;
"n {0^0r5rh         case '*': 6a5Y+g,A?L^&BY:w
             result = x * y;8A8k)Qp)] x-FoA
             break;
*`f_5^Iv0a.Z         case '/': _'A^ K\_a$Dy
             if (y == 0) QQ7p\$l)X^
             {
"N'i1|M$A8QQn                 printf("Divided by zero!\n");
:lTO2Ir*n`A t                 return 0;
Q&[7S9R] ^d              }
iC.r6a!k6Ch1nhW              else(A8@-kCho.d9yC
             {-Cc$_M*Z{'~$Z3O-V
                 result = x / y;
w {&e(M ZL                  break;t q:^Z-u"M`
             } xmL E8A9rOh
       default: !oF ln)|"I'y3JH8v[
             printf("Bad Input.\n");
e S}w*n              return 0;
9fXZ4q6dS     } X!YZVj5]Q A/G2O
    return result;
w(Kr^ m7h7A"N }    _p|f6B9^:q%]L

;lO PT5Z6b;YZ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
j r6Grv0aG'x { ~2P.uiC
    Stack optr,opnd;
6Wo `)N9r O     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0C*lH-giI;B     char c;
7Q7^ Mj/N!Ju]Imc     char buf[16];
:DAyR I \Zi     int i=0;
-c}n7WBcX+eq_@     }1sR1?.t"bnyG
    InitStack(optr); /*用于寄存运算符*/
.|0@ca0UDWt"B     InitStack(opnd); /*用于寄存操作数和计算结果*/
9q%i3f7`o-z-L     memset(buf,0,sizeof(buf));,exc Xu-G%JU
    V2qxx [1KZ@"w
    printf("Enter your expression:");4eS!cb az
        V2B6?1e{~@/g
    opr_in.ch='#';
7YL0f|+d2Eg     Push(optr,opr_in); /*'#'入栈*/
%~j&py7Vn1zaf`     GetTop(optr,opr_top);
gB{8^| dKF$w5M#|L     c=getchar();)K4xPq0~
    while(c!='='||opr_top.ch!='#')
od.{A+t%q     {!G5RjUs9g#A5O
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ S6O:?[&j x0Q
        {
|B)jaB.[+a[             buf[i]=c;} Aw:P6kRP#`x}
            i++;+tj5}W:g
            c=getchar();},BS\g1{)}:N
        }b5j!h.\ B}Gf:w
        else /*是运算符*/
XT7k%|"F7p2^b         {!B4uLN5b*rD
            buf[i]='\0';
6p],wH&j s%|Y(xD             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
0o W!S\5gg*@3cE:qTg             {9c,fJ~a@Jf*Ok
                 opn_in.data=(float)atof(buf);
/X*T7@8u;rM8H                  Push(opnd,opn_in);
Kmu].Q.I9rM KV,]                  printf("opnd入栈:[%f]\n",opn_in.data);
L"diz J(Y d?Q}p                  i=0;~A'l I,n.y~
                 memset(buf,0,sizeof(buf));
hG'`7@a5Ij             }(O1R`iD"y
            opr_in.ch=c;}E4?*`x.?Gi
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/(Y*]u@0?xo%U9q
            {
xD5AJg1p*S                 case '<': /*优先级小于栈顶结点,则运算符入栈*/)VF0v7H8Tz
                     Push(optr,opr_in);
UnFr2@.`                      printf("optr入栈:[%c]\n",opr_in.ch);MHWO.t n%gU
                     c=getchar();Kp"wr&x*i0gc
                     break;
\:?_$M%}uu\8x V"v                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ qZl2\ ]
                     Pop(optr,e);XnlZh
                     printf("optr出栈:去掉括号\n");
6|{HT8L0l;^e5Pq[}                      c=getchar();
5Ln)C7u&iX%h,a1?m X                      break;V BZ s7j N
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8CYC(D"Z]9CB!s
                     Pop(optr,opr_t);
]y-_\$Z,Otg                      printf("optr出栈:[%c]\n",opr_t.ch);
'CoU0UR)b R                      if(Pop(opnd,b)<0)X9d%J$AnA
                     {&ei+L&dz_r
                         printf("Bad Input!\n");
,{ P#{,f'NK F                          fflush(stdin);
lO+^"vh.\3w                          return -1;
8aUL4tI*Df                      }
-K3Q x(nxn~?h%Dx                      printf("opnd出栈:[%f]\n",b.data); O3s _R!P
                     if(Pop(opnd,a)<0)3h3S-JJ(JS `P)gJ
                     {7xNl[TZ#W
                         printf("Bad Input!\n");"UwUWB5?-rR3O
                         fflush(stdin);le0i mDfo
                         return -1;
%y G.H:MS!X3_N,Q                      }p!d|(y!`,yOf%?
                     printf("opnd出栈:[%f]\n",a.data);
"UIE8}IM!| ]so                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/P)B et/E&nW8@
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/dxxg@k
                     printf("结果入栈:[%f]\n",opn_tmp.data);
Sufg0l                      break;
t;z;U1t^.S             }
"\ | ? FhpD         }
dM5T9n Q0]d         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                bKS2whtA Z/@sH
    } hpOe*a XOH B
    GetTop(opnd,opn_tmp);
2f&a R&g6Xb     DestroyStack(optr);
N8e&S$G w t)@-P     DestroyStack(opnd);
W%AtmNcR,@     return opn_tmp.data;
Q\"slD } D3^TBS4T;B'uH2t

@dY Oy}a char *killzero(char *res,float result)1AXDI AJTX
{
_G0[ `4bY/OP8t     int i;
o ?Y I@q S
:k(Y.[&YaY3H1{1TS     sprintf(res,"%f",result);&^.s8Qtm,Edu
    i=(int)strlen(res)-1;
3fH _?;CF}X]H1`     while(i&&res[i]=='0'):J-CxZG)m['@E5j!g*N
    {
(hdp*y)e"\-f7j9r G9U         res[i]='\0';
{#p%V0y5]$uPk         i--;E1B2GiJ`
    }0| ^L!Umbt d
    if(res[i]=='.')
$l;rqf$?{5G3FE         res[i]='\0';8G.E)AlOGb
    return res;R;@g eje3h/~ M-_
}
eS mq l*aO`
fEC9V_P#h int main()
5Nh:g-ML6RM {
.|}%Rh \r5h.q     char ch;
xe%U6l o5H2N     char res[64];xi b$qJ3^c
    float result;
%S*k!t4e:@L0w     while(1)#pd.~L(BMS't
    {
*}*J$l*v*?&{P;P         result=compute();
cW[ y3AWEge         printf("\nThe result is:%s\n",killzero(res,result));T)IV4\c0`YOf
        printf("Do you want to continue(y/n)?:") ;5QA'Y#Hi{!s
        ch=getch();?qd~%s-Qj%F:Kv
        putchar(ch);
8xHcU H8X x-@pG7p         if(ch=='n'||ch=='N')
suDxv:Zy xC E             break;
Q^ L HC         else
N e9G-T b4{n ~:q             system("cls");
"PSLf)CX     }
'T do\^$ztl[7RM     return 0;6`"VX/Y;I/Z:bh(`
}[/i][/i][/i][/i][/i][/i] x,?GF;u1Q,@$pb

x+}[f[#EN#~ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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