捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.&j!H[ l5c7d1j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=f"w[c#PHZW
/**************表达式计算器************/'wud`$eD+Dx%r9?
#include <stdio.h>p v@Upz-~.r
#include <stdlib.h>mJrc?
#include <string.h>`!vob#]6Y
#include <conio.h>
'R&L ~,P3vm4v3p #include <malloc.h>pt!C.q)pZN{
(I v nd fn^
#define STACK_SIZE 100
Q n&Ed&bo;tm #define APPEND_SIZE 10
UtI.}f .^:ub^z Ua4D
struct SNode{mD}(@s
    float data; /*存放操作数或者计算结果*/%a*U+D!J,}l*vAh
    char ch; /*存放运算符*/xGpH-|#T}
};
/F/orLa Q9U9u? ]nZb:n"W
struct Stack{
0G*|/ie I.B     SNode *top;
b&Dmz`_$T/_     SNode *base;Xa6\%@k6sr/r @3j?:?
    int size;
'w(a#~$R\.Z8Cw };
PBx Jq,u9EL
)J$u#[au.\_A7f /*栈操作函数*/
6Ub^s'G_ int InitStack(Stack &S); /*创建栈*/
S.tvKI3DN int DestroyStack(Stack &S); /*销毁栈*/(`a[-c*lc ^RHrQa
int ClearStack(Stack &S); /*清空栈*/rVY7R ^ gF
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/X&[I |?/H:z6{ Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/)^d`.O:A
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
,@'t$e.?e'i;[0J~
6JP7~W6u.b /*表达式计算器相关函数*/
)s4L$VW?2t char get_precede(char s,char c); /*判断运算符s和c的优先级*/w1eXo6e }:L
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2w fK1l7@C BL
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/i"w5p3u9m7s/f.ine|1S
float compute(); /*表达式结算器主函数*/&y7K&E6{wc-f
char *killzero(float result); /*去掉结果后面的0*/
BuP7Uuh`+R Y A9n|7Cj3is x&j
int InitStack(Stack &S)
/Sk_6GwCTn? {
,o s'|!b ^.eOF     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
.T `q0}MlBg     if(S.base==NULL) l Vq0@%IHif
    {2ijs`O LQ
        printf("动态分配内存失败!");
JMjVE2q+~c         return -1;m4D2lEc1m
    }
2m(q5d#e#r.`*n2Js     S.top=S.base;
J&l? r#V!PCK     S.size=STACK_SIZE;
)f2Rd?+l |~     return 0; dy^t$`1iR@
}
`F5w7e MZka +puc~D,S%Z9P
int DestroyStack(Stack &S)
+Tb,y,n {XD'H+N {
7G)fA u$C[d3M `     free(S.base);
(I,l6? a1r~R@     return 0;I5?$O+N3XUx
})Q(O#w:Efs gf
S5\_+Qt7h II
int ClearStack(Stack &S)cW h1Z$hdB0~I
{ fe|Qr8OH\S;Ch
    S.top=S.base;
-n*TP{ @;T)vB `     return 0;
},K5rA,]E?Z }6Kw \8goc

O#r+s/bO int GetTop(Stack S,SNode &e)i Y,r_1IN y G@
{
{7m*[6Sx rD*B2r     if(S.top==S.base)
BJ!d;Nc,q     {
/T `c G8?         printf("栈以为空!");] l)kn |p3e`;J}
        return -1;YJy6z8D2h"Kr
    }
Ig_D*?FXm     e=*(S.top-1);
$VK6v/\`S7S-@MN"b     return 0;}X UO%YL
}M+^`&qp.b

.M5N"wY C@O&PLe2J int Push(Stack &S,SNode e) T#S-?^t?
{:b w+aC ^
    if(S.top-S.base>=S.size)B K1n r@ u5X S y
    {$y DC |(f6U ~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
:Yh"`SO         if(S.base==NULL)G J9lX:J7c^/Y
        {
y$`#ClS)[ M             printf("动态分配内存失败!");d V"_+p0CNI["st
            return -1;
D G7Vc+?*X         }
3]6vi0?)^oP         S.top=S.base+S.size;
u;S$u3ce/i4q(D:k         S.size+=APPEND_SIZE;
4yDr E2o:T     }@y;Pn+Z'R(m_:b E?
    *S.top=e;
T;P!p!Y^$A1w     S.top++; Z d'u@&^w"r)B3G;uc
    return 0;u`4f@F$e%x
}A/}|"aL ]
,L ]|~1TaV9Hx
int Pop(Stack &S,SNode &e)$_gfQ)xNJ`
{
+`*H |k3T Awu     if(S.top==S.base)
Fx%Un jZ-O#U     {/Q4M'a(a#lL*JE
        printf("栈为空!");
#bIH U.g         return -1;9mGTRT`J2s
    }
2w6t'R,]$mi     e=*(S.top-1);
1DJ9_O2E-l:y^4R%e[     S.top--;
)QG%R0HEb0K1[8A     return 0;|#r`fP6v TIU
}
E&UE{&f3u%h9\R 0qJ'D-yX \
char get_precede(char s,char c)
R*Y%M:J6WojXl {
9^0ME'h{O     switch(s)l#NqM$MF
    {
#tr^2H:^G|5p         case '+':                 
Lc M!O \         case '-':k0r8sB"IQ
             if(c=='+'||c=='-')
#Wb j3y e)h                  return '>';A,?} MpQ
             else if(c=='*'||c=='/')M B*Jm9g|Z8TG
                 return '<';
'zR7\x;w7p Q              else if(c=='(')
,P~oKW3z                  return '<';2V"dx(W9t)iD"R+G
             else if(c==')')
\&ryqC4['M$}                  return '>';
)KZ2`3b9x?h'yw              else @l_"S}+S8Z_&u:zw
                 return '>';:?$^(@;w;S
        case '*':t P6]9gl4PZc5B
        case '/':pN-z`3@-H
             if(c=='+'||c=='-')
Ob$Ud+mu QKFE%]                  return '>';
$A2a.@ h9|9@i              else if(c=='*'||c=='/')
J"p7YK.xq                  return '>';9ljP%C#[
             else if(c=='(')8aa@z8g)S+E
                 return '<';
w({|ywtb+i              else if(c==')')
z+| X/_+^a9P                  return '>';
.C{"h`!~*h              elsev\G#qk8Q
                 return '>';4V[l ^}*WL
        case '(':zKP9sB5?4o/D
             if(c=='+'||c=='-')
?6]1\.?tdMGrXfg                  return '<';M-z\env
             else if(c=='*'||c=='/')p)BQXO&_
                 return '<';
zwD} IS?6?              else if(c=='(')'qRC2f9}MK:{S
                 return '<';cC3K ` T+o.f(Y9M
             else if(c==')')
b8yF'A k'_                  return '=';
7vu!ldYL_              else
^z9IE~I\W-bj t                  return 'E';
[`J5C9E\U         case ')':+?_Dc#g*t
             if(c=='+'||c=='-')
[4[X#LB*M0YDt-|                  return '>';
'u#RIi!D;Ai+a              else if(c=='*'||c=='/')j CnbQ\S3ZNKe
                 return '>';X8v#Xx v_h
             else if(c=='(')
*_]ZufQ                  return 'E';j-nrf9|CY
             else if(c==')')
5p d]5L;F,f1`                  return '>';!E!s F_su9|
             else
*^&B*mL(h1|                  return '>';
IA!a}#R/c         case '#':
IUe5?~"D:u,L^*wH              if(c=='+'||c=='-')
m'R2sI,H `F0oM                  return '<';9C+?7OB/|V;y0h"c)W
             else if(c=='*'||c=='/')cP Y.n'Z
                 return '<';9as%S$U%n [ J
             else if(c=='(')
w U*F7s9{T zXA                  return '<'; Bt5m$i]!j
             else if(c==')')
ON F7s b7q"J lNz                  return 'E';T3j4Z3b)C+L5se
             elsex|``$h'_[/]S@
                 return '=';
q2y_2A8a         default:
+~WliY1fc|              break;
zR0b@r8h1z y A     }
-A!miY#]     return 0;    9J(ydW H
}1G0ts#yz%^9_R/?
#Wh`4f!_ qb9@L
int isOpr(char c)bq5a`6kR;` q
{#p IQ v5GD/~R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')"n3g!_F8cW3m?Hcsl [
        return 0;
6E or:XU U1}9t,Yc:PU     else
l b4YTF7hL+a         return 1;.RBc%?(h n
}
i@/Ft4B2nD {/F #J_%YQ p:U0]^
float operate(float x, char opr, float y)Ab,O'_V
{
I`3CFE UEY#bp     float result;
)Ecj])yNN     switch (opr)0{Dm\,j)E4Xc9c$~5F
    {
d]hEc xYpd         case '+':
o)G0u&P;c)Jq              result = x + y;
0K6eZX ]7l1W M `4k              break;t$Id2])pek
        case '-': %fe/[DM4]\
             result = x - y;
U {`p1xs              break;
q!`KV5C]G'e2W \         case '*':
Y-l fk,vP!n(Z2` ]t              result = x * y;
e q6CRJ              break;7R4{9uk9r
        case '/': d?4x+H2^2T^ y2xg
             if (y == 0) j ^7BT,h4q2lj
             {jJ:{+j5aF
                printf("Divided by zero!\n");
^dW%d4m^k                 return 0;
#j4P"zo$h@-Z2v+y              }8[ nv0e3X5gI;R&g
             else.I/Yw2h5YZOr
             {7I!HGO/JO-y\
                 result = x / y;
n!d%}l,X6R'J%R                  break;
YOGA'`              }
1o:h Z7N#e%p        default:
WM$q#?;Z0C8T/p~-Sn)?;U              printf("Bad Input.\n"); +sDA~?9Ut'K
             return 0;7@.Q)fl"|1O
    }r/``#wO wsz1f/X
    return result;
#s6u;|-jJ*v#Eo+c!D }   
7e}sS Dd
3S o}n8_.U float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/b0a8p a)^5Y
{$k.Qy$V,np
    Stack optr,opnd;;E*ppf+w'|-~)w1ZN
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
^:ebK h*a L d U     char c; _pf2o;o$|4N I V:Xe
    char buf[16]; L/PIG#q~+Y
    int i=0;
y&Y y&v E$m:_8chC    
M*I"WP KY2Q Mu Aw     InitStack(optr); /*用于寄存运算符*/
3S8N*R&RyL,EHv x)o\     InitStack(opnd); /*用于寄存操作数和计算结果*/
['B4hB3?;M;g7^     memset(buf,0,sizeof(buf));;MV\b2~
    w Ry8m3_rR
    printf("Enter your expression:");
m`2_Ol,|,s ]mdz$I         'RS#PwM*JN*?U
    opr_in.ch='#';
Pnq/pdHa     Push(optr,opr_in); /*'#'入栈*/esMXV3j(N2]
    GetTop(optr,opr_top);
U{+B&[7g     c=getchar();_\5Y3V|#xI-Lw
    while(c!='='||opr_top.ch!='#')L M!}-b2tZ
    {
y2?P$Zy(qW         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/&m9H2IT'oD2dfL
        {n | Ah6|)a7x Ig$iZ
            buf[i]=c;
#`|tD__ cj,n8`             i++; Ag(q })k9x-o9_
            c=getchar();E%Hf Tb [9ZlS&y
        }
+otJ(v8n3q         else /*是运算符*/ M,kHi2B5^6C
        {+i)_+By'O$MR
            buf[i]='\0';r~ a0ky Y^
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
f'{{6V I:tx!j             {bbIjX^!S+Px
                 opn_in.data=(float)atof(buf);&u#dU(E'YGD De;S
                 Push(opnd,opn_in);;G]}/cY5G,J4N
                 printf("opnd入栈:[%f]\n",opn_in.data);*QKs'W]7jex6`
                 i=0;
q f}q#H$B-p                  memset(buf,0,sizeof(buf));
B,tXgt}w1dlB!V8s             }
Ku_fN%OO,l;h ^%W             opr_in.ch=c;
hs&fw)C [ WTk             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4aS:b6ZRD ~9O4U
            {*q-~g0l:M*~*[E%J/@%D
                case '<': /*优先级小于栈顶结点,则运算符入栈*/cSJ&WyU^-S
                     Push(optr,opr_in);
~$OYQ7i&Nm                      printf("optr入栈:[%c]\n",opr_in.ch);
F\w R|_];Q                      c=getchar();-YnTLEqaH
                     break;
9Y/p~_}/bc5K m.Z                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7|3?-}9Z$]e
                     Pop(optr,e);
f rw_9_;f qk^h9o$s                      printf("optr出栈:去掉括号\n"); D6@5E.{4V,u U!UQ9v
                     c=getchar();` CbA+Q lMaB7p
                     break;
tJ` }/b                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/@7S1Du-[`9s
                     Pop(optr,opr_t);W+Db+P!q o"qT
                     printf("optr出栈:[%c]\n",opr_t.ch);
+Gg*CT p                      if(Pop(opnd,b)<0)rp}Io$eD'pu"Z5\
                     {
,J^mJ3}'l                          printf("Bad Input!\n");U*ub3ad.K
                         fflush(stdin);
G]y*tg1_9L                          return -1;
-mPyKk$N1t F                      }2[4Dc~~'t
                     printf("opnd出栈:[%f]\n",b.data);_#I*|j6s+gsW0L
                     if(Pop(opnd,a)<0)
(b(K0T'P"v:n                      {[ CoyS(C?R
                         printf("Bad Input!\n");
mE/ny y{Y                          fflush(stdin);
)f4btC w#w'Gw/Gc                          return -1;
@;wK5A N                      } de;v9Y qkUM
                     printf("opnd出栈:[%f]\n",a.data);
R-c$ie;Cm-dm8w:r                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
K ^#p7c L2]p%n2z7b+[                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ E7~ iKol}f&Ke
                     printf("结果入栈:[%f]\n",opn_tmp.data);
l[#p3t3_xx                      break;
N u Ju N2}4C l.R             }1o$\'cTU7v"\m
        }
4[nN d|K         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
'I BGL7y8[ u     }
D i%rChXk3_     GetTop(opnd,opn_tmp);\$K}$ne0R}1t(^
    DestroyStack(optr);;A(y~K5a!E
    DestroyStack(opnd);;Q9RP%Ag7i
    return opn_tmp.data;
`Y6s&ZK1ZxB }IT+S5Y o;h

P!k[ t} fN char *killzero(char *res,float result)
$h$_x~xU {
xZ(x hB%Vdi-N     int i;a TS;ue.P)r

8O!R5f as8~ x     sprintf(res,"%f",result);
6M#G!f7xz^     i=(int)strlen(res)-1; Oq!h7j a+wA&w
    while(i&&res[i]=='0')e~QirD$M
    {[bea/`c
        res[i]='\0';1S n[i%ME3E H
        i--;
x~+V hT5u)dVJ     }5yb4z,sm;hYFw+V
    if(res[i]=='.')/uM)@v:P6|
        res[i]='\0';:SG ^sK cfHT)_
    return res;h#D7\4a_u mF
}-T1c;z'{m$N

(\N?F Q,a A c0x5n int main())\-nofF0}:eOS F
{QM8VN7X |C)^
    char ch;
Mv'n'Q4BC     char res[64];
l)zl}F8O     float result;9A)oW5wH![
    while(1) Wkp%Zq-|
    {&f*Pr(h5Rn
        result=compute();
A([cDU6Z6vC         printf("\nThe result is:%s\n",killzero(res,result));!kX#ZQj,|Y
        printf("Do you want to continue(y/n)?:") ;
+@M&l-^E/~OH9{         ch=getch();!GT7[8W3g4Z5[
        putchar(ch);
0GU`5dd"o L         if(ch=='n'||ch=='N')
f9\J;x:UQ0W?"y7s%M             break;
_~c]m0~J         else
+I AG5yzIQ?!}             system("cls");
"R3@9R;i\u/{gK     }
E;Phl"F%W,l%GqJ     return 0;
2Y,cy qj(EP }[/i][/i][/i][/i][/i][/i]
k3G)@0A(l(K$f
~A&s#f-S7F c9Je+D#K9Q [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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