捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8nZ2\:E/N)`#fkc 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
2S2hk+w-R(h ?0VL[ /**************表达式计算器************/0Q7\"s5k#J
#include <stdio.h>2k2y+o4Wv1V,@
#include <stdlib.h>HLIZ8C
#include <string.h>4I `q5q E mw
#include <conio.h>6] eP:GN#daaA6s
#include <malloc.h>"o1ZlL l5Tm'Qy

5?4f,Q }4W%hB'KT #define STACK_SIZE 100
F@;K}\l)o a'D7B^` #define APPEND_SIZE 10r+Pt M5T3cf z`
V pKo2u8R0tN(O
struct SNode{
N:Ri"i0T9n1}Os     float data; /*存放操作数或者计算结果*/
"ST F2M&k9c!P$k)v     char ch; /*存放运算符*/Q6z&C S-BB5~vZ
};"a-W2lb3E|G:M
BW ho/n{!Y+Uz
struct Stack{
+IQsC8b qt     SNode *top;"n(aY9oOD }B
    SNode *base;|9y]hH5Z1['c5qa&X
    int size;
:sO2BI S };
!o8x@ AU-j4_)qK;d
x,c,I2r!~K+C /*栈操作函数*/|k[%]F^S.fn
int InitStack(Stack &S); /*创建栈*/
5?5U |ZZ!wI NY int DestroyStack(Stack &S); /*销毁栈*/
qkb`+qm A int ClearStack(Stack &S); /*清空栈*/
ES5^ J$V8E.l$N int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
;C Y8`D*\F3V int Push(Stack &S,SNode e); /*将结点e压入栈*/
J ~{b9RO8^;OW:Dj int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/s"L"e+X`G,L%s({_
/n)y K;[J*j*Ro fJ
/*表达式计算器相关函数*/EV;Vr:_,`;U9?
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
}p#w!Ky.n int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0^R/Q7qM Xg#U\A3~ ]
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/)T0^x{#dZ;da
float compute(); /*表达式结算器主函数*/}pnTn iV
char *killzero(float result); /*去掉结果后面的0*/ (F5~7X3x~Fl-M u8b

2D.A3B4? B"a4w[){v `0` int InitStack(Stack &S)9Y"X8}BZ0Y&p6oy
{K!T9e'V~l.}G
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
^[!G{r;}'j,q     if(S.base==NULL)
w%Npq2Z{     {
"} QJ}B.X9`         printf("动态分配内存失败!");N^9xY X@
        return -1;/NnY|.l
    }
#hT5P(M}+o     S.top=S.base; ^[3p!Ph L
    S.size=STACK_SIZE; h,G-ne DGMm1Og'G
    return 0;
)hXI'B6fg,af }!Z:js%T'h9?R
Af'}b"? F8N
int DestroyStack(Stack &S)
sgI-d&|(Q b&V {
,F.pn)O0t DA'v     free(S.base);
*?bOop;uW^%Y     return 0; ^j!W4Eh
}
%z7D K;A}0z} M} Cz&[+P8^5k
int ClearStack(Stack &S)\+k3xmY*u @
{.|!Z-e;{ rl}
    S.top=S.base;
3v E4E9Y3?3b$r:@     return 0;'uJf;K+I c'xh
}uO Vl`4o`*j

HX&LQe A E-?$G{(]j int GetTop(Stack S,SNode &e).bOTC&e&@J\
{P.m:Sa,O*F`3a`
    if(S.top==S.base)
p4ErP:cc#no_     {,`R-NV`/fz
        printf("栈以为空!");u{I!WKL\Zy
        return -1;{]1RG V;ChJ.v
    }
mo%Q2\ e     e=*(S.top-1);
*c-Lg5T{)?-X'W     return 0;
&i]n}i!s }dJA.zRR
K'M)lX1s|Z?
int Push(Stack &S,SNode e)
un3|E*[ Kj{](W k { K;P+U~C ]1r2|4d]+r
    if(S.top-S.base>=S.size):^TZ&a5G0l m.\3Y$C
    {+r}#~ nc:uQ
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));,Z#`W4jF:C-K|
        if(S.base==NULL).\g4Ls1zBN8O
        {3_1tU@ l,C$@(e~
            printf("动态分配内存失败!");
:_$Y1~i0tCm             return -1;3\-q_F-SImY,U
        }}P!A B2x
        S.top=S.base+S.size; `M3T1E3Rb@
        S.size+=APPEND_SIZE;
5|G;w"G.XkK     }y8CW6pmtS0@a;U{
    *S.top=e;w:mj^9L{'c'\
    S.top++;*oP1d.} ^:R UL|
    return 0;._qkg r5h9B G6u
}
2B]e`R)n
? tRH3CC;k\0~ int Pop(Stack &S,SNode &e)\X0X*o{"v_
{vMZ|.\)B
    if(S.top==S.base)
"Ef6E"S\     {$w.j:U/H:\~
        printf("栈为空!");
FNy o1IF!W0UA         return -1;$|:y(LAB9x.d#D
    }
r7V Tt6O4n,N     e=*(S.top-1);t~ aOdi6}.r
    S.top--;
8A&{9QN7\s|!z9H     return 0;
w:EG5hgr }
:~G/uSw:N 'N1m k5[!J|| I
char get_precede(char s,char c)$w5bO:H;}FwG
{,L%Y:n$k3[^X.Xkh
    switch(s)'[U,G"}C u
    {
:eiBNic.o)D]C         case '+':                  JZ&o(]ob*S
        case '-': D8xF s9` Y({j
             if(c=='+'||c=='-')H)v*k YN
                 return '>';
qAFle!MLf              else if(c=='*'||c=='/')
wsXTfl                  return '<';\w"ya r#Lav8H
             else if(c=='(')
tkjv$CL"?uR J+?                  return '<';6Xls Lu+A
             else if(c==')')
a+k#R$_/@F b                  return '>';6]iQjs9|
             else
t-p(yFx(Ik                  return '>';,Ur],tTS8i7q'h$w
        case '*':
$q `rch t iGy         case '/':r-LR O-MF4?0S \
             if(c=='+'||c=='-');H)? ]!A#[!m4Qm
                 return '>';C$JL#\wX!j
             else if(c=='*'||c=='/')n }-VS3k o8e%o)q
                 return '>';
wG m sVNy!S              else if(c=='(')
3AWvCn V%|o ~                  return '<';
4k.W4qF0S9uM.Z              else if(c==')')[Up"| rh
                 return '>';!o6wV\{fk
             else qj"d-T-c U4z,m
                 return '>';
Oo$_ uyj K         case '(':
Ln:_1x f8U              if(c=='+'||c=='-')M vL W~X&WW&_KF
                 return '<'; ~'Zl$f? tLS ]
             else if(c=='*'||c=='/')
N(_ n"n)haG                  return '<';
4WK#^b,[HH              else if(c=='(')
FzO'O9jR7]"aw6A                  return '<';
|T5CT8nO2W3}#Au              else if(c==')')%W\2fe)F0O&c?
                 return '=';
(v pFVA7}              else;\?9M)i~?}m SK
                 return 'E';'`[ v1y7Bi%E
        case ')':%gd@f+E:U1jZ
             if(c=='+'||c=='-')
Bm)BCc                  return '>';
B!Q3m'Ri v7j6X*]              else if(c=='*'||c=='/')-[%dA1M6|i0irTb
                 return '>'; JGql b~Kf
             else if(c=='(')
j`fyhr)|8F$z                  return 'E';
^)`1o A#gX*Yy              else if(c==')')
8l;{3O-_(q/E(J L                  return '>';
i~9O Q0C B?              else
+a |/]nt(B                  return '>';*WR9A{*_fG { TS
        case '#':
5w)])Xk'z6Y              if(c=='+'||c=='-')9[[3V1I b9[_
                 return '<';1F? Y3p~6v#S
             else if(c=='*'||c=='/')
m X/[Ct                  return '<';[J6jj xWC[
             else if(c=='(')d9Mp.ru S ? e,w(``
                 return '<';:~\.GW6?&r tM
             else if(c==')')'pd:nSLV-}
                 return 'E';
/ubY9Qy#lz              else
v,m.P~ A`4l5F                  return '=';FT SOJm~H
        default:
S1} m O6m+OA(A              break;o7k+xB7k)t_
    }5X3[:QenqF$v
    return 0;   
j6p*DG:Gl }*l:q W4V)cr!{ f(U

,[(^ x#AM;R*rl int isOpr(char c)UAzAB)T$lw
{
S;jdL;^YRq,Q*r     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1lD1a+W^ \Y         return 0;
q9_bZ2}3yt!Fdf n5A     else ?1V x V(`l(s
        return 1;x0}6E*?9](n
}
5X:`rFQjDF"B2_f b
.|,qxB:T`'h:L float operate(float x, char opr, float y)
,Z+Yk2f*YrRmR2u {2nC:xVZ}@~1_3c
    float result;
/L taOI"sP     switch (opr)
3ok _F2pZL     {
F9w:L#U1}wK         case '+': ;F,n*l,YH:I
             result = x + y;
G*i"q5P%S T9fW              break;
\%yT1E5A.a!k         case '-':
hw(x:nS9t B!k              result = x - y;
U6a8l#dT j~              break;
w'EO6rajvx G?         case '*': DQ)U$Gv'ga9iaN
             result = x * y;
s.\F.U7bP3uI              break;
i&C k~2e3Sbm"_#o         case '/': `f{(RLs
             if (y == 0)mm+q ZE&fM#X$yW
             {
m.iu)xV                 printf("Divided by zero!\n");
i V3C7CC%`                 return 0;
c[({'~e%V\-L              }&y['TJr2H
             elseVJD4``+P&H;w
             {e4X#k%Vq(\E&mM
                 result = x / y;!d%mFvA
                 break;
0sF6T,l#WS&@@8t%cj              }
RDs ?q8{        default: b+fY:p5vE"Q
             printf("Bad Input.\n"); U? }~]o
             return 0;
gf#N0b7I#n3_     }
sFQ0W1i7xxvh     return result; nrJ/\E }}i&L
}   
3Oqlr!P9IT ?F h ~.aPEuO
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/r3WG+A0{$r
{A$Y$e_r k
    Stack optr,opnd; g*Hr d~]K4g
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
3Sn&f%q.m?(s     char c;8D"[&Kh{0Z"y
    char buf[16];
9^N |V8O9A7Hg|     int i=0;)},aY Q [M@Z-g
   
/QT9f _YV%xR~%B2a1G1h     InitStack(optr); /*用于寄存运算符*/
0h"Q&T;YT     InitStack(opnd); /*用于寄存操作数和计算结果*/"y N-z8FD/gb
    memset(buf,0,sizeof(buf));9@"Iwdx#zu ]
   
-g|Z S Z:E h/}Q     printf("Enter your expression:");D'H3@f~,K+i-]
        ~v nsJ:y3yT
    opr_in.ch='#';
2I@t"daD     Push(optr,opr_in); /*'#'入栈*/#A&UX#t4}y
    GetTop(optr,opr_top);
n8lA2t%_5j4X.|     c=getchar();;S}WX4xEio!u
    while(c!='='||opr_top.ch!='#') q*LMAy-UX
    {
7z1oJatU3UW         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/PI]] e'm m(V z#N
        {2t}]SAE3k2w
            buf[i]=c;
Xu'\~3p             i++;
2_ AJT'OLX             c=getchar();
_:|3v!k}7^         }DDd7oq
        else /*是运算符*/
je ^y1uL         {LqaxEz:c4i4_
            buf[i]='\0';
/R(?DT{aW             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/o4}2r:w!^N~
            {R9C"u(`o+J
                 opn_in.data=(float)atof(buf);
[!h!rEt U                  Push(opnd,opn_in);k6g@Yv!M `+f A6j8?
                 printf("opnd入栈:[%f]\n",opn_in.data);
%qt[3x}+^h                  i=0; O~l dAsB!bGF a
                 memset(buf,0,sizeof(buf));s$f:r,|&I5vs
            }
:_-?.O$K|1j k1n             opr_in.ch=c;
C"sg m#K P,a             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9Z4A6zbY gD i
            {
p*qs Sb W#Y                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
AD*`gK-eC$e                      Push(optr,opr_in);
q&dl;mN*t x                      printf("optr入栈:[%c]\n",opr_in.ch);
cD ]Q^4NG"p                      c=getchar();ng+D D$O
                     break;q w&Z/x'{mM
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
V#P'xk_o3KsWUo                      Pop(optr,e);
4My0s)VT!J,KW                      printf("optr出栈:去掉括号\n");AJ7_$w9A)l"u
                     c=getchar();(c1z/o$n/[
                     break;
0B;K9S YXg$n}~                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
}0Ba,V.u@+^                      Pop(optr,opr_t);r$XJ$F0t,unn@
                     printf("optr出栈:[%c]\n",opr_t.ch);R VDS0`LDz,h
                     if(Pop(opnd,b)<0)Bh_ N)Q
                     {
hf*\/c5y+A"j/n!W9\I                          printf("Bad Input!\n");8XssjgN%FWV
                         fflush(stdin);
!w2BM0o*t_;e;K(Y5Z;R                          return -1;)HT Zj8k"cxr
                     }(Wm m.Wa
                     printf("opnd出栈:[%f]\n",b.data);
&wr3i-md                      if(Pop(opnd,a)<0)
nQ8kNO:g&lS                      {
~\r.KJ [                          printf("Bad Input!\n");?4EF.pS Vw I
                         fflush(stdin);4O+|)^C,v'N B
                         return -1;
)o*j:fT-Ad                      }~ |(z C Lr KZ1z C#\s
                     printf("opnd出栈:[%f]\n",a.data);
*w3im7x)ffx"l                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7@Hfa&k9{"Mz                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
Ht!EVwiX                      printf("结果入栈:[%f]\n",opn_tmp.data);
Xx9TL PjU                      break;
)[Ifd-q             }{"@rjLh @ {
        }C+r\ ow4]
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
&[ ZE o7[7Le b/Q;V     }
9WIm9D-N boSq     GetTop(opnd,opn_tmp);
4~$mAT&w Qs s~     DestroyStack(optr);%A8F ]$G+c3k+x[
    DestroyStack(opnd);
+`lyd5U TR     return opn_tmp.data;/G1TN}l%g
}
Z\b6}!T?aq;D|
'r7Cq|g_3[ char *killzero(char *res,float result)4p^&Z![hI mZG;E3N
{
3m]gM?j     int i;*C1E8W!wV,Wn7NLk;k
Sa.S QV
    sprintf(res,"%f",result);
(Gu Etv-X:?     i=(int)strlen(res)-1;
Y HK7C%D*B     while(i&&res[i]=='0')
(G}(eAv&`0J\8J     {
Q4eE0v v"oV         res[i]='\0';n2S{'|P
        i--;!n ZS zI H;kLq
    }
g-R;_6d&]5\     if(res[i]=='.')
rd6^4k+r kj         res[i]='\0';At6iz-Yp
    return res;W urQq&crl#`?
}(y:e p)_l:A"a!Q
y(V B)e%^$} i(|1{+g
int main()
2P~.DU | {w P4?(ZZ[9p2K l3K
    char ch;_ Rj0F{-kG
    char res[64];
;[J8PI S6B^d2y-J     float result;Zbs0ol#]AM E}
    while(1)3J-{!d;DE
    {.H5p"l{-] U
        result=compute();'S.J6O${(q
        printf("\nThe result is:%s\n",killzero(res,result));u&\p @$hZ*Y
        printf("Do you want to continue(y/n)?:") ;Tl_H3^n v$f/e
        ch=getch();|;mfK1Q
        putchar(ch);*E5h/^#n#t x5O7\:^
        if(ch=='n'||ch=='N')4N#L(z$j/oZ
            break;&i$j3B q/[2s
        else
'H]4~a4x#m@             system("cls");
3kU6Xb u8N{O     }F0G'{6E6z|qv6T-VS
    return 0;No)]/yP
}[/i][/i][/i][/i][/i][/i]
~;U-Z fXi3j8^
)p}F"OxCP [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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