捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.%q5s4o&s@gliv
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
%qI7FqeJ8t /**************表达式计算器************/
N$s$}b-FW #include <stdio.h>
5}^ V"r I%^r#y2y #include <stdlib.h>Kd?R"?
#include <string.h>%s5D}x2O^R~
#include <conio.h>
` xroh,VMTO #include <malloc.h>
7pE8B@5T(QE[7Y 1BQ D!}[#J5`"| ?2I
#define STACK_SIZE 100
W(S8[ Y JvO w #define APPEND_SIZE 10 BBLZI!t
MY+v|i$E H} tG
struct SNode{
D,}*v!vH+PU V     float data; /*存放操作数或者计算结果*/
3~+C'?.@C2ATB     char ch; /*存放运算符*/*A F-wq+u'[ m IzU7?
}; J*?P9QJX6z6ih8n

Vq:^:t6x:{e!BR$l'^ struct Stack{
7A#l.py{ ].H,[P Ti&F     SNode *top;-{1UNbZTE?
    SNode *base; |-]IR`-SZ6x
    int size;
T5kP9W2J NgR(U };
A q8v$R G/C
k-j;Q%j$C'cC7t_rYW /*栈操作函数*/!i&I PFL&DIE FI'e
int InitStack(Stack &S); /*创建栈*/2q)@(`2@x0h s
int DestroyStack(Stack &S); /*销毁栈*/
F5l4II6c.D int ClearStack(Stack &S); /*清空栈*/|3PWU`p/D
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
;G ~(f\^X int Push(Stack &S,SNode e); /*将结点e压入栈*/y0h2TC]$i;\~
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/*U)O/t4Y$B?9H

AWU'~&fH*b^5Z /*表达式计算器相关函数*/0B,`+XQ1f'][1X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
a7z!M pt)U!O-A int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
(\^%A)Fxm yy float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/!Kn:L5\;qtC7S2f!t
float compute(); /*表达式结算器主函数*/%KX*B5qEsB%cg
char *killzero(float result); /*去掉结果后面的0*/
h9[W/w[
2kCh YNV1ZV1A_i int InitStack(Stack &S)
9?$dF/d_ V([ { IK%c%q0lK;k{
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));1^7q!Uj7}&E4l5Y,iX/d
    if(S.base==NULL)6zfT,gO8?3C
    {MRRl W8z[;t+`
        printf("动态分配内存失败!");.G5BJ(D&e
        return -1; x0a],Cc C5X2B.@
    }
s%f;^k%x     S.top=S.base;
v9f KFo @0x     S.size=STACK_SIZE;2|d`:v{ M qI%G
    return 0;
*v!p~,aY.mw~-Y7c/y } _)}Eoh6x/xR
m ? t[f/RI3w{
int DestroyStack(Stack &S)s6tS)DLtc
{8P%n;e|jiH k
    free(S.base);
~ ab/usti     return 0;
8BQ(y3H0D`3}-K6NH-]*P }
*yF"B!`:Sxj n'B0N+h'F$]L)l
int ClearStack(Stack &S) Ng2N7k_a
{i&jPRO I[!cp!t
    S.top=S.base;eTNV+x%ux9o
    return 0;w.nvp#[l
},B(Lw0[L3?[ a&x

H p7q^_9lot4l)^ int GetTop(Stack S,SNode &e)
4LF4~5x;WM(}Y_ {9XOU,D'H"b-~yK
    if(S.top==S.base)%~X;HCF.N
    {[MH7M#z~ f`
        printf("栈以为空!");"w|YQ u!l#z N%V
        return -1;
1]6uv,L,h,x4^ g     }:g&K;ZJ#j$x kL[4_
    e=*(S.top-1);
y!o.kQ8WsI'diu f     return 0;
't2Tw;@d4`+Zu }
DG-a8O/T SP 8Q2y%?~{
int Push(Stack &S,SNode e)-zL'~]P$Px5l6v;c"c&Z
{5t1f)E-S)g$lf
    if(S.top-S.base>=S.size).K-i aF:P}lHJ
    {
2W n"C2\ V         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
9P+L3UTr_}5I         if(S.base==NULL)
7J h5e'{ GDF         {
c ? |-qAZ,]c             printf("动态分配内存失败!");*q]b0Y.Y}re+c!I[[
            return -1;
4K0wB$OLn         }Qs(C g0f-M&c
        S.top=S.base+S.size;Lz~Fz A!n:m
        S.size+=APPEND_SIZE;4z|9lx)Qz0E5Lf
    } hH9a?!Jl
    *S.top=e;EC+Q)lH1Vm
    S.top++;
:w.u6F3] W;x/Xb"I|     return 0;
;kFRkU:g }
dJ T*E#tkG.W
?]4V/AMq int Pop(Stack &S,SNode &e)
)@dN-^Fr\,oNK.j-T {
b'Dy;O-V4[ Mj     if(S.top==S.base)#O J o7Fm l
    {
:i pF1MN%J%L|*VI]         printf("栈为空!");f4qr$K"j
        return -1;
9mw:UI(P@6}     }%LD&xxA6L
    e=*(S.top-1);
pJ` WK8? y d     S.top--;
9Sk Z(K?oD%g     return 0; AdhT2Ds
}
(xD P,c!GG'W4h:~
R+a0lpD%pe6p t j char get_precede(char s,char c)`^8Jg;HHn:Q.S
{
c:U&z%^"z(Yq     switch(s)
(`'|*o^!w n     {3~!ec%mlUB ony@
        case '+':                 Bn c$z8Sm @:~"T5s A:C
        case '-':IQW LP3q"[
             if(c=='+'||c=='-')"au"vtG0n0p
                 return '>';Yn$zH D.z)Nx
             else if(c=='*'||c=='/')K)y.r'p'r(B!A
                 return '<';
Vc5oAAg              else if(c=='(')"u(^X%I8Bp"b
                 return '<';
;j So+`s u3H              else if(c==')')
~2SR+C%jSV%Q8B u                  return '>';xyC.e0Cvr
             else WRm BZ9aHnn
                 return '>';9{;L1EP;br t2Im
        case '*':
jH ^Xy$W W,^         case '/':
SX#N.om`B`L              if(c=='+'||c=='-')5]kp._L;R*g4Z/A0{;W
                 return '>';
] }'F8w%t1I"I:g              else if(c=='*'||c=='/')6Buc8?)gO4aF
                 return '>';9^$B'x ~w:dP SJ
             else if(c=='(')
bD@U)H{,H'j                  return '<';1f\;w(H-[ h:I
             else if(c==')')
:X$J#w&@&v^d                  return '>';G|:r&]!_ D~
             elseq&nBs4Q&K\7C,?
                 return '>';
3EdlHQhp|         case '(':
g\0ETA/}I"Z2LLp              if(c=='+'||c=='-')x9CEzKa7N g$z
                 return '<';
?!l8Jh!N}/k              else if(c=='*'||c=='/')?&G_%HL
                 return '<';
$\H'r$Fe#u              else if(c=='('):zR~5`gb
                 return '<';
Y`k8r3A\              else if(c==')')
@i(t?,eb7X^;RM[                  return '=';,_kM*Jo-o0r/d)l
             elseW9N9iUsF.X3j%uMP
                 return 'E';
c5\f*xrbQ         case ')':
~)SJ"r8]2C              if(c=='+'||c=='-')
@4Osn-PQjp/` @                  return '>';_4Z Y%k1d3yB
             else if(c=='*'||c=='/')
\:b,@h@3Q&?:p8q?]t                  return '>';
)k,j Rr{j8|^m              else if(c=='(')
6R)q"]'B}*b                  return 'E';J(V,Z.Kw]4W6Hq
             else if(c==')')A+X#J1b3Iz9@
                 return '>';a/PZcx6y
             else
T3^?!tKa"f                  return '>'; a;kYS5U oTv
        case '#':
v!x;h-zkJg              if(c=='+'||c=='-')
ES iDng                  return '<';Y(W1Vq@*m*O[["J
             else if(c=='*'||c=='/')r` l%VnX+Cj9x3@
                 return '<';:c4Ngk|
             else if(c=='(')
$u0^7D'Ige)Ez&x c3X                  return '<';
S-_\ ]UT q'Ni[              else if(c==')')4A2mE&S` Q
                 return 'E';5Lt\]&B6T?:P'P
             else
e/R s8d!@y.|H                  return '=';4pA*t4_ h:j]
        default:
b0d+D7AHM+EY              break;
3Hy f.r,h$r0R.X4`     }
;Y2b ar] U     return 0;   
l vU:o3}8y }+_4] QA'^q j,Ag,O

7a@;u\Ef:uY int isOpr(char c)
O.h Q!DE3\k _ i'N {
NKHvh blF\8v     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')z [t]3F-D0a
        return 0;J3ZB&{*To/@n5O
    else
*F&X7n+]sZA(|         return 1;5c]-x.v)]\x/Y?.e+h
}
h8fj @/{r S*d |8s7PDe)I_
float operate(float x, char opr, float y)~2a#c J"S
{ L be Vng)e5j
    float result;
x,[-n+]w[ P]     switch (opr)
y4Ib2a8Z'Q(@tPR/e)Y     {
*v5Lx)Eai0|         case '+': ?Ljui)H8^
             result = x + y;
/Zy {9Kx;t U&T9o              break;
L;TK,ca)M+A y@         case '-': T_e aT+R-q)F7e5n
             result = x - y;
a2f3eV epH'`              break;WX%\,n4g ~
        case '*':
1k-Y~XGty              result = x * y;_|p i!BKP|
             break;BxO6k BYv']
        case '/': 4NH.wU;jhC;F d,s
             if (y == 0)
3Lcz^pQ3B              {
3{$^XB0K o4{!q                 printf("Divided by zero!\n");,w,kr {Y;Y(E{E0h/i
                return 0;
B d2G~Q)Z              }
ch8Ec$dH9Y FP7\0t K              elseW.i_"phZ4b
             {
2zT_e)s                  result = x / y;
j m!N1T5w~0|                  break;'AHr/z#F:PK y w
             }
l!HV9y` e#l9f        default: FZ,xuw1^)y3Yz
             printf("Bad Input.\n");
/Y l,[b}u _              return 0;R UdO&Q q
    }
$uve;K{-` t S7H     return result;
0u_T2t.fp}G }    1E/ArC2YO
$gT!UG+z*rL
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Vs4pp]KVO {4@"v]\ot%]/\
    Stack optr,opnd;
Uq0HpIuD     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; Q ?N$~{RlnV#Q
    char c;J(ient"T5sMh
    char buf[16];
]*kC bV     int i=0;
h]M`uC     X6[B$j:B4S U'P
    InitStack(optr); /*用于寄存运算符*/7a#WK0b[Z4G
    InitStack(opnd); /*用于寄存操作数和计算结果*/
At1{O*DhG$wa     memset(buf,0,sizeof(buf));(h z$c'P u*e
    !s G M1}/gBw/m r.L
    printf("Enter your expression:");
;P9XG3mG         
wC4Vl jt \+wwC     opr_in.ch='#';aj/Aj S8CE!N O
    Push(optr,opr_in); /*'#'入栈*/*W|l bH{SQ,L
    GetTop(optr,opr_top);#U2@+pyJ"}
    c=getchar();
f[d2R0O$S     while(c!='='||opr_top.ch!='#')4z(\/D8j+L.Cj\$\!e+f\
    {2Io'f.g F/m!~N:r
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/q%Ur/j2U,Za_]
        {+@;u!\NjN K4rB oc
            buf[i]=c;
Q x9TXwV |L v             i++;
6O:w},pjI9Y4ZR             c=getchar();
4xtlKF"f         }6tUM7Q:n5{
        else /*是运算符*/
9@dkW/I4f:Im#` K         {
8k;i J'ZbpR2V             buf[i]='\0';
ZW2Z5P0@#|2Z             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*//{VM/a @T_
            {O@DPp?
                 opn_in.data=(float)atof(buf);|s:gw)~c sw(]
                 Push(opnd,opn_in);
^l8DHPZ                  printf("opnd入栈:[%f]\n",opn_in.data);
8W }"?1OAS$n                  i=0;/o+H y0utq+{6s
                 memset(buf,0,sizeof(buf));
$S M)C!ym.L             }
nmdv-~ } ur             opr_in.ch=c;m0H1gi1C8sT
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7S0@s4U`4s@8Aw%uE
            {
D*Lrcvf                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ w,?t|Ef
                     Push(optr,opr_in);
:v7P7x ` u|3W                      printf("optr入栈:[%c]\n",opr_in.ch);
2Q*Dxh.ndd M                      c=getchar();4\U/dz5S
                     break;
+Bx;l#{ cP                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/d-zP5lBOgZ
                     Pop(optr,e);4U6yi@,M
                     printf("optr出栈:去掉括号\n");
E|_RF5ft:^H%W,I:X                      c=getchar();
(e~L8Ea'y                      break;
2m*N(g+o7\                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/G ztg@{ E5XC
                     Pop(optr,opr_t);S+K in|(~OW*?
                     printf("optr出栈:[%c]\n",opr_t.ch);
j6y&u+K4LW                      if(Pop(opnd,b)<0)
'^-VvI t3Atn                      {
%^][k2PG!s^bT                          printf("Bad Input!\n");tdYR+X}K+}5p/gP
                         fflush(stdin);
(@} VeW                          return -1;@*X*p4V.zDhC
                     }
8i-PU4ESt `;|G                      printf("opnd出栈:[%f]\n",b.data); X1ak4s)tN"Qnr
                     if(Pop(opnd,a)<0)Y!n!EB s@sTF
                     {iI:vf+q;[b?
                         printf("Bad Input!\n");/U,_!Vx7f
                         fflush(stdin);
DKiy O2O m7Z                          return -1;
#CX"zsKr'J/@/]                      }I5b?c.qr:lT
                     printf("opnd出栈:[%f]\n",a.data);Z!Q]Bf U2l
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
5d,}r%Oi LggE+r                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
`)D J Y3m`-X                      printf("结果入栈:[%f]\n",opn_tmp.data);
+k7m cT zpF                      break;
(gHrf$t%@F5U             }
U^h^FH,L         }8F?9F%K\ L Pp lK6}
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
%wen_ t7K     }
;y]9V/S [ Y"Uix     GetTop(opnd,opn_tmp);
3xD:]T9rZW     DestroyStack(optr); B O"yY!x0v
    DestroyStack(opnd);
"trgpT Ow*c     return opn_tmp.data;v&c8^5VE{*IN]
}
?w f!nU8c s v _
ZB7e9R%V] char *killzero(char *res,float result)"D3~4mF.wLKmz
{7c g6a,xpk/]%[
    int i;
8dCe3P9GAhk;D? 'E].d YZpq
    sprintf(res,"%f",result);
t+u:h4J2n(H     i=(int)strlen(res)-1;ey!@?N8g3},Y
    while(i&&res[i]=='0')
8kXvaHG!I+inz     {
oQ7d!F^_j9b         res[i]='\0';\:eQ @6z
        i--;
"oj[Ak     }:`2~3p7[ b!f)|2k
    if(res[i]=='.')
L8rs\M*Bn         res[i]='\0';
]8XX O a M     return res;
*Mqo;u| G#[ }6kna't b J2h

k-GSB3\+y2h int main()8W2Bf(m0p0l
{
L3E&a)^[s     char ch;
6NJ#U2U'~*n     char res[64];gU,_&Z(xS
    float result;%^ wv3m4x5D$p%r}M
    while(1)*{^:c:]5n C0kx
    {
N \:C)U2D Ei         result=compute();V@}Kx){3F
        printf("\nThe result is:%s\n",killzero(res,result));
\m|&fDX]Q g         printf("Do you want to continue(y/n)?:") ;
Sb g"SJyL7w         ch=getch();
)z `J.])L+]DE~         putchar(ch);
X2S0L2xm9^&W4u         if(ch=='n'||ch=='N')
1{6zh ^ S&s&`             break;'yg4`7@#g~_[ `
        else
y7[0q%~Q{I             system("cls");
:kxU"r}S)O;I)k     }
%V ]a)U!WcSS     return 0;
H1rRa%?9e }[/i][/i][/i][/i][/i][/i]`(w5]%Y2K'[

*g+` s g P A"H\"RC#R#s B [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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