捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
d@1T pPgT,F 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
&x*H;\6i(y2O /**************表达式计算器************/
oolf;O h E #include <stdio.h>
6^k-Oi"^r #include <stdlib.h>G@0i%Wii%KW
#include <string.h>
:S9a] ?3{3^ #include <conio.h>
&\_$Khn/No!a%N{ #include <malloc.h>0i gEzW?*U,C
'Dr.v[(t
#define STACK_SIZE 1001z-uR!Z$hF
#define APPEND_SIZE 10
e K4p*LPp -d M&|!DpAq#_h(s
struct SNode{
-w9O[C |Zf     float data; /*存放操作数或者计算结果*/ H;k!s[8@$Z,u
    char ch; /*存放运算符*/&`*B$c c#OL;\ xvxB
};
^.Psm%C7yA y "@.]3FMjj*J
struct Stack{Q m:c7k~%t(]W$];K
    SNode *top;m'TH6}3J*_:bl5m p'a
    SNode *base;
6O*lUTa)C     int size;l4Ny/V6zRn
};
#C7{6g)^-YI
h9u }RC#l#fEk /*栈操作函数*/
"^5h+At _l T3R int InitStack(Stack &S); /*创建栈*/Pq i.l.AB3@A
int DestroyStack(Stack &S); /*销毁栈*/
Z Hr s8N:C int ClearStack(Stack &S); /*清空栈*/y!X"FQ#]8e5c
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
^5\`kS6THC int Push(Stack &S,SNode e); /*将结点e压入栈*/
V,g!d"^6S int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/g+Hn]T(RH
*q*f'BSRo-z6P\0e
/*表达式计算器相关函数*/z1H:I+Q*wYDdyd
char get_precede(char s,char c); /*判断运算符s和c的优先级*/6c8EFz5a7J,q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/5QIo ` oP w:M[
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/8R7z?7`Pzj:e8z6u
float compute(); /*表达式结算器主函数*/
Z'tQ|+u B eS char *killzero(float result); /*去掉结果后面的0*/ {%uQo4H I}-~ ?
&b6Q}G Z.jtb)TR
int InitStack(Stack &S)
8L%x+k U z/`0G? {
4ih Z9W2Xy+w     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
;D CG7] w*VbmC2q     if(S.base==NULL)
9a4a Y%}R]'Q;UK2ZB     {
"DiA\W'B         printf("动态分配内存失败!");'OH4E&A CY
        return -1;
L8E [\ z9`$~     }#i+?'m;v*I E/?c1VDJ
    S.top=S.base;,mq#O)l;r(F
    S.size=STACK_SIZE;
_h5I6Jk)ER,D5y     return 0; g#w*];L]
}W)uaY#h
z7T6@'Zd6]Y||
int DestroyStack(Stack &S)
V`C3`&DgO&\ {
|N4rT0`g     free(S.base);
v.m!wps1t     return 0;JqH} i{Cr a)Z-B T
}
,ph~}o;pU
4Lx:m7N&V9Z!G`M4D int ClearStack(Stack &S)
S7e:L.zHa9`(|Q {nO{&U/mC
    S.top=S.base;
9J:En-B[8kUZ     return 0;
JT2xJM?"H$]} }
.D.Vu(Kv.F @5c
(P/F#]!| gh Yn int GetTop(Stack S,SNode &e)
(F$t4JyA {
]4z%^n:h-htR7W     if(S.top==S.base)'eti&N1X |5J
    {
DRi!o2N;L^         printf("栈以为空!");
:l1q!B[ nK\Q q         return -1;
P/@Hh!U9[     } [G1C9J zv
    e=*(S.top-1);"~Q!?6ve/c[L&s
    return 0;
N:A4WT#o_ } e[!`Nlg2eV rW

'jk#vatj&H0t)E int Push(Stack &S,SNode e)
LB\'jL/a*Uo-L(f \7I {
m1Uhr3H     if(S.top-S.base>=S.size)
R;rcour     {
w`2D7M2{%a%]         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Y]*M$s-[T!P@.W         if(S.base==NULL)
-{4N"mz m_^_         {
u(jF.~i*tg$|OQ             printf("动态分配内存失败!");R.J z&e&f$[`Tk)E
            return -1;
[)r#LR%a         }
*kS-bI0m l4F         S.top=S.base+S.size;#d%E qOWl
        S.size+=APPEND_SIZE;
GYIz }1T     } X Y'Q#B){r
    *S.top=e;M`&D#Sd"n(m
    S.top++;
O~6t}b)ai1hh     return 0;
+x{/U$H^&@c }
-\ `@"kPO
^|f qIfq int Pop(Stack &S,SNode &e)f/Xba~+mJ/}
{
+A'c8^:}\n H8o'd?     if(S.top==S.base)
\ AQ3Bw(W     {
#\@l+WB$V(H%E         printf("栈为空!");zD2|t C1U'C(YO
        return -1;Zd\l Tn5Gt:S o
    }I] C#Rw+Q
    e=*(S.top-1);
%?ftft3[     S.top--; d{BN0S+x"~3P(^
    return 0;1o*?0P8jE^
},D:?(_Wp7VTBI

U!EA4AE$R U/x char get_precede(char s,char c)%c%Z{&z h6{
{
l,O7T4gyK`     switch(s)]0|-K R,x5]
    {
6`0u(k,Y~!}         case '+':                 
,^0deBU oT         case '-':{x h*XN%W@
             if(c=='+'||c=='-')
c1w;QeDX1V;M%RJ                  return '>';8R$agb9p ?*V
             else if(c=='*'||c=='/'))Lb7Z!gU9g
                 return '<';
!xka&XgD$kC              else if(c=='(')3[y@Sv)Qh8LS~z
                 return '<';;SD7|%Vg0]
             else if(c==')')
M?4y.EH\_CSg                  return '>';
~n3r2B7o7j cz              else 8V8|\ LH-L
                 return '>'; U5d e/nX T vM7m
        case '*':PQ#E;ek
        case '/':v[GRTZh\ ?5M
             if(c=='+'||c=='-')
4Nl} r-wN!h[6C                  return '>';
M2`R.D]J mr6g              else if(c=='*'||c=='/')g:PZ n#U4y^
                 return '>';
e k u0jr              else if(c=='(')
Az3I3d[j                  return '<';
8v-B"Y3s8R],Y}9L G%{i              else if(c==')')t XG8zBxs
                 return '>';e*A$ni u;}T%~
             else
#[H(o/H:dcPsK                  return '>'; zV9bPN2?*meH
        case '(':k%?v9Nx;K{ms
             if(c=='+'||c=='-')
L(MMTIg/^                  return '<';
z'B2w%]7Y,F              else if(c=='*'||c=='/')Y0Np h'T
                 return '<';A7c(f0@(Es
             else if(c=='(')
$i/BK8nB E}                  return '<';
D`"@ y:g,h bpez              else if(c==')')UG2D G%x-^B
                 return '=';
)C.G,fsId \%B              else
zhZ*n0Q4V(@ V In                  return 'E';
y] SB+h1` ^ k         case ')':
u#p!L7^0U Z9p              if(c=='+'||c=='-')&x4xElGM9SvHB
                 return '>';X|/L@aog
             else if(c=='*'||c=='/')
'}[YMG o b:g+[                  return '>';
N$[n6Jy;\*|Hv              else if(c=='(')
3X0M:M'W$C1i                  return 'E';
l:P#g/qOZ0u:^ wG+S              else if(c==')')X]8\!x@p
                 return '>';OZ*N!sW+o1_
             else
s ig z0H5DP                  return '>';
y u;Ea` xA         case '#':'QW7Z9X+af4~Q
             if(c=='+'||c=='-') ?XAWF
                 return '<';
]0`[&E mUYX4X              else if(c=='*'||c=='/')
p'r {`1L+m                  return '<';
AH POJ!\D|t xi              else if(c=='(')?4`\~I
                 return '<';
{8o u$w&|:g @              else if(c==')')@,Y3z P gK.nj
                 return 'E';
"N0fb+R/KU              else'Q2P;i D o8oHQ#`.B_ Y
                 return '=';,bVvEC}
        default:
c%x(@}u&D's,] |'P              break;
:F``7oSqV{/N     }.~3E+LpY `+NS
    return 0;    *C'|qiX A
}
s!Vi$U2} M#]{ E
)MDP}^g\9o9H int isOpr(char c)
$K@)BbyTb`Hb:t {
"wHXt|5yE&O:Z_     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
Q AI Xm3i"WZ         return 0;
%EYBh+D     else T~c4L"a6^
        return 1;1gr1{_9@-|Uzr-V%I
}Q(Npb`DUf:H-e

fv m$Ag(ExZ float operate(float x, char opr, float y)N.r!p^0wK8i
{agKPD_rX4o
    float result;
8b:W+n6T(Fc j     switch (opr)%Im.Ni R P1U9q8c
    {3^8n[snN1|0v
        case '+': +Bp6l-p:? G.V n
             result = x + y;
XD,`n'P/L              break;
^$Xf$sM[` U}J         case '-': -b"AJ0i!qI1lH K
             result = x - y;
E:E&hQ8O8])Ko              break;XyCD8Y|w9O1yO
        case '*': ;}!N:t L}4E
             result = x * y;
^(krWc              break;/^.A)I"?,Ux;[M
        case '/':
`uo5g]N3l$ia              if (y == 0)
/e}RTT2r%f              {:["lU-b5M:]:E y]$nz
                printf("Divided by zero!\n"); @#Lv v6KV^
                return 0;
p#| X1e#D4[0F3T              }
l6g0]j2kQ Z0` d1u              else'KNvND+^B/R_
             {
/lB#prym~Y)f ~                  result = x / y;
K;R'o6\g                  break;$}9Mge y#n
             }
/d o5a{,v#w/?#m8x        default:
Rw}7TTq              printf("Bad Input.\n");
&p:Gs2]$_h\ w.yyV              return 0;"u"Co"SMf Qn
    } v&A-Z_CS/e z
    return result;HO2R#W/o
}   
-l(b.l/z8GG]
%^M3fk2rw float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6Ce4bLns {-K$aAwi[y
    Stack optr,opnd;,r+H/WYtWy
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
L^4^e)Wq'n u*m P     char c;
D[ Q;f.Y8O+Z6y     char buf[16];
#P"l])c4U8B7el^     int i=0;
0~ dMy8T0iq5~    
*K#iQL(N     InitStack(optr); /*用于寄存运算符*/
.w"n a8?&V%uPo5x:_     InitStack(opnd); /*用于寄存操作数和计算结果*/
%\5y-~V*@9VO^7`     memset(buf,0,sizeof(buf));'m0ir Q8{
    jz+j;r`*?E
    printf("Enter your expression:");
j|+|I,}.ry&cYD         /Z_N`$c&d
    opr_in.ch='#';
#yll3UQCq     Push(optr,opr_in); /*'#'入栈*/7O ^c^I!@[
    GetTop(optr,opr_top);Y?*lsg+h.tu
    c=getchar();#t:f1ALbx
    while(c!='='||opr_top.ch!='#')(z$`ZD c BX)w
    {
B,wUca5QX         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/I%k+tV:SM
        {
`Wm_ ^ [}R             buf[i]=c;
Ro&OgG+Z?s;a             i++;H;`Kz)Y
            c=getchar();,W]%ab#u%K'i
        },qUB.@F7~(T4e
        else /*是运算符*/ j*wX6ET
        {
~&^ E*w~:p             buf[i]='\0';
'@W6k3Mh)S M             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
L t|T"vpc7yv             {x!jIW&u9pt0P&AO
                 opn_in.data=(float)atof(buf);},]#w/MK7mlj,U"p
                 Push(opnd,opn_in);E"kW/~ }
                 printf("opnd入栈:[%f]\n",opn_in.data);
`+s7S,R p.`$S                  i=0;
$C&F8r+h$A*L7M:V;u                  memset(buf,0,sizeof(buf)); K%y:l*`:xAY |
            }
~$}/s3_C ic             opr_in.ch=c;-fqf c ]o_O$\R H
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
d6B;?'H0ci \             {
? I2v*?'r+y                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ ] X%u3^@ k7Fae
                     Push(optr,opr_in);S"~-{Pbv%i,}zl
                     printf("optr入栈:[%c]\n",opr_in.ch); ]}"RA1Mao+U/y O#[
                     c=getchar();
:T{e&J9n;ym                      break;B$i5V4MX2t
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1p|nk"n w                      Pop(optr,e);5i2k2O+Em'j
                     printf("optr出栈:去掉括号\n");MW\.I+^_H1p[
                     c=getchar();
lO:Bn:w6]d+N,u$W                      break;9\ztY5eO(s!bX:x
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/njYVs$DZ7r Xp~
                     Pop(optr,opr_t);M @Ko7L K)|gH!L
                     printf("optr出栈:[%c]\n",opr_t.ch);
3@7ZH%mW                      if(Pop(opnd,b)<0)
vE%W#WJm8g7Rx                      {
:Xe,N j7A_SF                          printf("Bad Input!\n");
jd9Sw*E ?E                          fflush(stdin);8D6W_ O'E;QjA}
                         return -1;
}U1H/@)] eDwZcx                      }
y0R s J-B(y4Xl                      printf("opnd出栈:[%f]\n",b.data);*m N,Qa#HEU
                     if(Pop(opnd,a)<0)
A%S QY^                      {
[2\7I*Sfx Tr                          printf("Bad Input!\n");
Y"x?5T9efds%q:W&c                          fflush(stdin);
0P S0Q#JHs4h9p                          return -1;/K8BD Gh{ M2jB
                     }sX$E%Kg
                     printf("opnd出栈:[%f]\n",a.data);
#E"p/o7V(M                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+v/s'Qu'g!OL                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0}r*v3hh6Aw%u\                      printf("结果入栈:[%f]\n",opn_tmp.data);
~vccc|;j                      break;
{Wg0oS2c?@E             }
S+gk? p6C         }]%rZ m*~"K K
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ,N+t0VB?P s]
    }U-Y-X4w Bgo
    GetTop(opnd,opn_tmp);
^dd.c&q;|&}6w     DestroyStack(optr);G1RV,S-C|*H!\x
    DestroyStack(opnd);
7rm0~3Q%r3U9F     return opn_tmp.data;
J,E0` D jJo8b }
j-t-Y+j1q-o#^
1L/w)` YeI#q char *killzero(char *res,float result)
`)`c5AV*Yg(thF {-I#[^Uv
    int i;
Jm*mz$xs X4~2i?F
    sprintf(res,"%f",result);
TwC?-a;iE l/s     i=(int)strlen(res)-1;
;`yfMw[ [     while(i&&res[i]=='0')
(o~`T-K3c4s     {J^k _.h+FT{5nTs2n
        res[i]='\0';-E+CO7ug
        i--;
S5yi+Q({E qN D X     }MkE[ H6M z k
    if(res[i]=='.') r2v!GCj?`
        res[i]='\0';
x#wwD{;U!Z     return res;
Y`-j5\.C._(a$NM }
x%hFZ s%t/n9}y!i
Vi9uY{ int main()[}9R7k(@Nd
{az2]8l&RO^S
    char ch;G+Ld%| ahE|]6~
    char res[64];^/Ky"}N
    float result;
A@EM)v     while(1)5fP$Ftm?
    {
K;h.Z#B8MLk         result=compute();
Q$K ju&E ^H"@         printf("\nThe result is:%s\n",killzero(res,result));X\6jn-Z
        printf("Do you want to continue(y/n)?:") ;
:a _)b4X$?cg(Z         ch=getch();
,@.x/z5Z"t/I4p*z[         putchar(ch);jo3au r.A$YI
        if(ch=='n'||ch=='N')PI(B-aFCw;[0T
            break;rD,?:b W$yLr `4T
        else
;qlV6N4mE             system("cls");
9TH@aXRqr     }0?)x,?1ztk8_hZ ~ L
    return 0;
'zt;eT @ tL:r }[/i][/i][/i][/i][/i][/i]
X*[dJG!H$\LY[ ;bE8y W P/Bs*J%e`{
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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