捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.^lSYGv$cz"m @
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/s(?U U,W
/**************表达式计算器************/
X@qupk9m&V:FF0T #include <stdio.h>)h#A(N%p%J&u(]
#include <stdlib.h>v [,p IZ8c\-`
#include <string.h>:c3{S@H0_V
#include <conio.h>
_^B(zew.A-x #include <malloc.h>
ZLWE i
}R3x Zdl #define STACK_SIZE 100*`ccCL,` ~
#define APPEND_SIZE 10A5{ C#n!W:?#Q
?G3W4ioM
struct SNode{
#O{/WNY!U,Flb8C5~     float data; /*存放操作数或者计算结果*/
3kKU+u~PQ C6vT:a P     char ch; /*存放运算符*/7f D'Z)f] a:M0b
};
e x7gY!N(c V ~ 7][Xq'o'v?"ro
struct Stack{cPs+hT#{v!e w
    SNode *top;
8Q sNMI tK     SNode *base;
.~Yx9i'D     int size;
K;z~&F3E };
7Pe3X7TXKI 9hO*{9Ps_t!N
/*栈操作函数*/
8~Z)o1\._F] int InitStack(Stack &S); /*创建栈*/$kfUe`wZ2w
int DestroyStack(Stack &S); /*销毁栈*/dW#_ iNj Pof
int ClearStack(Stack &S); /*清空栈*/^9k P,h j FK
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/k1}(C"r b.t
int Push(Stack &S,SNode e); /*将结点e压入栈*/
Z,v |q7l int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/R:}!B#K-z ^?

8_#f5^$X2BvB^3K*a /*表达式计算器相关函数*//I&H pF%] }:`Wp8s \
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
p)FJ_8@0V int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/g,U U B7m3e&\
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
Y6P&s:b3sFC0u6@ float compute(); /*表达式结算器主函数*/8Dn0g Sk4{0CU!i(Q
char *killzero(float result); /*去掉结果后面的0*/
w1AsPnO3E5I |:C
Y_-zc k!h`NP int InitStack(Stack &S) [4Hm*x:Y@4D
{
;GFD(M~p{O K     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5xn"yJ;i
    if(S.base==NULL)
.bd!reBHu,A     {D.`;F'@@5O
        printf("动态分配内存失败!");
+Q(S4]6q%H4_ttq8w         return -1;8m]E\k#Y"IP5B
    }9dq^8ol/[W.PW:w
    S.top=S.base;.P2Ad'Y7@ zA
    S.size=STACK_SIZE;W;y s&EF"u(PDA
    return 0;+\7\G&\*t%geMd
}9p}Ja;|
g*F;k `P3nNL|:xl
int DestroyStack(Stack &S)
7z2D Y;}(scQ&O&p)o^t {5y'P"MD;Ni
    free(S.base);7ta3|P,@
    return 0;
,~.a4}2V SH } Q"~aV1R{
z&J;_K:V
int ClearStack(Stack &S)
w,O|7JrK([9t \j {
e;c'zVa8U-j?@     S.top=S.base;#Xi!XN?ZF#]L
    return 0;#{4I(jQ XHvV
},j b%e/e'F/_ d(Y%bF
0x,| n}!Zd#i)` W*@
int GetTop(Stack S,SNode &e)'Q.i H9~u
{{1Q:\~9m
    if(S.top==S.base)
x$U ?w#w H{"T     {
!? I2t-Z'D         printf("栈以为空!");"q1@W&M z
        return -1;t(c9i C g1DC
    }
,i_*h n;E#Y3u${^.E]3b1T     e=*(S.top-1);%E1y?&~|5}*kS
    return 0;
t~"[0A0Q| } qH2l8zK9nm p,j
#A vgv Z?},M
int Push(Stack &S,SNode e)
5v4@BzuH {-U4C,a(WL+n
    if(S.top-S.base>=S.size) gefx0Y:Cq
    {
9o|Il%}!k6wLxW         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));)cg6F)c#dC
        if(S.base==NULL)
$b?7v["T2AFX         {9LM1YxG#t.AjM1KR
            printf("动态分配内存失败!");5uj@0x`R)??
            return -1;
\ q b({ zWm?-o6@ `t         }
*o9VmVq-cE9W3|8O         S.top=S.base+S.size;
/g3oO2_ d&E,S         S.size+=APPEND_SIZE;
t;~Dp)pK.p!T{     }
[Y%G$^-Yun     *S.top=e;
w+v:v i0aA P     S.top++;
#ee'QD/k     return 0;
:U9V`J-M d }
P9Q"]b!`j!\s [2o
.b#MOr#u2{ int Pop(Stack &S,SNode &e)[2T-W-PY/{&iW~
{0o%j)H5ye,Q*`Sn
    if(S.top==S.base)
TW4W/Q,P&lJ1WCV     {3A:O2y4y~c
        printf("栈为空!");
Zi'mw9}x         return -1;3S7p$o OEm\^
    }
:@,z3D$^5u?|4T     e=*(S.top-1);
,O{M P ?E$PT9h     S.top--;.Uj-vj%J:x
    return 0;
%C NTWx(H }MN6{!t[5]B

Gl$`Z$B8C char get_precede(char s,char c)
N'dRjG9d {
/f_m |dw,B8]1V9T|     switch(s)
BBA x)L1w#u"eH5q     {!O4w9?!f g)hjdr
        case '+':                 
Nv w,p.rY5^         case '-':
/e3r(lw| VaKe              if(c=='+'||c=='-')
S2H9Tq,F b                  return '>';
u!]ou7?-K              else if(c=='*'||c=='/')
8F!FZ&Pu-z*o H\ k                  return '<';
'x.s0Lb7L)\2n_\              else if(c=='(')
I-h7w^-NNku                  return '<';
0TH_ox              else if(c==')')
:I E8T8pb Z4yY[                  return '>';
7\#\'v6[#C rP              else
"C.a+B&yE*u_(qCZz p                  return '>';
$h[\Dc3M         case '*':^s\)] m1~c
        case '/':7MPWMd&Q(lx-Y
             if(c=='+'||c=='-')i4gU%aQO$WkZNz
                 return '>';
Hcw,en!_.uD              else if(c=='*'||c=='/')S+U%U;Fy$V*\K:v
                 return '>';6d*[%bI up-e
             else if(c=='(')b0Jv'G%J7I'ea
                 return '<';
5y:QWN1?:ny)B              else if(c==')')
Ajp;}.d2\Y                  return '>'; j,`7f"@d w
             else:uT9?SCxyzmk
                 return '>';
B1TBGTI*Q         case '(':QP7P!J5s
             if(c=='+'||c=='-')gI}B/hO#B(W
                 return '<';
NC c{D_v              else if(c=='*'||c=='/')
4w pmu(v9mP.G B5b                  return '<';
zbpN7C              else if(c=='(')
$W0`3u5P$Wv                  return '<';[i,l0Z3IO/J6s|3J
             else if(c==')')&LU+X1J6[k6o7l |
                 return '=';
?jC{CASu              else"|OD#vaEK
                 return 'E';
5lxh*~{#u         case ')':3\4r-['wn0y @]2n
             if(c=='+'||c=='-')#S@^sH Y TZ A
                 return '>';
A:?!y5V] n'O4HS              else if(c=='*'||c=='/')
e XndwUH1r+Bi                  return '>';
j mquY              else if(c=='(')l-Zi|P
                 return 'E';H ?m(~m9P9X.l
             else if(c==')')
/wRn}6Y:f"o                  return '>';
7~*sB*YXZ              else4q4~R+cOw
                 return '>';
7ldf$\A1wi \         case '#':E K7tl6E*N@/T.K
             if(c=='+'||c=='-')g2Q I&i&H7g.gTsi
                 return '<';
.V ^ Jl5I4U(a              else if(c=='*'||c=='/')NL!aug#e0a1P
                 return '<';
V&K#s S)EvzSt              else if(c=='(')`9WHP:{ J [(s:n
                 return '<';
g ~e.s/_-X CsX(z              else if(c==')')
'k%hL cr];a^|!q                  return 'E';![d,X~3u
             else|o&aS,ZS
                 return '=';m%f-\b1u(J8Q
        default:#@7FWvMa-c"e,W
             break;
J'Y"]2~3z^PV     }([6{(Xqs/MLQ
    return 0;    mp:G)X s.J
}7ASb/|%YMU

@Ps$pA p5L"` int isOpr(char c)+Nb }e e ^U jL U*XQ
{_/M0H"~Y/Z
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')KL4V:t,im1|
        return 0;;T!T)l)qx ^Y
    else
a U7lm_}         return 1;w"D8Ph)[)K
}
{q h|5AkN
U/U)I4On B float operate(float x, char opr, float y)
#O h"@ ZV }x {wgA6w5D y L|0z
    float result;
C2H.c+oP     switch (opr)
T/BR"e KO A     {1qV5jK)X y_jA"Js
        case '+': +Y4ut!v pa/U;J
             result = x + y;
$W5u^3U#}'Wd.f%rFP/R              break;
u^"u fU:Y4~;v         case '-':
?7]w|&@?              result = x - y;
5uD E:ia$X _              break; U9?0b5k!t1R?LZ
        case '*': ,F v'C6HT)O c
             result = x * y;
.r,a!qg5L\K              break;
Et9g pX3v:W!x6m         case '/':
-bP N(_ v.\{              if (y == 0)7Xvq3JcY
             {9@bWgT7}V.j
                printf("Divided by zero!\n");(} F)O.\v:VW
                return 0;hiCqM
             }
IdYhRu&VaX.j              else
vW cF&dr              {H]c4hhw]Qaf
                 result = x / y;
v5hOl{Y~:Z6G                  break;
`1l xT)^              }
:d0D!HD |Q!`.h2Y-O        default:
4T?J,w,j(py6p:{              printf("Bad Input.\n"); R(Y5b5R&R
             return 0;,N m2h+T"e)~
    } F&P^4_ o3dJ+|ZP
    return result;
)x g A/i3E qp }    !W,]!w.O\rH

N*i |I4z%{,e L3DNb float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1i e+M~_Q%[`
{jD8YhZV7p!kSX?
    Stack optr,opnd;+C.d'R D.a8g&H)M~'Xi
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;&r4kZ~g:{
    char c;ZL pe {+T$reo
    char buf[16];
|1zSKF l s     int i=0; O{ wUwwNY!R
    9?;fp,^7Ba
    InitStack(optr); /*用于寄存运算符*/
:A D&O9m6j     InitStack(opnd); /*用于寄存操作数和计算结果*/
1V| a(}} a*L'sv     memset(buf,0,sizeof(buf));u9O?RrQ{8s
   
gY&o7Y3t*e     printf("Enter your expression:");iR$Zf#e1Q
        
?V/|{T,vW^     opr_in.ch='#';
?LuO8n,BNT     Push(optr,opr_in); /*'#'入栈*/lR(Zm nu
    GetTop(optr,opr_top); ~J7V`N.^?f S
    c=getchar();;vH}BrM7P
    while(c!='='||opr_top.ch!='#')`^3e{+Ckg3|WMt
    {
tZ5aZ0~U"i/d iT         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9I%pj@4n5O6`9S#bn
        {
kB?t-n7M0Cy             buf[i]=c;*fOaD/o
            i++;
c)BPa;w$rU             c=getchar();
oh!L0L"p[ m \ v         }9}O&F5]P!g w"L
        else /*是运算符*/
#DV8?6CTG4S!Z1v-V)y4T         {b\@v,a4N U~l
            buf[i]='\0';
e#O T)vKG6]             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/J.AF9F(jH7QQ)de%n
            {
4~-w|5Xz0A                  opn_in.data=(float)atof(buf);3B9F3K1a/l]*|
                 Push(opnd,opn_in); cwA[,i/J
                 printf("opnd入栈:[%f]\n",opn_in.data);
b _9v+Re` L7i6\m|                  i=0;
5dh{6{"U.S ?8?l6~                  memset(buf,0,sizeof(buf));e%]wt$`2N4n:N
            }/} r?q9x1Vxp
            opr_in.ch=c;
9K2pj*?1X%M             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
U$M.Mfl6t u             {
9]-iU{i,v"Ud/z                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
ELO*J d9vipc                      Push(optr,opr_in);s i&Mf7T)I)U$]K
                     printf("optr入栈:[%c]\n",opr_in.ch);5j/c'\u ?*C-@
                     c=getchar();
#uB(f;}|T U                      break;k-qw,n/[
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
@nlo%Y_ e"`7h+M'{                      Pop(optr,e);
9}$J9DiX.e"A                      printf("optr出栈:去掉括号\n");
/e'oP2y-K7F+S                      c=getchar();
PObI9@%Y V                      break;$d'o'h*N&q6J)vcJ"K
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
X7K3lQ;f                      Pop(optr,opr_t);
7d m [iw                      printf("optr出栈:[%c]\n",opr_t.ch);
7}?}bP                      if(Pop(opnd,b)<0)Wl:vx5EP
                     {I3Y'I4E;`&D-\$I
                         printf("Bad Input!\n");
}+N#C8i}M$}r0Y;?                          fflush(stdin);3r0Vb(~5i t6z_
                         return -1;
)DG}^d0w^n I z                      }3@ c;O7z'd h
                     printf("opnd出栈:[%f]\n",b.data);Z5W`-i-m x
                     if(Pop(opnd,a)<0)G e Yre~$Z+t @r
                     {BR"Eb:T
                         printf("Bad Input!\n");~2V Q8L,r
                         fflush(stdin);
1].DX i"s}8\                          return -1;2Wp6O-QC!P-KnD1D$N/e
                     } @$Wn'h`SR
                     printf("opnd出栈:[%f]\n",a.data);
x D,d$h(d                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*//L3A_2}2N
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
gXk/NHqu$H d                      printf("结果入栈:[%f]\n",opn_tmp.data);
Ky k'vL8J!Y                      break;f Ql%bX&e
            }
*|w XQ9xqVj         }
l c-^5Ue9Bi}2r         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                9Hg)["u L#ny
    }r8ZS gVd
    GetTop(opnd,opn_tmp); aAUR2uU
    DestroyStack(optr);
6w'K}T~.hd^     DestroyStack(opnd);
O)j8c No+r7~c.y     return opn_tmp.data;1Xj;Y%G? cS yg ^7Y
}
,i2r9}!R1Bz
;|%g6{5n[Eu1g$vc ? char *killzero(char *res,float result)
tQ\Dz| { v+m$B!_-f dl0G L
    int i; QVTI:K)u dF

vZ1x%gD4O     sprintf(res,"%f",result);
]&O+Af)obso:]     i=(int)strlen(res)-1;9O.G~a"B)j
    while(i&&res[i]=='0')
0M{Bz VgdB/?     {
m6XIWf1yB3he         res[i]='\0'; qG M#dY7g[
        i--; I l5`b%j8iG6a,i
    }
*|&KV'L{     if(res[i]=='.')#|9]R U0FR,c
        res[i]='\0';
m7?)C X?3Y     return res;2Vh't~sEQ
}
4f1SK(Z"VB_ R;r ;]1uml6rN6N/B CO N
int main()0~ @ OLzu!N
{
#V1V8f8xCX%W4y     char ch;
lv.}L ]9EI-Y{     char res[64];
3s)D)p q lK1Il     float result;
B(\'cij"O     while(1)
'B)SvZ ^-z_k#r     {
ntC+m3IFfz o?         result=compute();/VBk3gM'u+In
        printf("\nThe result is:%s\n",killzero(res,result));3`-V"{!GYq)X0X/[ t0O0y
        printf("Do you want to continue(y/n)?:") ;
Q!V#HTJJSU~         ch=getch();c8T8LzY$K]
        putchar(ch);
@!mQc8sm!^-Ln Q         if(ch=='n'||ch=='N')
{n?u{ I$NW&t/R yI             break;xzvL5gL
        else
p!z+_ F)p Q9b%c:k             system("cls");$w"o*C]ks7H5g9\
    }'B(^3])K!c^
    return 0;"^.}w} QyA| [/T
}[/i][/i][/i][/i][/i][/i]
l0~FlZ#Dc L K~y
)N%Q(}6w^OaTI [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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