捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2O[o5^.t\\*{ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3H$t5wM?-b!kI f
/**************表达式计算器************/
M9U5Pf+KJ)jp$C #include <stdio.h>
9a4|k Qw#}XEX #include <stdlib.h>
A8C;hk J #include <string.h>_a1DgN
#include <conio.h>
](pDq^Q #include <malloc.h>
)x&Yio4?m9R ^s
7b"sE/U(l #define STACK_SIZE 100
Pd&v1B$J5y^3T7P #define APPEND_SIZE 10rKZ!X Gs
/u3N^a^I6v
struct SNode{ ^QN/w9i
    float data; /*存放操作数或者计算结果*/X/?1\$^b
    char ch; /*存放运算符*/g/]5{J8V;J(Qxy
}; VG8H.[O G
g9@&gKV&JB3l;?
struct Stack{Z8dR/d O7R
    SNode *top;
TN8e,tU ]iS     SNode *base;/s'@pzPS#d"B y.D#f
    int size;
eU-C'o#L,Ve };
t$q(N_a~ };H7Fu-d(^K
/*栈操作函数*/ y$pi3FI4s)FYt6PO
int InitStack(Stack &S); /*创建栈*/
s/aC#Wo2EE int DestroyStack(Stack &S); /*销毁栈*/
[(b+N0k&A^#l U int ClearStack(Stack &S); /*清空栈*/ cv!t.]b@)I:r8}
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2T Ec.d n;Y7s2_3zn int Push(Stack &S,SNode e); /*将结点e压入栈*/$Y#q,g3V?dm#tQA3Qq
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/6q/d0t:P.Td
6V/o'\$K$t4b7{1ES$x
/*表达式计算器相关函数*/
q!d'Kd#s@v char get_precede(char s,char c); /*判断运算符s和c的优先级*/
.i*ea(eP(j9T&H;|9[ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5?H:W'Nx0o Ri~ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ o,s9{cV
float compute(); /*表达式结算器主函数*/
9GZTV u#e%W)nk char *killzero(float result); /*去掉结果后面的0*/ 'f`.M} k Z
$m2rWG L:i
int InitStack(Stack &S)'|\Z M(B LP#oN
{
&` oL O z     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));}Bm'E,J]/S2YQ A d3hy
    if(S.base==NULL)
*v$zW@%gj     {
T-?)B9uW B5b7`%u         printf("动态分配内存失败!");i L/f(ty.mo%c
        return -1;
V#Tbt+Uh&k     }
1h3LX#`.z3t9W m     S.top=S.base;
8wo yIi_ th9T     S.size=STACK_SIZE;.D-] lh8o;Q
    return 0;
2{ClW}Q7njscf|X }|"V.Ov-?
.XU`#{-Gc
int DestroyStack(Stack &S)
+? _JU*^On {A#SeMSV9a
    free(S.base);
.f6]v)N m;l     return 0;'o Q VAe;noczE
} P+mXf9u)o1m%zc

^+|-N Eh C int ClearStack(Stack &S)
y r ^%x/Y9U:@h {*Z9n3u,WgguC&`c
    S.top=S.base;
;@|6~x`#[s     return 0;
*?9aZK6\4@ J#S aL }
4H8Q3B1{J's H/yD
&wa u"t s&M ]1I Su7H(U int GetTop(Stack S,SNode &e)W*[ i)Q1p+E0Z%b
{5];c}C H;n8B/nr0o^
    if(S.top==S.base)6pO2}e \ c
    { o B D{&L'hO3e"KI
        printf("栈以为空!");
!Kwbt:tx"Klo         return -1;
f)V} z%kX/o0N     }d,{jy4kTv
    e=*(S.top-1);
l b"utCr*S1k7Tf     return 0;b/i Fq ]7A#S;qx5lr
}
V9Jl[ W&MC&l!d*a{
5]+|ub^\ s'g int Push(Stack &S,SNode e)
H!| JrY-\ C {
'e7d m3j#S G2HP+[d     if(S.top-S.base>=S.size) jp_1sg5z;z5J VP
    {
wX5cS_%b$Q7B         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6npsi2l)L+w l
        if(S.base==NULL)Boh)E PB ~
        {
sK:p\ N{;{H             printf("动态分配内存失败!");~._B!nl h*k:W
            return -1;fGT S8d$h v9?Fxo
        }:FOZ |(e^VV|5\O([
        S.top=S.base+S.size;
w&h%G#TJ         S.size+=APPEND_SIZE; |c8f!@$\1^+J,d&S
    }
"wo NOy}6~ i0y     *S.top=e;
l m.rG7M*Y3o-G     S.top++; i$?t9DJ8L-|
    return 0;x7o \Iw
} t%tuP Vdr;FvW

'Fg9z+X ^2E int Pop(Stack &S,SNode &e)O/EZ Lz,u+Y |[
{7P\ Xj e'z!B
    if(S.top==S.base)
Ei'f#L0S t} b-J2|     { DW8J2h*PzZ
        printf("栈为空!");;F5ph ?;S9~E
        return -1;/Ork c`L
    }rn|ls,X6Z c
    e=*(S.top-1);Z |JR:Z1Ssz9j.Z
    S.top--;
-})Z.M6F_;u l2?D O)t7{X     return 0;
J\'M*jr(f }0l0^)OJVI
ax4OW2KXn
char get_precede(char s,char c)
S.@ r?-\+O,H6j FS _ {6i7t3cUe*~j
    switch(s)u&Y(C@ m;a
    {
"~$@E DJ         case '+':                 /Tg/?2j9_)_y
        case '-':6f t:Q*} xk E-dT
             if(c=='+'||c=='-')6Da@4A0g*kGj
                 return '>';'F+c'g8J J0M
             else if(c=='*'||c=='/')
A#zYj2u$F,r                  return '<';5ke$V6n8_0P
             else if(c=='(')
&K%bf)D$zfLLw"c ug.W                  return '<';
:x"V2J4](Vi+JK              else if(c==')')
]-{x,a'VgB^uc                  return '>';-rH?%N;S+N1Z
             else
4U,SW4Q*FZ                  return '>';
)sZ ^?nq(Y)j         case '*':
j[ E]DV|x*{z         case '/':
uk&q#O]$L#w[#G k,@l              if(c=='+'||c=='-')
;hV DPiP:eY cr                  return '>';
c7CX ri!Kr:Tln'b              else if(c=='*'||c=='/')%fk7hlOI ~)r
                 return '>';/N ^'^"GV:Rq
             else if(c=='(')Bo?X_:P*_$d
                 return '<';
{8Fu+| @L.P              else if(c==')')Z8l"c },n*q s0P6V
                 return '>';
xz8D(P!DkS1? z(y              elseB`5a7|H
                 return '>';
cWk7K;XC         case '(':*KynEt}
             if(c=='+'||c=='-')1`K|*OmY-J
                 return '<';&S `"kpF r:D%_
             else if(c=='*'||c=='/')
@+[i,I6t?AEE                  return '<';
*_+E#k Pp6b#ri6x              else if(c=='(')
+w%\({_,{4S3A5oM0|                  return '<';Ty h-n#Q6b;sb$^;z
             else if(c==')')
Cv-Iu6K'Uj                  return '=';
0K6\j3B.PH!R Ng:k/T              else"b{ cP;O$O!Dhe}
                 return 'E';
N:_5Y2F V |@         case ')':D,]TDofS
             if(c=='+'||c=='-')C3Yw(ez?*{X,l
                 return '>';/[qD-C)nC
             else if(c=='*'||c=='/')
Dq1n y%y{l~:VB                  return '>';
v3g WIAD8J{O6y              else if(c=='(')6[Rk9gW7W%X
                 return 'E';
"wN+OX3f              else if(c==')')
S"Fpue C                  return '>';
9kOl+U5N6l&t+T*J              else
-i)AW M9d:\.Y n#o                  return '>';
}4Jk4{ t-sdww9q         case '#':
o(D)r^5~!sl+|Av6S              if(c=='+'||c=='-')
t^h VQl$@p                  return '<';YhEH7C-D^
             else if(c=='*'||c=='/')@X"n$BI\;|[
                 return '<';
(RY[)C {Z:G/DxI"U              else if(c=='(')
O0C&t O HG P/|N                  return '<';
5K&s#C~)C[/N3`              else if(c==')')\ gx K_iu8S |?[
                 return 'E';
I%yDN)u+?gW]              else
$K%j3pbs#Lw{$[8h                  return '=';#l {.@igd
        default:4r$_? xb\ i1}
             break;
;C~R#tS@K$v-E @[     }ERl3n+V:V-l Ro Cg
    return 0;   
4l:E3N/C6X }
c-G+{$]6\ Q:t 0P%\au @'F
int isOpr(char c)X-V:no:ds*b
{
9_q7m$R l#@ D h _#y ]     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')$] `m RA?+V
        return 0;#HS9wF*wyh5dW
    else
*zaS-|V.r_         return 1; i&N3lS4`7ZFA
} l|g9RQaF
}J$V)aj;n|7[
float operate(float x, char opr, float y)W%E$qU t;T,ij
{
u:i `$uPE G     float result;
)t Yk k+}Y#Q     switch (opr)3FH;k8e|v Tw.C
    {K3UCU@k t6k
        case '+': )`6K#fDo8l J Zr
             result = x + y;
"G |nC2}+L2T?Y:X              break;5L2] P#DSi| r
        case '-':
R0zVN K fia[              result = x - y;[;^ sc],m.w^g
             break;i:?9k:V+ri4Tt9mE#ud
        case '*':
%`5Q#Q^J4}              result = x * y;
)y*Mi/^P9NO2Cn              break;Xk6`w`vHz
        case '/': tME ^)J0Z
             if (y == 0)7[ sv.XX3M4EUt;O
             {2@mT v Fe6J4N^
                printf("Divided by zero!\n");
Y'o hn$x @                 return 0;
WL3B8@.zmX              }#d g4{2o wm
             elsew#Xyl'g&D @g
             {?7z-m0E4|1u
                 result = x / y;QX4|7hKu
                 break;0n&y$N1MdVcS0@
             }ofO @%[!JTd ro
       default:
Amo8~J~T%G6m              printf("Bad Input.\n");
.P8S;pN u#M2X p              return 0;
)be'V1_O#v7f }     }g j0_vAM;|s
    return result;
1~2wrfI?e }   
4Om5Bep}N ^!i3e Md'W^v*c$J d
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ @-t"x0t}zPH
{
3P6L)j,~3gkn1G%Sq     Stack optr,opnd;
RTjp%i     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
;A9VqM+q     char c;
3r ?Z[~k     char buf[16];pt1UzUp
    int i=0;
&M,M5FZ/?"d+uv#l     O_%qzUg }
    InitStack(optr); /*用于寄存运算符*/9u(G!Z0p#M#`M
    InitStack(opnd); /*用于寄存操作数和计算结果*/:Hz#?Rg%z*C#F$e
    memset(buf,0,sizeof(buf));
2aj3n&]QVZ     0E,Y6fL K O ?%w
    printf("Enter your expression:");
x4N"i"]H*?7vUY         
Yx:Ps+^v     opr_in.ch='#';Wv5p7Py*g7vJ
    Push(optr,opr_in); /*'#'入栈*/rT9Q}!^S
    GetTop(optr,opr_top);2{2m;]L-~#i2A`
    c=getchar();+mT&l$K#?&U
    while(c!='='||opr_top.ch!='#')
M'nR`2Y5BV V~     {
kyvGM         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/WFdA|)WP
        {
1Jb^p#K             buf[i]=c;\6WHhMw
            i++;
(}g,Z U^M)c             c=getchar();1R0I1f4^!~2T1d }U]o
        }B/q`2pF kK |a7D
        else /*是运算符*/
m{xJGf dJ         {{6vP6n"hko
            buf[i]='\0';
*R:C+Y r9l{             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ ~Z e0] b*KXP
            {/_B[x#a[ t
                 opn_in.data=(float)atof(buf);'s2?T5^ w|~9o
                 Push(opnd,opn_in);
WO8FP@Xt Rt Q                  printf("opnd入栈:[%f]\n",opn_in.data);OQ4x+wu2f9j
                 i=0;
INO6`D\                  memset(buf,0,sizeof(buf));
:x xuEb!UT             }
d"C.O ~$N}%~^b             opr_in.ch=c; SZa&sI3a1u$H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/3j&e)bF jG(gq
            {
2p1e9v3V[u                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
)rc bV0bLq[uF*M$T                      Push(optr,opr_in);4EA:L~6}A{r
                     printf("optr入栈:[%c]\n",opr_in.ch);
@ ?J+g(ugQ2H                      c=getchar();
;p_ANi\;gB                      break;
z4UC4nH)MIa+R                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/uu(f'`!C-D
                     Pop(optr,e);+@I:B5?9| Z
                     printf("optr出栈:去掉括号\n");A3eu_:]K'Li
                     c=getchar();
c4W(l:e8Ki;T                      break;Y(@3TDR*A5Rj0B,h
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/'s$^7L N \b0st
                     Pop(optr,opr_t);\/S's J!g)t
                     printf("optr出栈:[%c]\n",opr_t.ch);
]U M+Do^6WH3T!T                      if(Pop(opnd,b)<0)*_?9f0efM3O$l
                     {4^Xj#Gv br&{w
                         printf("Bad Input!\n");;Hfa(J/\ZdeiN}
                         fflush(stdin);
-lV8nC%P-H3YSR                          return -1;px7Z%J6Ah#o
                     }km'|]&aoI [ ^
                     printf("opnd出栈:[%f]\n",b.data);}N7nq$X(z)P!j$BV`RQ
                     if(Pop(opnd,a)<0)
{3{@p U                      {
.e-s$qK+q n                          printf("Bad Input!\n");
i_cw5IE                          fflush(stdin);G4OR;ur
                         return -1;| GV(|K y
                     }Mlf%Kxf
                     printf("opnd出栈:[%f]\n",a.data);
7ITD9o6\u5[5Ne                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9?4q-D3t S.]l\                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/*g5CP"k%D4dy8A!p
                     printf("结果入栈:[%f]\n",opn_tmp.data);
c$j#qO @u8f5X                      break;
C~?(R!^wd             }
L6e cDZe(ACyWE         }yb5o/e(OQ:Wj:n}]
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                U6J8u5h,`S1m
    }
!Y]W)EV'eO9? R#B     GetTop(opnd,opn_tmp);
%Lu:bP p(d?nI     DestroyStack(optr); v3fZ2Kr\ d
    DestroyStack(opnd);
%qsN8p ^v:X2F%J     return opn_tmp.data;
.Jg%v`cf.c$|8P }
^ }oPK"F A%N
bR fm$~6G#l!s char *killzero(char *res,float result) |4Yf#~h
{
X:_ D"t.u+B"F3~I     int i;Nl:w3k[n T)Tt3f:wPp
/CP.sFN1A? OE9g
    sprintf(res,"%f",result);
@ Yt"gT     i=(int)strlen(res)-1;
7Uuc(X1Q/s-SY-okZV     while(i&&res[i]=='0')
5u,g!a&u4p:N&Aw     {
%[|yoDj sL _2m         res[i]='\0';
X,dkk'Y W\B6yw         i--;
7?4~ H0e9\2x     }
gj@IG"H:b     if(res[i]=='.')
O$]7hpgE~u         res[i]='\0';\Y[K)Z0]"d)q
    return res;)qI X,o+f2f.G
}z;{_$B_ M)x
$d+m*]3S` C ]:F
int main()A*Ujd$]7n c-H
{!j)k8IU5a
    char ch;
,Px#SRi `F!G:r9Q     char res[64];
Ou|${]"m1P     float result;
:M Yg;L#O3Iba/i     while(1)
7u c C$r2O}T+S     {i9kP S Bp2AID3Q ^
        result=compute();
'M!cix"iQr         printf("\nThe result is:%s\n",killzero(res,result));
a1AF-k7e-r         printf("Do you want to continue(y/n)?:") ;
zQ\$_ O,};],gF.?         ch=getch();
:zweVfv&?         putchar(ch);
;R[!R'vm(c         if(ch=='n'||ch=='N')u`t1`t3P9A
            break;$R'\ WB aS
        else
jB[D u)d|.~9l             system("cls"); @v1?w1s5W1~
    }4fG:Yz.\,X
    return 0;1Kr7m`|` Gs8e_
}[/i][/i][/i][/i][/i][/i]
"z;l&iuCV Z$o;i#s/S%Im }] m
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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