捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
%re.Ho M5^E#u s 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
Qn(B*hed /**************表达式计算器************/-Ira!cC:r `#[4B{
#include <stdio.h>
7A)H&R?-d!` F#q%s #include <stdlib.h>
ku-Q)[a7s2yh |}8iGL #include <string.h>:bK4@7R5eSB
#include <conio.h>"ocy;Z+Q mkPj
#include <malloc.h>`5o\Ju!K7a5u|:]

%}0f IzK9B #define STACK_SIZE 1009gdw3\*j2vX[6XG
#define APPEND_SIZE 10
&uo8B,V%}3X)a $bpQ;H$nTv@C6p9fB
struct SNode{
iH)b5aI     float data; /*存放操作数或者计算结果*/;Rl3jWWk+M
    char ch; /*存放运算符*/!\_;Q%O2h
};|X b^(IB

Im.Z6@^H,Fnq struct Stack{
`w@2{9S     SNode *top;-RBkU3Y"Abt
    SNode *base;
3E#FR7J.z$Z)y9w     int size;
%Y w9g]E.B };
Bw Q Yath\
9T4?JLs'@ [ /*栈操作函数*/
9F'H%E*v)I ?t*GL9oU int InitStack(Stack &S); /*创建栈*/
?/T7{Qx j ?p int DestroyStack(Stack &S); /*销毁栈*/
?/JK1z(h int ClearStack(Stack &S); /*清空栈*/ C6q&g(pyv
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
i.wN)hvd int Push(Stack &S,SNode e); /*将结点e压入栈*/-f,F,N$\t x
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5K4]8fq?$U*{
r0Jg_'y |
/*表达式计算器相关函数*/U6deS;K2r;D
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
u%w{2U9~ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/!pZ_d,XR)mU*_
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/~j-Cf!Ds M
float compute(); /*表达式结算器主函数*/YA@jiS6Dw
char *killzero(float result); /*去掉结果后面的0*/
,{/]6gi M2\l'E[5nG
?Y3pP7[3o Ea int InitStack(Stack &S);E)Cc wILU%JQ
{
;w$~.B,ND;a     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
g{z0E3ij)@T     if(S.base==NULL)RP+l!W.I n j%K
    { ps1S3B%Z
        printf("动态分配内存失败!"); EX;iU^2n
        return -1;S_ _Fv.eY~ P'@
    }
D3x0X;cj'r K     S.top=S.base;
:XNO ^"\K+A     S.size=STACK_SIZE;h }L b:[ y
    return 0;"eiy$e1Z:y;k p
}n:UD-q1w0z
O%?~eKY$r
int DestroyStack(Stack &S) }-a1v%[hq
{
#K9qdLvjI0|     free(S.base); tC s;T0eV+qq.o
    return 0;
7nz7A\6h:S$k,D }
f\{K \Wl
%vs!Tk VGm int ClearStack(Stack &S)$HA9@4S O2Gw4O s+e
{Y0x r yswg
    S.top=S.base;
&YQ M7r*Q?x     return 0;
5I!c B`-HCv-h2[ }SX?(i2q(r6|,gh
~'S%zyD8D9r"[
int GetTop(Stack S,SNode &e)
3P,hiY4}I4FM!g {
d5_j H$T6x4QZ     if(S.top==S.base)
#i2t_ zn2DAo     {
"Hl2R1s T D n         printf("栈以为空!");
D L.k|9i/?fcq         return -1;
(K0To2P F.q&MC7l;T{     }#xu&?pt'y
    e=*(S.top-1);4[ td {7R
    return 0;
c`Qtr&N:|i d/] } x$r%S*R ~2ZB i U
q `'bX_HX$V
int Push(Stack &S,SNode e)Q#}"C-xKh
{
)zc d2O$Rv'AI     if(S.top-S.base>=S.size)G Dyv-E6O^p4\
    {m3|6tA/\g6J7~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));^ w `\$V{!E
        if(S.base==NULL)
7P0frrV         {"ZUaa8_)ve6^ K
            printf("动态分配内存失败!");
yRrL6M-q             return -1;
6h!cI*TB         }
|PS4P.` ^3T O3V         S.top=S.base+S.size;
)|2UB4Y TXr         S.size+=APPEND_SIZE;2|E*i;[Da:K
    }8d4[G2x,U.W-PM
    *S.top=e;g lBsX
    S.top++;%BNZ-j"t!O
    return 0;'R|2ab-[/m:]b
}%c:YV+}ou
P3Q#lT7YU7}Kj
int Pop(Stack &S,SNode &e)2I F^w%f'M3Y-u3I!]![
{
&xxp1]VN#O1\F     if(S.top==S.base)
"YX6Y2y.nV8Jfv     { XW;X+q5}S:`"a+u#f
        printf("栈为空!");
#muN`-Z7L*d/zf4V#`)Q         return -1;
y^'\k0u`7t`     }j DmX]6YX
    e=*(S.top-1);n$AAi(|,W2?+~
    S.top--;
`.b8WNF*z I-x     return 0;
9U+e Kx] }8^o:K6Xy_sk

)[ mM"ak }E v3y char get_precede(char s,char c)G!h-`x@b$cD-U
{
c$gf"en3KY:`     switch(s)
K'xP+q8?     {iuB [*r$k
        case '+':                 
2Z,m_w@(|:B,e         case '-':
Z3HWuV$a              if(c=='+'||c=='-')jVlGo7`2XW[
                 return '>'; Ue;L%husa eIY
             else if(c=='*'||c=='/')
_f\o LO9L%R                  return '<';
3ef9pt lf*L1Q              else if(c=='(')$pm!G#]2MF
                 return '<';.AU4{)bH sc
             else if(c==')')7[otMURM6Op|x2]
                 return '>';
?7G#z@Pu Z:O V'ZK n8f              else
]+Wf#t_m![V7B                  return '>';1hZ3KwF^*ZANM
        case '*':h]-`&OnvrYo
        case '/': W_~/o8G |6b6`"A
             if(c=='+'||c=='-')
:G Z t)`)oH Q.~#VeU9R                  return '>';
/Un"L^Wq              else if(c=='*'||c=='/')7ves)RK2rp
                 return '>';
f)gJ5d!_t9MYx              else if(c=='(')
+g%m|$xE_0bD                  return '<';%l`S EA5wW4C.p
             else if(c==')')'c'~q3_u
                 return '>';1F\MRzl*C+Z]"o
             else
%u:_/NXJrYA3s                  return '>';Eu9Lbe
        case '(':
;v X%u^'\Vk              if(c=='+'||c=='-')]:{-^s+m:Y'[
                 return '<';
a,\:p2hH%d              else if(c=='*'||c=='/')
n5L4RHU_/v                  return '<';9b5H@0C8_ b*l&e5c
             else if(c=='(')/B$T F.|?&L%y
                 return '<';
.~JBNy O-[oV              else if(c==')')
8R-uR3k2B                  return '=';
'Pg*q6ZB4U[p d              else
Ct)Q D@![                  return 'E';9k L5a0nX!I"B(z*r
        case ')':
2lO$f D m              if(c=='+'||c=='-')
6ue9Jj(?zp                  return '>';:h;J,^_a2p
             else if(c=='*'||c=='/')]4F#LB"Z#C,HQ:Hp
                 return '>'; Z.U p.P%X(h I.oL
             else if(c=='(')
JPK'`2]$b                  return 'E';
R0or*mf0O5a:@z&R              else if(c==')')
8e*Q0~-bHsA                  return '>';
#`&N9o oM [-u[y2^9W              elseuv8aV6bGr:B
                 return '>';_}-E VI y:^
        case '#':1B r7RK1C"ke RY@
             if(c=='+'||c=='-')
?DK#kp'j                  return '<';8K m1MZ{:Y0uqS#?
             else if(c=='*'||c=='/')8}(b#J3H'FtX)Z,M
                 return '<';D%b)U1ZC}G2X
             else if(c=='(')
hX-Pv+so                  return '<';
7lyk)G ?%QU              else if(c==')')
XVN$Hv4v                  return 'E';
nn)w @n              else
|-I]0uy                  return '=';
;\|Hek Qg Qtt         default:
p`kF9~%z;P`              break;h#yd7feW$|x
    }5Y;b6Ha+AO!w
    return 0;    7q!BO&pn![.T9Qc
}ZVM t0aavBh
iIAJ`@*g kS"R
int isOpr(char c)Anx[?
{Jb-Pp0E7s
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')alB.` qDOR
        return 0;
e5|nI,i7^k(@     else i"k#kti}1O
        return 1;
,G_4Auc(H C1u ? }
yE,A%j G"{g9h
5s"| pZ#gx float operate(float x, char opr, float y)Lsm-eck6Wt?3J
{
:y0BCH"BT'}D b     float result;v#t5\ eLLj.Bx
    switch (opr)
N"e?1?#GF#{     {
x:h ^g7gr\ }"c7v         case '+':
H(X0[k5SA              result = x + y;
G"@1a:aa-d)| b\W              break;
%~%~'|k K         case '-': ,r\ ^5bs` s$w
             result = x - y;[`W4p,iD"hu
             break;
!c5h+t6XktF         case '*': `/]:pz?6GV d
             result = x * y;5Zw%U2~A5Ep Z
             break;
L,L![UUS         case '/': Ti1Z8}${8A0Z
             if (y == 0)2sb(nK/gA
             {(lN7xE4Sf J[
                printf("Divided by zero!\n");
9]|~MfUt                 return 0;
`Z5Z#g:vKs              }
3i?2} PC(h#s.k8~i              elsecf:Rjt d
             {5gWW\.`l8{
                 result = x / y;
#v4m:F2`.ZI#Ly(P                  break;
u Hd:~??H              }
N,dzJ4J T        default: 0q%H8{%v7` L`Z8w7]
             printf("Bad Input.\n"); M2}'t\\3e{'kF9x
             return 0;z5S/C GJaX?q e1S
    }
eh?#LScf.{     return result;
bSv,[ u+pp7k }    -|acJ;aI

l~9fY4FVV float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/^w)XG`
{)C*ru {g ^9] F;q
    Stack optr,opnd;KWa1D#N8?7v3z*\!Q
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;TH2YLB%[J
    char c;
!oD_hZ n     char buf[16];9c7gXQ p(Ysi v'e
    int i=0;
*I4TT2h&Q,TROQ     0IUaZ+{;Ks
    InitStack(optr); /*用于寄存运算符*/
a;R!r,cq|     InitStack(opnd); /*用于寄存操作数和计算结果*/
.yx9oM _)Hrl,x     memset(buf,0,sizeof(buf));
p&w0O4L6| Jx;u    
&Y v pk\,jn     printf("Enter your expression:");
8F;{BQg;W6Z!s         
c`'A6Em@wa^\ E"[     opr_in.ch='#';+r [#f3H"kZI/f R#i
    Push(optr,opr_in); /*'#'入栈*/
.J6Q7XFp/WACm     GetTop(optr,opr_top);
p`x!B9x/F&o     c=getchar();7R5k y,EB5I$d-d;thN
    while(c!='='||opr_top.ch!='#')
]'c^)VT&Lu     {;F8o9}_"Iag@*g?"D
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/}Lv^BC+uW5_k
        {
H3\5}k+^             buf[i]=c; n6`.Me Ce4{YTy
            i++;.O}YF$jhP |
            c=getchar();hJh(m"xV+b
        }
SC5g-N ]l#Cl-f(N#J         else /*是运算符*/
nJjB&pl@:[         {4e]`.@3Q
            buf[i]='\0';Z8y*z2x7y+^-H
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/f9x?%{4`P
            {
xX d8mX C-v                  opn_in.data=(float)atof(buf);8Z^^Xd}1[R
                 Push(opnd,opn_in);
i*\Qv v!A&v                  printf("opnd入栈:[%f]\n",opn_in.data);P,D j\,ju]
                 i=0;i4_2e"\LC\^
                 memset(buf,0,sizeof(buf));'o$p!}9jK
            }XA1swH7It
            opr_in.ch=c;6g j2i7`z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/f&I}6L ng+a|
            {
*u ?]6uy,Y,_?                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
mt-Ri+a                      Push(optr,opr_in);8Sr-?d*ms
                     printf("optr入栈:[%c]\n",opr_in.ch);
7B}tD:O                      c=getchar();
$~@un3P4P[!~                      break;wR4JA!h GH8f"M7?
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
I9Q$Jf.uLO/\~*Y~                      Pop(optr,e);C J Jrj7l
                     printf("optr出栈:去掉括号\n");l%@G,C)S3D mY3s9}1`
                     c=getchar();&{k'T hCIG
                     break;
t6J4~ S\9\{g a                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5Hz!cC0N!X j                      Pop(optr,opr_t);
+zA-Q2PM)r0~^n                      printf("optr出栈:[%c]\n",opr_t.ch);
]"^?S*s;f e                      if(Pop(opnd,b)<0)
T)s/]!Q#v"r)@P"Vb                      {7H&gcz4x/\0`
                         printf("Bad Input!\n");yC#m n/c
                         fflush(stdin);k OSy])l-g
                         return -1;W&|VP7{4w-{%k
                     }4H;E-_&cyagxz:m
                     printf("opnd出栈:[%f]\n",b.data);[,DX l_
                     if(Pop(opnd,a)<0)Sq b8kPH:k
                     {5]V(JdYp$f `u[
                         printf("Bad Input!\n");?){lf9X6^
                         fflush(stdin);
+n%pBGv;^2f*~                          return -1;Lh.e cc-V
                     }
!q(n2| E8L@3Y                      printf("opnd出栈:[%f]\n",a.data);GS1yy+ftVr
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
"{x#YiG4Wx                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2GY-e F}                      printf("结果入栈:[%f]\n",opn_tmp.data);
8Kf~$MnN7z5XqSm                      break;)h|9f"L'FU$_mt#z+~
            } V0Y"G1yU!|l8y#b,X
        }
mDVof7_/s;Os         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                Lt+RSk@kk_5zL
    }^oI v$A1}.z
    GetTop(opnd,opn_tmp);\h0zlHa
    DestroyStack(optr);
2S9}{:\z)Y Ui x     DestroyStack(opnd);y9A O%p|\Z7j N`z
    return opn_tmp.data;x/f*S'NY/T U
}I.V I,MzK

BBIO3V_;]{j,w char *killzero(char *res,float result)
fvx3g.r'Hzz {
Rl(?*y/F!S5l;Y     int i;\!bu*V&B'I/y

f f1J8@2a^h     sprintf(res,"%f",result);
cW#vkI#~PX+m     i=(int)strlen(res)-1;
FRvW.Q[ n.A[2N     while(i&&res[i]=='0')%mj4Df%k2Y%Nr
    {
'h D E5E2Wn         res[i]='\0';
)m,FiNN tPu         i--;
t|5JZ(q9m(V     }+NH{7x'V+E
    if(res[i]=='.')
8hw1k#e*~ T d5A         res[i]='\0';Q@"{9M/_zRTI^D
    return res;z*@5L'q Y:@M3PEn
}/K0St ]xI1XZ9s(T

7I/d-}`\\bHt int main()7S5H3^B1~
{
.Zi S%@g{G|8koL     char ch;
m"o CR/kf@,h     char res[64];q ~!t3|}7qVu k T
    float result;
{$a)E b%pY     while(1)
Rk9Tg`dM     {J9v4[}j sk
        result=compute();
?G#R)e9W tD'`         printf("\nThe result is:%s\n",killzero(res,result));
*f&q6zLO'H1`1r-Wd         printf("Do you want to continue(y/n)?:") ;$tA(\uR9C R-o2v
        ch=getch();J?'A CCw"V S7m"U
        putchar(ch);
5EPGW^1K,M/u         if(ch=='n'||ch=='N')
;K3[Kfvy.^Wx,N             break;
&X^:@nFR+W         elsey3W(p'J!W7WDr[
            system("cls");a9a)iP,f$`H+u&L
    }i*x#vtS7~A&y,Q
    return 0; hk| p5e
}[/i][/i][/i][/i][/i][/i]
a'lg;I@\ cB
l D*V~5z%sy-X [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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