捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
.j wJe)y5@Y 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
x+C]7a["@ qZ0[ B#B /**************表达式计算器************/
TABs L7A-d"~W #include <stdio.h>nS8E-I't-^4s'^
#include <stdlib.h>
o3ZYjw\_k?)q;Z u.S #include <string.h>B!Fy5s:H(M
#include <conio.h>
eVR Qi Pi0U1S #include <malloc.h>
q*eMDSW%NK+t(V 2K,Y2N;]2sxu:X9LG
#define STACK_SIZE 1007B4_M)`/mR;K(`9U4Jj
#define APPEND_SIZE 10$o Mlv9d
+E:iEA%M$i
struct SNode{KiLm }r$T
    float data; /*存放操作数或者计算结果*/i/e {} D^ ~ HuO
    char ch; /*存放运算符*/ ?)Vq8PQ C fon+[
};!t,u[%R4K`4Q]7NK3i
~cBKsk
struct Stack{y X~*S[.`@?G oh
    SNode *top;
:e M$a%?"nTq     SNode *base;QnT9Qb&{
    int size;
%B'J6s:]&Tn+Co };
R L1k'zX
ZE/K4~9Q ^ /*栈操作函数*/;X6XA+]p
int InitStack(Stack &S); /*创建栈*/
:r"nWv'V,X int DestroyStack(Stack &S); /*销毁栈*/
7EY6b5^,`x\ int ClearStack(Stack &S); /*清空栈*/"q-Z9ca/T!b4W[ _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/"gr[u,tK7eqL
int Push(Stack &S,SNode e); /*将结点e压入栈*/
E;y9MR#y/w int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
OSx"i2L6cS
JN#X3lmG /*表达式计算器相关函数*/J3f+d7\;n$S
char get_precede(char s,char c); /*判断运算符s和c的优先级*/E;M3SG+X?U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
t Gb4g']"jK1c_9T4W float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/C$}"Rt%[g/w+I}
float compute(); /*表达式结算器主函数*/
^tv2jU9[%M\%n char *killzero(float result); /*去掉结果后面的0*/
z]h N-g m:[b6i
*d,Fr*YT#A!lB(V int InitStack(Stack &S)
l?/^hz6Z-J J$os {
MM7S4S*q#E/N1h-H     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0E)WSPW7HA }4I
    if(S.base==NULL)2})ys'Y} dJQ
    {
2m7IW-~VJq         printf("动态分配内存失败!");z e Th`:J
        return -1;
9KI*{R W{f Y;\&_(m     }
%D6Py QE     S.top=S.base;
5T Cz}fz]Vr     S.size=STACK_SIZE;d@$BKH5{7j
    return 0;
mC.kQ2uf }]G}%Q2tT

9] J ^-oH.X7q,J int DestroyStack(Stack &S)y] `E!l*Hk
{"XOI/yQ|
    free(S.base);QG6W)j(`,G
    return 0;/e|(Ac Ac3gr
}
X3U6o9x X*cf%{
!]Ex;Oj[l h6E int ClearStack(Stack &S)
XI't.pdB {{I/m2F+b@
    S.top=S.base;
Tp9tQ1Q.a:JRp     return 0;7N Y:J9D/Nw-iN
}
c4YKHQ2U&w
4})\~H'H7L j1W int GetTop(Stack S,SNode &e)da/ok$S~L w
{
2e3N"Y5a2B2J2P k#T M     if(S.top==S.base)
[.hXF-@ Hey     {
&Z!~@1GSf*\         printf("栈以为空!");
TqC`AN"T ^i         return -1;
5Zn1BX0USB     } e2A3no~1_
    e=*(S.top-1);:P+u.k#]4o I C,W'Z1e V\
    return 0;
~nH,H5`"a }
N;m0H$Wu'K H0~V t}s*km{3u s&V
int Push(Stack &S,SNode e)7K6Tn7IJYcy[n
{m ~M Ces
    if(S.top-S.base>=S.size)
2{u7UW&v%fU HZi     {ie!gN"hU.E(Y
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));;BJ p;I0x-t.uHB]
        if(S.base==NULL)
2Ns)m f+dO@         {aR/Z.~Zg%Jui5\+|
            printf("动态分配内存失败!");4S,Y FF:k!m8J
            return -1;_v a"`ASs
        }-]f5HtP,S
        S.top=S.base+S.size;
r0W.k_0Z0[         S.size+=APPEND_SIZE;(F;YUk/I{6L {^s
    }
9L `~|*VR9wx!@     *S.top=e;
p3R/H#[#v"u}     S.top++;4}_Y1wH'^A+@M
    return 0; D%j8}\8p v j%B#r
},B'j&y.[8STly

%r:Y!q5h A0C int Pop(Stack &S,SNode &e)
'RFm ?L[8o7b'C {k(t'O XAR1t
    if(S.top==S.base)
)K;g(x m-Da7J2Z%}2D#l     {F,wbER!Y
        printf("栈为空!");6K3oVY3i3A }:e8mpu
        return -1;CM:v4cZ:EKC
    }
7p,W A.nj0R ^     e=*(S.top-1); a Mryp
    S.top--;
1]B0R c+jH     return 0;6u ]\7W6\3R
}5cXZ T!f+S
r n*K[:\&U)Mg
char get_precede(char s,char c) sW1[(W%u_2tYe p
{y*r]~1O(_5^cv
    switch(s)W6NM x/iy@ NC
    {\;C8t lS_8IVn h
        case '+':                 
vs&L R&P S n)l%t         case '-':"Eg,^y*v4|*A1[
             if(c=='+'||c=='-')
wrhj6jGXV4f                  return '>';
%h(@uZ&N/}W`A$f              else if(c=='*'||c=='/')
/@:ggJ.W                  return '<';*iY#My.c
             else if(c=='(')
eF)Q m|R4c%b                  return '<';|k.dLW
             else if(c==')')
&bg*]PW                  return '>';
5z mR.vH&S              else .l G*s'Onvo`
                 return '>';U3sd~o
        case '*':
k7F&B6L O         case '/':y ?1^*G6{ O-Q
             if(c=='+'||c=='-'),sL/x2vr/k w.r
                 return '>';XD2e2Z,X
             else if(c=='*'||c=='/')5n}Q:WRmH$\x
                 return '>';*j^J Gwv?U
             else if(c=='(')1SvfA5G
                 return '<';
~ZZF/s`-Hy0Se I              else if(c==')')
ap|!N;Gx4}                  return '>';
aj3K YW1{              else*s~-j6??P,W(z-k
                 return '>';,k-xkhv S|
        case '(':L3z'tR`&d N(j/K
             if(c=='+'||c=='-')r9z!s2?c:Jy7s
                 return '<';,yu&^-rnr)h:wo
             else if(c=='*'||c=='/')\1q&u'N4H[*QD"|
                 return '<';)T:v k0|\)FA(SA
             else if(c=='(')#U7]+Gyk?
                 return '<'; Zmr*{XN
             else if(c==')')
KMH6uq6k4D.g                  return '=';-~:SxL;w
             else5{D0[ R\
                 return 'E';AA{ Ikm b^%A
        case ')':
$o*R)JD v3Z+Vt              if(c=='+'||c=='-')8djFg+ab
                 return '>';*M(D}].a
             else if(c=='*'||c=='/')_(r!j$l@
                 return '>';Q+k8u6hPZ2T:wxp
             else if(c=='(')
9N VY;VX                  return 'E';
7qLF!]fFD              else if(c==')')5\;wgg$x
                 return '>';2t-f@e4C5b
             else
w/mAkf'g,w(A                  return '>';
7|~} g:_v%]         case '#':
5c#{6aD.G \0M6XU]              if(c=='+'||c=='-'))m^c]!C+r4A])}2H
                 return '<';
3Q2@9_/lW3{R              else if(c=='*'||c=='/')
QA H{$JVM                  return '<';2hV]^ n[
             else if(c=='('))M3b.k%n.f:Z3xT B
                 return '<';)j Xt"\/Qs k
             else if(c==')')/V%l?*k-^+j
                 return 'E';vRuP1ab
             else
U1}H}q)R4KR                  return '=';
W:U-U)[:zAZ         default:%mNkEO"a]*X
             break;5K&o"F/k,K%p
    }
PF/i(e1A(FLS6?     return 0;    m!c Vx {"ub
}
[Fj2\ [MiD(c af9a-~1P)cvVy `0]q
int isOpr(char c)
#qh*jf#t*C?'r {
}m S,S!a     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')}TvAr
        return 0;
#bM$c3g6? B mwR5t     else
iJfGE HCs?         return 1;%^C$z1]3?'I2k|A
}
dW4\z2rd4I&SDx -qF;l$|3yh T
float operate(float x, char opr, float y)
e Y!`ZL {
7z:u?9c'Y0u)O     float result;
3k-}XC"Qa%u;ya8@5zC     switch (opr)jL h"~)EP
    {8?9VIG Eye*^
        case '+':
)aG1~${x i              result = x + y;
\X V_-l4H4r&n9I\              break;
R!l~6?9f(}         case '-':
NjG LuVL8@1EY4`              result = x - y; k&J`?]
             break;PIM^r6}'O|*x
        case '*': uy$lj.i:|'Z
             result = x * y;._&ygU%Vg
             break;
4cW}'U+~aC         case '/':
!T} ~ U~U(f+C              if (y == 0)
:otw&Ruc              {3L/|$e|*k
                printf("Divided by zero!\n");
_~ y5[i3F;[v                 return 0;"B3M7g0_l q,C)\y
             }?5U[Je8o}
             else9P|2h8M _1d4X@,yW1a
             {
~$?q |$r N] Qy                  result = x / y;;?Y$\e.in.g5ic
                 break; d Q+@W#yt1k
             },K0R&T Ei#O&d g _X0x&b
       default: t+sD+I Ed
             printf("Bad Input.\n");
S7z t `H In H              return 0;fqS pZ jv"U@8f
    }
C$h sz"JPj     return result;
3b1e3X)B0e;s9k*K }   
.|^0Y {BIf/{ :~$@@#P$Ko
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Bp A8f ^@ {0UK!c-RP1\
    Stack optr,opnd; g R`3~_C%k
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; }6\Y/W%dWs
    char c; ](YIQ.I gy|
    char buf[16];
7S4v%{ b(Y] Q&xV     int i=0;
$K ]@#y#E#EA;bj     i;`(s4ip:~E
    InitStack(optr); /*用于寄存运算符*/
v:sg.q$kHsud     InitStack(opnd); /*用于寄存操作数和计算结果*/Uo7v0K|8N/@6~
    memset(buf,0,sizeof(buf));.p#Q V&Z ~2o`X F'f
    f)bHC p,nY+V,|
    printf("Enter your expression:");
8|p$NmS.v         
.d#\&E&A4xRG     opr_in.ch='#';:`u2[BX!iu7l
    Push(optr,opr_in); /*'#'入栈*/
.n2\+? A.f3H     GetTop(optr,opr_top);
T h GUDJ6K/H9|7ubC     c=getchar();9u#t,Y,wV?-qu,m
    while(c!='='||opr_top.ch!='#')7A:I}q-H*X
    {-EI SfUnG%]
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
~,]p H cCL)s} ZaJ         {
jc8d$Cf,aS             buf[i]=c;
#H2E]V{8q.y#dKF/GR             i++;
imw1t,dXX             c=getchar();
Opk~AkWmzG         }
u~+H|9`-lmi         else /*是运算符*/
'Jx$Kg;x:K:a         {
E_.n4p oz             buf[i]='\0';
L*yAS3bZg.j%r             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/-CC-lI m8R
            {8^ s:l8L?)Z e/p v
                 opn_in.data=(float)atof(buf);S!_ y4xJ,^)Kb
                 Push(opnd,opn_in);
\ \|%Pnt[m                  printf("opnd入栈:[%f]\n",opn_in.data);g&t!M9u3r
                 i=0;
YQz @"e                  memset(buf,0,sizeof(buf));
I*V"z1ZL#H'M2V,A             }:[|l@TxTc9_
            opr_in.ch=c;y+bNn7L/D
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/p }4K!p#vB
            {iTJE'm7~ un
                case '<': /*优先级小于栈顶结点,则运算符入栈*/ FZ z?My
                     Push(optr,opr_in);
q"KK#\nD9y                      printf("optr入栈:[%c]\n",opr_in.ch);
R7cl H7^                      c=getchar();4U,}j*D@-zW
                     break;
RLZ'z8R-d.u0o F!Rf                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/w8yNPb
                     Pop(optr,e);
?V2F,Yv]U g                      printf("optr出栈:去掉括号\n");
4oa `3V2C4?0f&s6I{                      c=getchar();
^I)wM"^7T)Z"~YQ                      break;{ S4D#QA!h
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
B;?8Kd1C9E                      Pop(optr,opr_t);
x`j^c"y9J                      printf("optr出栈:[%c]\n",opr_t.ch);
-v)Y6?X(Mx                      if(Pop(opnd,b)<0)3r } bNey#T1F
                     {
5~@4K ]#Q_U \                          printf("Bad Input!\n");
%j8J5g U{L`                          fflush(stdin);
!|oqC)k["L \B*?`                          return -1;,|5K2l0g??]
                     } f5Je/yS,N
                     printf("opnd出栈:[%f]\n",b.data);#B[m?"Epe~
                     if(Pop(opnd,a)<0)
#A)Hm-@k9{?0N                      {o A g4eeMC\ x8T3B;ZW
                         printf("Bad Input!\n");1q'M%iHX!`
                         fflush(stdin);
T [w@#[5Y                          return -1;
St|2FMA                      }
\Z B*ms*P                      printf("opnd出栈:[%f]\n",a.data);oyd {zi%V
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/&e.rg+j pC2l1H
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
%rKhl+@z/st%qk                      printf("结果入栈:[%f]\n",opn_tmp.data);u8`F0Mqs{
                     break;
d-T%@&g:wKB             }
*^4y/W/YG li$\j         }
a-BK{N-^0X Q#^ Xd         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
-f7Q&o]"auUh     }
wNe/w ?M[8K     GetTop(opnd,opn_tmp);$c7Ir3~m
    DestroyStack(optr);lJl(~5nJ
    DestroyStack(opnd);
#U1ty!d5K2nM3e     return opn_tmp.data;\G1h(z0tH
}
f*W;[5T9u0K#J5Z!M
&UR(F-p9gL2k)j c char *killzero(char *res,float result)
7jC$}@u1y;P,f {
7ju:n)N8C!A+q     int i;
;U?k3sD\wve"l
z8M+h%O Yf     sprintf(res,"%f",result);
R3lt[S m3JG     i=(int)strlen(res)-1;
lK!F%p-o G R     while(i&&res[i]=='0')
#i bR%`T*Q3u"j     {^Jz9p#v
        res[i]='\0';D;e _h*V
        i--;$J$gZ&QPeL \+^
    }^ bv zny)C
    if(res[i]=='.')L+\mF1J%c)]Xr&ON
        res[i]='\0';
-F*Ql3y-D4GMkLv     return res;
HqeOq2m }
2^8t@5T` v^JY
.u;TH,]o7{ \ int main()
*XFu&be {
w4Ia8c/l     char ch;%I^i*xrJ,RS
    char res[64];
~)j4N?,EA"`     float result;
AC:g Uv*V!C^b*q     while(1)
aoN9G5ED| Q     {{1[[3[-rL1[
        result=compute();EZ-^So#v
        printf("\nThe result is:%s\n",killzero(res,result));
4d*]Uw qK,}7rnxX3q         printf("Do you want to continue(y/n)?:") ;&c9Va~,ETKU4Nz
        ch=getch();
{~(y;pi[         putchar(ch);
.m/l-?c$u#DfQ         if(ch=='n'||ch=='N')
U L.N][7I             break;
;H/@~+?8]1BZ,t2C5s         else
S X(f C,b8H A%u#U3c             system("cls");iHwh-cl-x&OG
    }
.e#DW8Z ZT]     return 0;sO)Y w2q:`ZM_
}[/i][/i][/i][/i][/i][/i].K T ?6B,X&J I
5m p:r-[z sC5FE w%V
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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