捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
'Tz^y5D6m8m 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5w x7{E CPh s4B"G
/**************表达式计算器************/[/K4A:F_ P
#include <stdio.h>8Ek7J K8b q"U*?
#include <stdlib.h>
;]VD@P{OLO \ #include <string.h>]#s AlP~
#include <conio.h>0F%jqk#EseK L
#include <malloc.h>
loP0It fiK
c!`;\ @ N GQFW #define STACK_SIZE 100
/T0W"n:@d_ #define APPEND_SIZE 10;@6}$M ~6J|
.mz:cpN#d
struct SNode{
:[fMn%H#w8nB     float data; /*存放操作数或者计算结果*/-A'a6A8w3`h^
    char ch; /*存放运算符*/ ?oQ+G;d0J"x?/F(]
};1d0l"~Ui

Fe-n"_.y.@;DN struct Stack{
(J+s[w d$g     SNode *top;&c W c'Q e'X.x(d
    SNode *base; dMmKd
    int size;
:f9l3Yn*f C~B };
m0i6^C:wT(F0e a{n @IIe@
/*栈操作函数*/
BmSFo+K9Ee-^ int InitStack(Stack &S); /*创建栈*/
;Om;{;F[~D"c int DestroyStack(Stack &S); /*销毁栈*/
"`0V&Nb:|]MA0F int ClearStack(Stack &S); /*清空栈*/
W"Q0g [ct ~:b int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/-C#V&xy]QDV
int Push(Stack &S,SNode e); /*将结点e压入栈*/s u?hR,u%W
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
a%QHw Z*z/Q 6P3{D9TA*J
/*表达式计算器相关函数*/RCLk S.Z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
7k(d L5PHa(T(J8_@'W int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
iB@9\!D float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4ES)FI"Xvsw)x float compute(); /*表达式结算器主函数*/
:v(D;ZQG'f:xk z char *killzero(float result); /*去掉结果后面的0*/ }$^|]c0g~p;~

dq9t#i} `k m int InitStack(Stack &S)[KJw0OUQR
{
K%Y.F.uaw     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
O P?g6s.^(j gN'n7V5Z     if(S.base==NULL)
%vdC!K"^"z/pN&wFo     {
}U#T*AS~         printf("动态分配内存失败!");F!ObGKV$y+E
        return -1;2N QhX$}(_;[{
    }WZ9qqQr
    S.top=S.base;
y-[C'L%AOu     S.size=STACK_SIZE;
d];CF:?Y7o x1MZ     return 0;
T2N&V I'b ^ }
7B;E:I;`vC;Y /P|#S$jE&]-g(v Z
int DestroyStack(Stack &S)+Dv+[ wa U-R
{
zW+}i^*Y T!h     free(S.base);
0id3G7b?V     return 0;
8~Q*l/c*V'x }
LL4N'z/l#?!y4S co
q8P~)o)PaZjP3P int ClearStack(Stack &S)
K4] gU(`4p,W&q$@a {
(Mc `A)_*kR a     S.top=S.base;
1_6ljDq     return 0;
F)f Mcy"Q"L5B }
Cy)e$RI;c F)EsS2NZ`5^$s
int GetTop(Stack S,SNode &e)
j.}Lb6e*]{Vwp {
}#o/? a}+A/?q$H4`     if(S.top==S.base)
CLOQ,E4j&q+~.[     {
;U3A R1|1`T7?'Axko         printf("栈以为空!");
eZ"]+|$q"j)Z7P         return -1;R(A0\p9Y'y
    } zv~,L cDW*o
    e=*(S.top-1);4l|;A!O/}X6G
    return 0;%g(jE)ey
}
.tG Ao-?Km O`
'r6@9j8r7P0u*l int Push(Stack &S,SNode e)w!T*G8RG
{
)yH4`iL^Q     if(S.top-S.base>=S.size)$z \^R Wb(n,B
    {yH ~K h_ g?F d
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+m Q:pb1MG9~#b         if(S.base==NULL)
O1R&_;t8n0d         {^5PP{ cw
            printf("动态分配内存失败!");]+ca-JyXa5r p(r
            return -1;
? ys(_U         }
"k C~4j [!E-L ig?         S.top=S.base+S.size;fFOF-} Nz7^:l
        S.size+=APPEND_SIZE;@){QP0U']7H&i
    }
+dd;_X"SE o'n     *S.top=e;
Ht F-U Gi     S.top++;
](v3?8j&J1Y}.q;G     return 0;
0s)w$H [;w Q }
`7A,I;Ok(t ;{U`W)B&[/z
int Pop(Stack &S,SNode &e)
PN%rh p3is {
*S.h*XsjCh     if(S.top==S.base)/{c`-^7mVs
    {M3h OeUP
        printf("栈为空!");
?)Z.RVK Q*I         return -1;7PU ^ Bv1kG8]
    }
X5pE#j0mV[     e=*(S.top-1);
~ x&V^~w     S.top--;o w)G6t z];xj&G%L
    return 0;,B0I.G#nK0{yVT%})P
}
y$V|w%\
@`L'b'mK char get_precede(char s,char c)
)X/u"z;c&]5IK {
.l US?P y8Xg     switch(s)D5H,b|4Mk Ig
    {8YKET0qh%i {W
        case '+':                 
hD3M'e(I1m#KH         case '-':,\/S P0[r:g,?
             if(c=='+'||c=='-')6U-`+gK3w{/j
                 return '>';(`J"FG'QP:P
             else if(c=='*'||c=='/')0Jtq4E$^*[]%Y8Z i#O
                 return '<';'V7Vh L3fIY
             else if(c=='(')
M7C&qw [*M/U                  return '<';
'f_$k*s&W3W(P@K              else if(c==')')T:cY uI#[ Bk |
                 return '>';
y|e0B y'K              else
Q2aI}+wM"[ t                  return '>';:DH'B&H4T:G(W x
        case '*':-JEz-weUr:btq
        case '/':
)e)qaA;h3[\ G6X              if(c=='+'||c=='-') YZ&vyd%g5H a
                 return '>';
o_,v5nvmZS-iG              else if(c=='*'||c=='/')
Y+G'aZ so                  return '>';
3w[8f*b4Z7^f              else if(c=='(')'~y8fDX/v*d
                 return '<';Dl}X c9O%E
             else if(c==')') Q"j(e,Gvzz0AB;S
                 return '>';*E!K,Gn8z _.B9pv
             else
s'?D(J}&a I F:_0z                  return '>';
o A%Mu:]}(a         case '(':
0DAf7n9}C9cv              if(c=='+'||c=='-') g5J6f:Y HU A Q
                 return '<';g hQuM
             else if(c=='*'||c=='/')
hq6eTwu;C                  return '<';*LzaE3]/^"[
             else if(c=='(')
r;uC,Mv;x7gN                  return '<';
/B%[q.ZYJI2s;R              else if(c==')')
)}x1m&_CrE-@'i'_o4a M                  return '=';
Fd+^ex0tt              else
lx0|d{&kS@8R                  return 'E';n\"_0dz:r+^mr:I
        case ')':cxzW CVSr
             if(c=='+'||c=='-')"s*Cp;J dEI
                 return '>';)Dz6r _N0z Mt
             else if(c=='*'||c=='/')^5|;fv!Z N
                 return '>';
(ni^,ks$C,fa              else if(c=='(')
&NO `7]*mj]2h                  return 'E';
;~9al[E\4n$Y5Ua              else if(c==')')C0ibsa [O'Fk&H
                 return '>';X v ?,^wev2F
             else
6qo+q.QC4a6Q                  return '>';
XexZPf\ E         case '#':}2t@3EdPEz!^
             if(c=='+'||c=='-')Z ueW+y:k6mu.i*b5ui
                 return '<';
ING4tw(F~              else if(c=='*'||c=='/')9j/L#G*A;B9|
                 return '<';
-v u'fv!EJ%n[|'u              else if(c=='(')
-P5?mc$W                  return '<';7ZK9k3Qg*o[ |J'q
             else if(c==')')F3QP*y o[
                 return 'E';q*f KB5]N
             else
qjW1@.v9Hk                  return '=';
8k1]Rf#DyxD         default:m,m\BT.O"] ~
             break;V ]3g y8zw
    }
5j6lL t/@.Z'oV     return 0;   
gV.z [V` [xM)S }fW#FN y!W @
8X@5| @9X/C5C%Kn
int isOpr(char c)V.PI D j{)D;]%U
{
4E%ui2r w4vTU;\     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
F_(E8Mgu V         return 0;
dspJ2eu     else '|#C4d D2v] Ju
        return 1;,w a\ or+x/y
}
u*F lP ^3h R6B1l*TK9CoID7xi-d
float operate(float x, char opr, float y)m ?m`-zyE
{
n"\ NM3h(t     float result;
:} A)kU^iz4eW K     switch (opr)
c&o)YUymN5U Z     { Kr#s#`#P0X
        case '+':
2M6e:l Q ^/z U              result = x + y;
4d3v ?Yb;j              break;
%Shl%FD'@9j Y         case '-':
D ~H5z5L"eoA              result = x - y;
M_4ND'I5N#x&G              break;
#sKx yA#h#m         case '*': 3~"vwYo.y1? y J
             result = x * y;
3r%h0eLlG,}j6{@              break;"h Ni?N5bPQ
        case '/': a,PB#E!qR-z{8y
             if (y == 0)
4y'ma&T0[4Q/]~b              {
b2G%L{ z`S?5I                 printf("Divided by zero!\n");
F$p-i?-bI(`;F2Y                 return 0;
(hB6gX|S!x              }
^W]RNZ              else
f2{(Z]^)W;k%w hQ              {Sh },C;@h9X;@
                 result = x / y;8g@1f!E ^OK`$U
                 break;4n2qYI2^3kn
             }C&{9uJ*ID'qXF
       default:
)Q]p:l*n"nB[              printf("Bad Input.\n");
9|6p't#j+_H$h&L              return 0; iwY1C8K4nyi5i#J
    }
GL/I q\^yl     return result;
j b`-~u b }   
(AO8zk&\!_!P!M 7n0_`&@E7e?-fx
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ Kw Z3a"^;\ ? H f
{Mw `z]%\Ij
    Stack optr,opnd;,c%aE0U6d+R sP
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;)zL]+f AI:JA1K
    char c;*HE+n0ZGu"ag \O
    char buf[16];
Y_r|#r O5d,b C:w     int i=0;
/{!u/U&h.a9B jS^    
;{$q.T%V c,}5X#O!V|     InitStack(optr); /*用于寄存运算符*/
s{*Sjy#tTP     InitStack(opnd); /*用于寄存操作数和计算结果*/UtF%w Z*x
    memset(buf,0,sizeof(buf));;NF3xq y!cMl0f;^
    x:pb3XgR
    printf("Enter your expression:");&i7?!f%U1{JQ8x
        %E e'[s9x0e dD^
    opr_in.ch='#';
5p]-Sh;]*^     Push(optr,opr_in); /*'#'入栈*/
\%Y.M C1C.?0c$f     GetTop(optr,opr_top);
w)T+SL~(BX     c=getchar();
8r? ^"U(^r~L     while(c!='='||opr_top.ch!='#') Oq'x8R+OCe
    {E8FK-GB#p
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
)Z |Axt| bYL&TA         {
~XDmb u             buf[i]=c;
N5T-_k m             i++;
)i\Z Pe;Y.c kK%T             c=getchar();
]&d4f Y*K)J         }U?;l7`[3^ q
        else /*是运算符*/
l4u!^j8|         {
n/HlN|8H$g             buf[i]='\0';
(QlG(~,oTGH             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/*j(D5uS?/k`n
            {
d'[e%j)l y8L*yG?                  opn_in.data=(float)atof(buf);xk3E9_*u s|O#U
                 Push(opnd,opn_in);?|-E7fo%`y4n
                 printf("opnd入栈:[%f]\n",opn_in.data);
$^_.d Zvw,YL8V'}                  i=0;NF7NJJ*~+s4g
                 memset(buf,0,sizeof(buf));tj6Q-PpF
            }\I*Z3Bs#?4Z
            opr_in.ch=c;A!|5F`3Hk%Tl
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/%m,uLJE&~ gjW&t
            {
5I3^#~2A,Mah8h                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
I"J#Jc z6TtS/Z#_g                      Push(optr,opr_in);
FEM+zh4GD                      printf("optr入栈:[%c]\n",opr_in.ch);
Dcv&A%v Fg4}n                      c=getchar();
`s gj6a*zNK5C                      break;
(Q7|H+Vbt                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/,O:AGk0E
                     Pop(optr,e);
.aeH)O2js}/_                      printf("optr出栈:去掉括号\n");
)E;B C8Bh                      c=getchar();
%Inp&fl!T%\,C                      break;
A)@:J?%NQ                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
q"H5pr\}8nR                      Pop(optr,opr_t);
9cm!^IS4|                      printf("optr出栈:[%c]\n",opr_t.ch);
%E3B-R'B4sI:a7Q O                      if(Pop(opnd,b)<0)X#o#FzIV/tO
                     {
z\u7uKT                          printf("Bad Input!\n");\n3Wf FA
                         fflush(stdin);
be\(sNPZX                          return -1;V#r1T:b*U3E5D%\!{5J
                     } L e9u8E"J L`"c7J
                     printf("opnd出栈:[%f]\n",b.data);
Om(ogj5rb                      if(Pop(opnd,a)<0)MVf4tr:LO
                     {VdQd9s w
                         printf("Bad Input!\n");(pO5k9w a&` af
                         fflush(stdin);8M'b,s8Nr
                         return -1;p@f%N[
                     }M(f"h\k,d5]{
                     printf("opnd出栈:[%f]\n",a.data);
/@/e'?"S5lO_T                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
BfA&b F6h!y*o;C                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
^&D4m1x Kpj(G|Q2b                      printf("结果入栈:[%f]\n",opn_tmp.data);
|5afs&L!^g p                      break;w1~#TGwx l)cH_
            }!nTI%C+VU1j
        }(L%RyKQn9pO
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
:]/d0u M/]z0|5y[     }s N/k R/g9D
    GetTop(opnd,opn_tmp);Hd4V2G*[xQ
    DestroyStack(optr);k/_/W/E"v(U$V
    DestroyStack(opnd);B0\D*k IFKq7C
    return opn_tmp.data;
R Q!Q!^Y }
(O:V8MxOV&Ga pSuD wP
char *killzero(char *res,float result)
x*e.Y5w9W&y(x#x {+_(w6O3k5]8L0]
    int i;
C2M$AXk+_!y~| L.qU C^/n?"|T:d|m
    sprintf(res,"%f",result); WE:ePi V#u"[-R
    i=(int)strlen(res)-1;
Ho X;xe0`     while(i&&res[i]=='0')
)M#J{0nG5_'^0\     {
/Jj#^7i^)jq         res[i]='\0';
-s*VL1a `         i--; d`v+]'I&E*_
    }
%z CS#@@%j     if(res[i]=='.')E@N6RJ
        res[i]='\0';
KV.d jRID1]     return res;,Ou-] ? }#n Z~#p/`@
}
7C+VZ:\kL8~
[dmiBf3g'B int main()
DPfYFb*w7H} {
!k$k3o8r;\+A[*|     char ch;
F]Ru1uE eZ     char res[64];*jd |~5|6?9{
    float result;
6B%m*Os4P |lB     while(1)D^0a_ G3A#VT5i,[
    {&D im2ob!{"sZtq
        result=compute();
h:X)T'w;DE2I         printf("\nThe result is:%s\n",killzero(res,result));
w5h2g1uJ T         printf("Do you want to continue(y/n)?:") ;7dO&N\y.x?)PB
        ch=getch();
+tb}} L Vzf'X;y;B         putchar(ch);
~0V*@hn-\ c'p         if(ch=='n'||ch=='N')
d;tb J~ [             break;
]a&r IM         elserO-Q-VR9CI
            system("cls");)MB9w#LU([rq i"L
    }
Y r(J&y%BA'Y     return 0;
9w.C}N8Ub0] }[/i][/i][/i][/i][/i][/i]!G:zln\ aW

+zMNMOj'H fA [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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