捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5u { B:OT#F g/qU"Ps
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
IjO;{&g I!t /**************表达式计算器************/K:N6z5s Rt(\
#include <stdio.h>,p2|J`2jI
#include <stdlib.h>p8F*s Aa } c2F*t
#include <string.h>
]+O2dt:\IJ(d;l#P #include <conio.h>
,Uvpz&G/g9rt1? #include <malloc.h>7s9i z@7O`oDT

:O*{ L&z R;Cv | #define STACK_SIZE 100 B(U qqm
#define APPEND_SIZE 10"c(bw+g1G4s0nd
k+SC9m7iG@
struct SNode{&yV*LV'tW
    float data; /*存放操作数或者计算结果*/
$lt$o7w;Xr     char ch; /*存放运算符*/j a9Q T T
};
2b4B&A}CF
&I|$^H*Qc { struct Stack{
+D;s)m8A`,}`+^     SNode *top;
,^0I,V:w\KTCM#D5C     SNode *base;
/Zl"G']c)v2]8?H     int size;V7|[lD GQ
};2W H%`*EMTP4R

;J4k;{5\hLh /*栈操作函数*//bV H8ASJ'W_
int InitStack(Stack &S); /*创建栈*/,Pz\%W^
int DestroyStack(Stack &S); /*销毁栈*/
y7O${z1Wh(j0\2K3ZI&z int ClearStack(Stack &S); /*清空栈*/
Fw|2yR:Hg int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+]H;b}/`w\~ int Push(Stack &S,SNode e); /*将结点e压入栈*/+TrG!\~3Zm L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
!ag:i7u p6\W p mi HA
/*表达式计算器相关函数*/
o[Y R5J%h&PL'x char get_precede(char s,char c); /*判断运算符s和c的优先级*/:Ws&zYrLj*C5_
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/z(U jdc
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/.N7Kd'Yk'C
float compute(); /*表达式结算器主函数*/K)od tF;J
char *killzero(float result); /*去掉结果后面的0*/ '`9VK.j%do vj
!cm1K2hm'TOl
int InitStack(Stack &S)
]3l?+ykFz {k*W o(P c/I
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
Gx#kZt@m"b     if(S.base==NULL) d ?@\ SJ FTh?'C
    {
+T$z$o3t a         printf("动态分配内存失败!"); s8^v JS#A-O
        return -1;
O&A6H6hCKxrOe6|'R     }
zT[NZ8o `%V     S.top=S.base;
7Hi(z)OoESt7s%Pw~     S.size=STACK_SIZE;
_'y|q _0s,xh`6k%kP"}     return 0;
K RsFBc s }
y*sK.V2nXNX#Sf )rtE5`jF
int DestroyStack(Stack &S)
k/K0c8tv H {SSdI-o*Z
    free(S.base);a^L(b*E'dJ,S
    return 0;/X9ko*bqxI8[;|
}
PRm ^4JT
W U N^.P&}c xy~ int ClearStack(Stack &S)0jO1d W$P`
{
^Q4d.}7fWq     S.top=S.base;^:^8}v1P+uZ
    return 0;
jukTf9t }:BU}V \C+T

X(ulU DB^ int GetTop(Stack S,SNode &e)
a0gk*WB*w3?vC {Yub:{4M'q
    if(S.top==S.base)
6Ok(b!vL+^;dZ$D     {
)F6J!CX*|J)_'X$}7_!Z+t         printf("栈以为空!");
R JiYB'G*I         return -1; \)b#A(l3f
    }RHq6i'h~
    e=*(S.top-1);8Sz4v1b&B'y] L
    return 0;1[*c'K5e4{J5K,n
}
!@Zp/?']xMN#c
6`"Fg!U[ sQ/^ int Push(Stack &S,SNode e)
[kI7p9D!?+z%u {y8_[N9a&^Nm.k3V@
    if(S.top-S.base>=S.size)
xr!Z1m.[t$~$~     {
vlU]M:r(jdrG         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));eis.CuQ Rvy
        if(S.base==NULL)
'pYu2x R3Z,W5L         {_Yy1q3v&X#F?&bP2Y
            printf("动态分配内存失败!");
?F.X.IN,U;z i             return -1;z7^ k^ZJ A+R
        }
3g&LWQA}0Fo         S.top=S.base+S.size;\-R'Hgu%zM$vuID
        S.size+=APPEND_SIZE;I g-cr.xH
    })p5]j*e#}1c*R$q
    *S.top=e;Q%BCtF$n4o)R B
    S.top++;i1oA^N7G5N`E
    return 0;
6c9H;BeG,bH#pB }~7M'Q;hz
Y#P0a/mv$H e
int Pop(Stack &S,SNode &e)
#~[3z(PA |SN {
s N7DB7c u     if(S.top==S.base)Z0}"{"k~!^4_i.i
    {,Z3N5B+LUZx1[Kiy
        printf("栈为空!");
:X"NWJ0aM         return -1;
@` I*bTa9i&{h     }
'b m~~;U%N f&C     e=*(S.top-1);
c}k iw#x2g&G#Vcf     S.top--;
D'YK5VS     return 0;h9C0h/V4F3P8u9~ZY j
}MD]0h)["w*n.k'W
8L ZoP:W|:|w6K
char get_precede(char s,char c)2e,W"w:D/m'{&W
{
*t:o+F6alv s     switch(s)+{l)dm0tUT)H
    {T u\ x,L-I E.`
        case '+':                  JPO M$aqe
        case '-':
{$BN6A.[?;B+fC$s              if(c=='+'||c=='-')4o"Ss6J5UpU"yJ kC
                 return '>';,T,yK:u9{2UHk
             else if(c=='*'||c=='/')"yS9T"ewe
                 return '<';%v}-Y7Wi h
             else if(c=='(')f'dQOKTdlI
                 return '<';
]l(~PB Q6j:p,h*P1E              else if(c==')'),~%z:t{6W`8@ _ TS
                 return '>';
1l,t0q[!k+L}o3_5V              else v5kF/HC7G(b
                 return '>';f&_0m6W)K#JN
        case '*':
?+A$KP:r i$@         case '/':;V#bf4[Y^ L7^
             if(c=='+'||c=='-')
SK/x&AHu"`zd_                  return '>'; qK,t(P$]%l
             else if(c=='*'||c=='/')
;W*F5Y(|%TwgB                  return '>';3mbu"A0q%}/_2] Y$u v
             else if(c=='('),A Q#@I$fji]
                 return '<';
P%fEue?1]&Mo              else if(c==')')*o ~qT~"H+W"}uL
                 return '>';
.S S.a+YHt(j @              else5hs2|]Mqv(I
                 return '>'; {%d2? NH)h
        case '(':rD7zc(?KIP6H
             if(c=='+'||c=='-')pD\ zz s2I3?Q
                 return '<';
E"_%HMbZW              else if(c=='*'||c=='/')
Sl;R5FOG5T H                  return '<';k4C7R1r9{6X7d
             else if(c=='(')
D2WU UR,T2`-y M                  return '<';Bt1a]O
             else if(c==')')
Ke!Aj t5]                  return '=';
b6?LRu x              else
_B4c}"JG4{                  return 'E';N`iXDL"t
        case ')':1p#h$N g#x5i
             if(c=='+'||c=='-')
lC2F)t Ex                  return '>';D/u+~\G2z
             else if(c=='*'||c=='/'):H&oR5[&N Wg2p'n
                 return '>';
s1|.D9I;bY              else if(c=='(')0n#C X#z/_D}:s
                 return 'E';
B,Q y U hQ2~`9J              else if(c==')')
!d`%`8YGF                  return '>';
%|"OqdOn%N              elseUqDpRX9Va
                 return '>';%Jzn&fv LX O2k
        case '#':!T^;B\_P
             if(c=='+'||c=='-')
y^^2Q;gV+`fG                  return '<';
)Ufu2jq8pi{              else if(c=='*'||c=='/')
"j8FR_XTH)u8` bx                  return '<';
%H@4^"W._              else if(c=='(')c/C"s D-V ?r1p$ej
                 return '<';
BW'}a3iS              else if(c==')').G1L^7Z(a%X;_Dx6U Jk
                 return 'E';9fNf j;\9` d#N:{9l
             else/V5e8V&?Poe:pPo
                 return '=';
tyA`Kk;v ~e         default:
8pr$P8l"anz?!Fu@              break;
"meqB FX9e:QI$T     }I/iXa^ T#o/N
    return 0;    9`*O}._}:U8Z@
}+HvRs"hM6e[
\t`m:CU(?$m
int isOpr(char c)0{|8A$K2H$i,A4gFV
{
nZBi q}6pt     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
A*w3}s?5`YY Z         return 0;c`!zjO1trfP
    else
.D,K$W8@ gI         return 1;+S L4bu!e1b!DxqX
}
.}0JF ng7jdW"RA
Or D9^+U3C)H Hyi#d float operate(float x, char opr, float y)7|5M$W2|'A+w
{
4JIY O$I,JX S/s     float result;zt K]%e
    switch (opr)I7@!a#IiKo
    {b FEu zT]
        case '+':
Wl e_uHM              result = x + y;1Mid1iK
             break;
J&S I2bgrx v'k         case '-': j$N&L}uVj0K
             result = x - y;Gj*a)G#b5}'W(j!n]{9C
             break;
f4h\ J8a%r         case '*':
3C X8k A a `f,}-H              result = x * y;|Y'FLmq2R/?4^
             break;
)sxX~|3LM         case '/': ^"FV}5bTN&}$P
             if (y == 0)ld-w"WLC.} @ r
             {
!]7o pR3q                 printf("Divided by zero!\n");
Eq v1d fr,D                 return 0;
Mx7g&Z@a'fS              }4qBU7[z h"fp`\
             else
i#mB4Kl.]              {"M)nz7di4M(Beb
                 result = x / y;
` p|:k4?4^                  break;]d} d8|IS7O.~
             }0jL/Q(|u
       default:
`,F QV)NS W+i              printf("Bad Input.\n"); Z"S'P [#}IMO%S9P1u
             return 0;tH%vY;hr
    }
8\b&fCs0^i'Y-L     return result;
d&e;rm@(s }   
U8A W5_JPQ
Y%UK2Yg"?O(s-b float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/{;~vR0A&h5y
{
] H2KH2xP(s ` h     Stack optr,opnd;
D,v @r;E f%P     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+Ku A ^)B[ND}     char c;X/dG2m2r_
    char buf[16];
d"rpNM+z     int i=0;!_ i N8_ e]L'J?c
   
OKsUL,s     InitStack(optr); /*用于寄存运算符*/*t kUM+k-QJ
    InitStack(opnd); /*用于寄存操作数和计算结果*/
2RT"Fh\1` E `     memset(buf,0,sizeof(buf));
I"HY;eS^B!Z3U    
0}'`%~'|'RYKc     printf("Enter your expression:");9pLa1Q4aw`!Rj
        0Q HT8Q~*RYk
    opr_in.ch='#';
D"S}RP8NS!X&|K     Push(optr,opr_in); /*'#'入栈*/+AY8T"eV#lM)H9O
    GetTop(optr,opr_top);.W e k!Z6z fyg#N
    c=getchar();
X|n+HF3WDF     while(c!='='||opr_top.ch!='#')
\ GY:]W0TR     {
*g W%u9eX.} N         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
$AXkDRm|/L1e         {K4m(L6M*_dc(PT
            buf[i]=c;._P4j%~(J-My
            i++;
N.i?^.sX_wf             c=getchar();
[GRPj         }
({$M*q/rA-h"]         else /*是运算符*/n;b` \5F DU
        {3y{*Q:z%?E9u,p:L$Md
            buf[i]='\0';
H t7r?fK}2P!X             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
`Qy1Ve             {RlA;a%f Gr#ET T
                 opn_in.data=(float)atof(buf);
OQyf8T;~&M hol@x                  Push(opnd,opn_in);
0w&l|Yd                  printf("opnd入栈:[%f]\n",opn_in.data);
z}a`;H,[H;C7J                  i=0;
m}M7Z-OB                  memset(buf,0,sizeof(buf));
F7F{C n+]2o             }
%g_r5nY {/\}'p${             opr_in.ch=c;Jq.K2T+u%YE
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/:uD/Jma/QaB
            {&t`2nw$@ w
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
DW`0`"B9U,g                      Push(optr,opr_in);-T&J7E'Xcvq
                     printf("optr入栈:[%c]\n",opr_in.ch);
m%ciz` c                      c=getchar(); k1r9Uk VsM4{
                     break;
XuP&B!J [hW                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
"^#J!V)SJy                      Pop(optr,e);
6^M xK4f)ia#OTL o1D q                      printf("optr出栈:去掉括号\n");
?)c V-GIj1k8z9]                      c=getchar();M5h F x/F)j S/\:f c9G _
                     break;%r v,O-J ~_%} jr
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6x A a3^a.H-N|,J;j.@YB                      Pop(optr,opr_t);
'jF"W s!E-m0b                      printf("optr出栈:[%c]\n",opr_t.ch);,q/Ij{/l Qj4Q X
                     if(Pop(opnd,b)<0)
iS5T] w                      {
:a0h6ZZdhR8r                          printf("Bad Input!\n");
hf\1gW5S                          fflush(stdin);0WH O]7A&s,bv{5me Y
                         return -1;
b5w.VPD o\0~                      }FC G+J+m[z%W
                     printf("opnd出栈:[%f]\n",b.data);r8n/XZ5s WZ
                     if(Pop(opnd,a)<0)
2y-i(NV"aZV                      {
`!U(Nfr3@%[?                          printf("Bad Input!\n");tI1R7@)IyWf-S
                         fflush(stdin); xR,NA0q9bn
                         return -1;
[e Hf,qn r2{                      }
!Iw3R9uP Ne                      printf("opnd出栈:[%f]\n",a.data);;INR)ifK-f(uS iX
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1s:Q g jF
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6a#F;z,f&u                      printf("结果入栈:[%f]\n",opn_tmp.data); doX.M*x
                     break;
$BJXF`2tk4e~             })P/f#C|[R6h1k
        }
)hp,`"E-e%~+q         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                8bU&JBl l1G
    }
q6j?c;oau.?1M     GetTop(opnd,opn_tmp);
xO6{2j8k     DestroyStack(optr);&aw9qV8nY
    DestroyStack(opnd);
XC"OG)SObxW     return opn_tmp.data;@ pA2SjL"N
}
*RV3B#g)j:W ie{Q ST0u
char *killzero(char *res,float result)o~*v IVT^H]C
{
;eSN L(Rx l({T*C     int i;L-w6iB9q Z7s
p2u.YGbTE
    sprintf(res,"%f",result);0|(a;U;A6p!pH
    i=(int)strlen(res)-1;
lf6s k IU     while(i&&res[i]=='0')
2?/Rk5@'xD5Q7cFC     {(o wu;@ SR
        res[i]='\0';R,R9~.Z6|k(E
        i--;*mH8Z}#A| |
    }oX7}B+i
    if(res[i]=='.')/}3cEA'o_:Zr'Rxg
        res[i]='\0';
_kZ-k/DO R5A&|     return res;
:Ch6p:H$^Mu(S }
;n^ DM;Oh
X z:IV o M Lk int main()
$Fo'j9BJI LA7R {GB/T Y3J^3y%{9LW l
    char ch;
H p](Tw     char res[64];^ @ U-e C5L&d Ea
    float result;
v/xz*u U|?TG0N     while(1)
'y@(Sd5sL,M     {f0K#Z0c z
        result=compute();d]9ve%K,{ @
        printf("\nThe result is:%s\n",killzero(res,result));jG9Ld@0v
        printf("Do you want to continue(y/n)?:") ;exNa@-^'ho
        ch=getch();
d$IOgd_2V         putchar(ch);t$Ru9o}hn^~ FA
        if(ch=='n'||ch=='N')abl8uM
            break;
a8N1DQ{/~i*eZa4b         else
MrV C1M`Lk             system("cls");
Czevn%Y"hPu     }R;`k N]f'KQ
    return 0;
cY2YV#~"S-z }[/i][/i][/i][/i][/i][/i]
\ ~,YH^j:y)}f
+Bl |w;eS [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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