捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.l$oU+e3z fs
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
N{(e)p:? /**************表达式计算器************/.Ct,^$[XjT:B.v
#include <stdio.h>
k-K8X$o U;]v] D)yi #include <stdlib.h>)\j9YnBP-[ [g
#include <string.h>
|*o h,\j #include <conio.h>
ip5y%QB,l` #include <malloc.h>0_L]8`2i]9se
| I1APp'm&w&AW
#define STACK_SIZE 100z dV6lY_"B|[
#define APPEND_SIZE 10
&HH7];LI8B"w*\
h:L7}zq5yb struct SNode{|YAy*]u_
    float data; /*存放操作数或者计算结果*/-ODR A2f
    char ch; /*存放运算符*/1F f)v(O"eAvj&U,@m
};
eq&q~5\4mY)B
3N*xSP0z struct Stack{
_y5[i#o     SNode *top;
pp7s,[q     SNode *base;[l)ikt&\3Y'e
    int size;J|] p#GP5UC
};O[8R n[0V/w*tT/W
$Yp*ocm"Y6IE
/*栈操作函数*/ fRn)W]7Y-M-V
int InitStack(Stack &S); /*创建栈*/
XEu$?!^ int DestroyStack(Stack &S); /*销毁栈*/
9` {2L6iFycnj_ int ClearStack(Stack &S); /*清空栈*/
s|a@5s%P int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/RJ)`?0W
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4dW)z;W2Ry^? int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/F/]CCg!Ga/O/w N6{

9hD/s9y#y IDHv /*表达式计算器相关函数*/ Pz,P9fRcW"O'`
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
1h`uT'?\ r int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ fE;c o `n,A'N
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$on*Ig~L"FV%[
float compute(); /*表达式结算器主函数*/.ZJ jHFkH;j [
char *killzero(float result); /*去掉结果后面的0*/
&xDc:zw6W"U;Ss RX3C6Hn8u EsKq
int InitStack(Stack &S)
+^p8R-H3r-BLP M ~ {
9uktwBk?     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));-j5o"@+Q-Q0w
    if(S.base==NULL)
x0_.J ~NI_w~.s     {
w1f!G:wWD)so%w         printf("动态分配内存失败!");I5v\'p']y
        return -1;
+LRz_\:\v     }
Y/Ug1gO     S.top=S.base; GQj5P eeH
    S.size=STACK_SIZE;T2]r*Di;@,c5\ F
    return 0;
(sM}.rSp };Cx7[w@ ZP

(TeV ~jEI3S8JV4?~ int DestroyStack(Stack &S)
N hd XY$bZ9TL {(p0D6[/JE-F*|/s
    free(S.base);
8c\v-Ng T$H     return 0;i hY }mL
}
}k jJm4Mn 4J\*v%T8k-_*d'O;n@
int ClearStack(Stack &S)4vTmOs4d%d+?v
{
EY3jb1Q@+Q$I0@j5~     S.top=S.base;
6O^oh)B(CQ'Nk     return 0;S"j&]]RJ
}"mK _f"l?d\

ITW F/oO%b(pP int GetTop(Stack S,SNode &e)
~.@~KUAk { A"E8P,x/Z#CEtM:N
    if(S.top==S.base)
8I2Hz)h'M8x-CD     {-Wp[D-j0w(Uz/Xyv
        printf("栈以为空!");f*Z sxf-Q
        return -1;$@ikRBwlVT
    }
o&k-XQ3n_Ym     e=*(S.top-1);
p4b)m4x{R4V Cf     return 0;
({*[we#n8s1\ V v }
P)@R+@{Oz 6q b~\ M7W2N#b
int Push(Stack &S,SNode e)LoT,^2g$^
{&WQt UmTm
    if(S.top-S.base>=S.size)
u+L._G7_K1L-[     {7NeZ a^9oL0t
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));}-OU~!fl Z
        if(S.base==NULL)
xF$SU3xB n         {h?J~W{1i-X
            printf("动态分配内存失败!");
}$vA,{+H&E$r:U;o\H             return -1;
@W P-r7p         }
^7y2o2ck%L5}         S.top=S.base+S.size;!\-E0J1p.G bo/S?J,g m
        S.size+=APPEND_SIZE;
l7g"m9jTT%Q     }
\+?7VK)Tk     *S.top=e;h#C1m~|6@#r3E` u8[6{ _
    S.top++;
cm%o G\{     return 0;
ClMl.{X }X^ZS"[ N-z _$Xli

;k4z"fiah _;?:_ int Pop(Stack &S,SNode &e)2By9`sNE
{:D"tm h&rxk.[
    if(S.top==S.base).h4LC6W2SX
    {9X.B a8q7oJ\ |4x$e
        printf("栈为空!");
` peQ#J t         return -1;
'|]!\+J^^)SyhL     }
'{J I3y4hD     e=*(S.top-1);$PkGqR)}#]7g
    S.top--;
FX4}1DQ6EuPW'D     return 0;
l| q{N4[2?yl }
)T8Q'?e9qjPk
;z^|7LlJcO char get_precede(char s,char c)
V"o]+l+N+K'b { c{+E i-O w/`
    switch(s))v?"Gx9U
    {&n PF"pFz5N/n a nc
        case '+':                 /yo nz'pX`U
        case '-':4h"k-R3y k z H3}4\
             if(c=='+'||c=='-')M$M.rHJmv)F$h
                 return '>';
9B@L*q`` x1u H              else if(c=='*'||c=='/')
u jE)j+O.N-Fw n                  return '<';
y,Mw0^2m X$o|9O              else if(c=='(')
Q$sI?:X.I+eAT-b'Z                  return '<'; Y^jJVtg
             else if(c==')')
md M4fWNm                  return '>';
-LS2d??y              else T'_.YpT
                 return '>';
jyG y0V4aT         case '*':
]'VML!Z8kC         case '/':
!dFN%\;Di              if(c=='+'||c=='-')%ag6F._ga
                 return '>';
,Y:LGa.rx3VE              else if(c=='*'||c=='/')
SXB(}cQ(S                  return '>';
6IEk[v              else if(c=='(')
q/d[&kH&Y0Y                  return '<';%a8`cN#j
             else if(c==')')!W;?{qy(A0A5})b Hy
                 return '>';
D]%m @:]J5Z5B              else-c Ac'yGUY
                 return '>';K_3THPn8R;DEa
        case '(':
vBH+aWrJT              if(c=='+'||c=='-') g;~s P7Ldx+e$[
                 return '<';(H^$fjk;AG'D-R
             else if(c=='*'||c=='/')5u$m.sKcK,h"R&s0p
                 return '<';
T;e!QSLU l-?              else if(c=='(')@A u#\6?z
                 return '<';
HS|`_v6Yj+h              else if(c==')')
8eV.r&WM(?\                  return '='; D*zg+\v
             else `$EhrI uvN
                 return 'E';C.l'T0S8h6d;N7l
        case ')':,np4qt;Kr#H[5{+J?
             if(c=='+'||c=='-')
;l+@j Xz3r                  return '>';
ZsfrY              else if(c=='*'||c=='/')1s)L.W:qRA;fR
                 return '>';["Vu!CGZ ^
             else if(c=='(')za$[g:T O,T
                 return 'E';
^8hW'Bpu%a)\              else if(c==')')
b@9CsKv2v                  return '>';9x P0xJcwn)P
             else YhD7l0rE-ab+V5|
                 return '>';8w&j N0m8b
        case '#':
6x _,aH P-j              if(c=='+'||c=='-')x/G4ZaT8MIZ
                 return '<';
YtE!nNRb              else if(c=='*'||c=='/')
[P$yN8HR a7b                  return '<';p _(m|!{'Ku
             else if(c=='(')$J+Vc_I
                 return '<';
:[f-]8{\8E(e)D M              else if(c==')')
4\*^Cu"Iti                  return 'E';
%D1R[B] H-L              else
0C"m\"z7hC                  return '=';I6d[E2P%i5j
        default:1OkBNp,xXw[{{
             break;
~{[3H,R/q[/S ~     }
3Vv3Qy#H p5k$D&i?({q     return 0;    X;sJ F+|T;P@
}!@9YrNZW+J |qt/`
6Rw(nS&Ht~:`
int isOpr(char c)
q vv O'hr {
%U{~n HW     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') Q.Q#fXQN"v O:P?
        return 0;#d)vV _?M g;h
    else
3Nhl/rQ_C?l         return 1;c1p'}-D { _t N!l
}
s&OdE)nF.R *O,hB#A2\ Yt4s4a
float operate(float x, char opr, float y)
.mPRQLM%oP\ {
&[a4m'K4?cC,?4v"][     float result;1z1Iygx9J!ptv
    switch (opr)
0J~ `U},dm9M5u     {$lnv O ~j
        case '+':
'_XH Y dL              result = x + y;
;b7O:c:o)N zf/[N ~.G              break;
&J/B&_u:^`+i;E(u(F         case '-':
[,gy$i&nbu              result = x - y;
.r)A6[_%vc }(K              break;-W@fe7zf X3g
        case '*': .c"FF"M r'} c
             result = x * y;7f0f*MW.~.x5JO5B
             break;
0^!y r/^ R&]Pmx/n         case '/': 6c8Q!iI {l$Wy
             if (y == 0)5Zh C2U-V8@fY
             {
Y7jbu&J jd;?                 printf("Divided by zero!\n");$F0B'^\nE N,K
                return 0;
'U@'eZ`QY| r              }
*El1L.UFx vXi&L0o              else.trH;I`&H~*|h
             {
z7SF:z QJi1{2D                  result = x / y;
Z.Jk,d7P4Fx                  break;/I1p+k$A{(pA$a)V3w
             }'r"P1n9t7wU
       default:
5jT t*cf-VD `              printf("Bad Input.\n"); i0N+aR,J
             return 0;!z&KE k3dbnV
    }S |gF.a5i8Ix
    return result;
W7S _0l zIs u }    +P A:h2|]'S8y do

Jp9s"X rzLMt8WL n float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/AZO0wM]
{
_AO&x#A C     Stack optr,opnd;1E I*rX2G YG1kr
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$@-|5X"C{L
    char c;
8_/oX%e _}0@#x$s     char buf[16];%zq1t:JI-~
    int i=0;
$?dF~2I p;of"~ I    
\^^mJzK     InitStack(optr); /*用于寄存运算符*/
$nAv8WPp{     InitStack(opnd); /*用于寄存操作数和计算结果*/
8|jHF2N W`~     memset(buf,0,sizeof(buf));;Y ]^(Mh
    y7_ xC'G
    printf("Enter your expression:");
9^$N#y$E({p Q b         
3h @5q f6TP^`}     opr_in.ch='#';
*? O5U#dUkPf     Push(optr,opr_in); /*'#'入栈*/
/X{}"n(w     GetTop(optr,opr_top);8]Y ]"Gi+n)e\D8z
    c=getchar();
9V]X][BzI     while(c!='='||opr_top.ch!='#')Y EO9`'CM K
    {^6Cv7l^Ob
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/'F._ d!Bzx,K
        {
2v+n$k1m b V#W             buf[i]=c;3E;n^*r~&l u@
            i++;8B'p X$FO N
            c=getchar();#S dI8f)V#}.~Qc
        }
r9i C&_ GR q"ZFri         else /*是运算符*/
$DJ+AG]V"T8}         {
o8l_ zsG4C%RZ,A             buf[i]='\0';+pR.ts K x_BV
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
!K0zsaYI             {
(p{2hy t+?!_:Lq8{I                  opn_in.data=(float)atof(buf);'h+G V.D!U,E
                 Push(opnd,opn_in);V!Bo;~g.CISH
                 printf("opnd入栈:[%f]\n",opn_in.data);j"\a`OG|\$|*m
                 i=0;
A4M i@/}.qf                  memset(buf,0,sizeof(buf));
5_'~*qw&xf*ku(l3p%Q             }
'PYG1WmO             opr_in.ch=c;8z|{ A N.z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/'A.XM Mg6E'\]
            {
Ilu.KIKx ^                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
*J/[,y C6^j _&J&e+f                      Push(optr,opr_in);
$Vr'L*s4P                      printf("optr入栈:[%c]\n",opr_in.ch);Th]*ky8W
                     c=getchar();C$g @A]e,kG%B
                     break;0I\5o9y6M'_7q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/cW `%o0r!TI5w
                     Pop(optr,e); lt3_8T8Hp6T
                     printf("optr出栈:去掉括号\n");aRIIbE']8h-K
                     c=getchar();8x o%{Pfw
                     break;(}*Ws7No%BNt2T\ q
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6m.YHJn"i O
                     Pop(optr,opr_t);
}7L"vi#n                      printf("optr出栈:[%c]\n",opr_t.ch);
!|&GYp`Ixg                      if(Pop(opnd,b)<0)$xT R F-^.r6iN
                     {
3F#zEV l-~Z                          printf("Bad Input!\n");Ny,V2[ P
                         fflush(stdin);.mIfF{IkNY
                         return -1;
)q ?e*h6_                      }&{/ThPK,R&q*U
                     printf("opnd出栈:[%f]\n",b.data);
)E.?,MwG&eq&x                      if(Pop(opnd,a)<0)
"x0C GGr3L,n                      {5~)OOck
                         printf("Bad Input!\n");
WO:b'{/Zp9`#Y3d                          fflush(stdin);
,Za``'~DXvF                          return -1;Z8|~5i2@&[
                     }
9Tf,VHz x.{({ A*LE                      printf("opnd出栈:[%f]\n",a.data);
1X l,~(k} ^A                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
y ?#i.Z0tT D                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/%H/\n~|6mp)a:bQ
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0^VkIDc                      break;J X:nj.w b
            }
:H;t9Ky {;s#p         }
+z Y2chZX}6l~|         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                Sv h?9TM)M
    }
!mhc3p9sA0n     GetTop(opnd,opn_tmp);k-h4R N!tjv7M
    DestroyStack(optr);#G6]l znLyd
    DestroyStack(opnd);
f"T a$Ba7G sC     return opn_tmp.data;%{*bY6?t WK D@AO
}
DF2A-q?te
&oY,[pH Aj,D@0H char *killzero(char *res,float result)
$\{M}Kr^]!^ {)|;}/s9h"Bq3nl
    int i;PM'K9Ll+nQ `l
h;D!{,N-J g
    sprintf(res,"%f",result);
%rM9xC'xLw9L+R     i=(int)strlen(res)-1;&l:jsqM;oH9j `
    while(i&&res[i]=='0')
'@.y)IPC6Rz     {
Q$h s:G'VDS w,N q         res[i]='\0';A&w9\&cisB@
        i--;
I3{.fU&C9a"V5N'\     }
L3]Z&MD4y     if(res[i]=='.')
*S"{(o.One8g5[x         res[i]='\0';Eqm}V1T)b S_k
    return res;W%dYu+pN1g;}#L_
}
;q1cZ$L)y !d1i L'cq vM
int main()-?lBfQ!Qj2C.Y
{
2?0a]C1H `     char ch; w,x)}0N;W2B7B7_
    char res[64];
KgN5b}:|p     float result;i$fP;K9bw(AVgD"n
    while(1)
S E3mn ?]$P+]iSb     {
\_%v3z:n'ui         result=compute();
h;HxA+|zIj         printf("\nThe result is:%s\n",killzero(res,result));
6XZW2S3cK         printf("Do you want to continue(y/n)?:") ; @S8?N f
        ch=getch();"p8Pw9JV5^T z
        putchar(ch);
X0o UN E+a H9jg E0T%C         if(ch=='n'||ch=='N')
$F5_ r9Q)b%s/v4DL             break;nb8{;b.OJ _
        else1}"^`"c-l Ps7J
            system("cls");*pV"tAT@1J5C
    }U+K'G3HB"X
    return 0;9@ \UMhp(g D
}[/i][/i][/i][/i][/i][/i]*A@S|-F)F"fk1u;\2ZaQ
Z6C Q#Pc[0F
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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