捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
4`o]*{/B5Csx Y 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
Zu1pT{'D /**************表达式计算器************/
rP!@:l,^0G4o4O ri #include <stdio.h>$G]n;ZFFH
#include <stdlib.h>3H.y9czivM
#include <string.h>z` A"G8A5j db
#include <conio.h> h#{ m{!Fb
#include <malloc.h>
u Q^P!?_ _'rs0L$Vf^7i9g.ri
#define STACK_SIZE 1009Y+GEV[s
#define APPEND_SIZE 10tz,HatY1Jf&|

rYK@"QU struct SNode{
{Jz/r(f.jah0E     float data; /*存放操作数或者计算结果*/0Of{#[J(CN1h
    char ch; /*存放运算符*/
aW4sc_m };
)Xfu0MrP Sn
&D-FE#OL0_:E struct Stack{
d^no4]0AP_'r     SNode *top;
5i,Hjem.T,`     SNode *base;
{"{8z+p"T$fp     int size;x|2x yb
};t4L6W4}Cy b
E8v7E)md'_5Ej4X
/*栈操作函数*/
c m/f+F K int InitStack(Stack &S); /*创建栈*/
]L k(dQjC)o` int DestroyStack(Stack &S); /*销毁栈*/yC+sw9alVnI5v
int ClearStack(Stack &S); /*清空栈*/
w\'v7[;W Zk int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3j I;| g9L8IbvY int Push(Stack &S,SNode e); /*将结点e压入栈*/.H4i|@8_Vq"W
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
T1e$g1@1B,Y9l)v4N'hgH 1Fd8rc q
/*表达式计算器相关函数*/]ppsx
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3O\3F1CF,eRJ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/"\\h.t Ur yi]
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/#Bw-I-U"wvzH&O3W
float compute(); /*表达式结算器主函数*/
m*k,W K:g6vC char *killzero(float result); /*去掉结果后面的0*/ 6oK j9o;Y,a6l8?
b/Kit UVbM
int InitStack(Stack &S)HLU!sm8biJbX
{r}f#}QB
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));#^(F'F DZn"Ck1B/]
    if(S.base==NULL)f~)p7[]%c K
    {
T?]Y4K;k(rb-R         printf("动态分配内存失败!");4xB u0aJ
        return -1;SH u#P"_g
    }
x6my$Qd     S.top=S.base;
We7]:Y3R$N     S.size=STACK_SIZE;\,`/sk b~6Y
    return 0;
\S"q'tthn5_ }
0rrU0T"_&{4@
WTk W aba&n"^ int DestroyStack(Stack &S)-{&eeg1YN _$wvu
{
2DB C2qz     free(S.base);
z6G-Y|k0g     return 0;:B X^O(|cSWF
} aFSNj

x%{oD~ _%f!O0A int ClearStack(Stack &S)8A'~V]X`vW
{olN-rOd4y
    S.top=S.base;
%dN3ia-D;d]*R F     return 0;
Y}[$Buf }
}y.C&W}B 1D,z#t p3rt+u
int GetTop(Stack S,SNode &e)
$j1n,u%b a!O3@K,x {;_;`b5Q/j{ Z"_:@ x`0?
    if(S.top==S.base)_? Tx!m
    {*o`Pr!aox%]~,Q
        printf("栈以为空!");
3]2[sk#x:lW         return -1;
?.j]%f/guo(`E     })TaHe'Z*e5w
    e=*(S.top-1);6V"E4u1[5N&lkp K1JK]
    return 0;
T3W|$_O7[n'a Z }
2I)@D2u8{ eGZ0};C*cr&MZ
int Push(Stack &S,SNode e)V,z I u L(Y~8MRl {
{
{2E Q0mg'] u     if(S.top-S.base>=S.size)
&V ~"mYM)^},I     {nsJ(H8P$m$B_T@
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));f%TF q F c#v!N)^
        if(S.base==NULL)
,]1v1[3["F*a]         {3[}`v6y CI0g
            printf("动态分配内存失败!");Z] u^9S9s(tm
            return -1;
2r [@:q]9f         }
O+]4F!jMS HK         S.top=S.base+S.size;
il!d ZR1KOQ)k}.`         S.size+=APPEND_SIZE; r CQ2Q}B"`,{0v
    }
qh2z_(B:g"Ys     *S.top=e;
Fl^~8z+x wWU     S.top++;W'k/WX.D YX:_p
    return 0; Qy[Phv8d h;|y
}
`ro g C]
5zJ |2_ Y l0P)D int Pop(Stack &S,SNode &e)
f j rF P2r {
g@`%D[.Aa     if(S.top==S.base){SO4^6z GT$]1N
    {
5y2lw-S7s[#b         printf("栈为空!"); M,vC q B0g/r|Xq
        return -1;
9_r,MW:n(}     }
S8w7C.iN3`     e=*(S.top-1);
LPCGc-k'~4M}     S.top--;
Uy"vP[*_     return 0;\G7OmcWY L
}y!J0R-paD~`
a%iMB {L{
char get_precede(char s,char c) N!Q5~8g}&w#a
{
!L|0bobxP     switch(s)
ul n?L-Zuf     {1E$oO(\G'gA
        case '+':                  ~RA1Wt'e
        case '-':
p a#w0S*lUc6@              if(c=='+'||c=='-')
?-O$F^/p(F8H                  return '>';0L#V_)QW
             else if(c=='*'||c=='/')
@BIq#}Zw                  return '<';
)O5q!y3U8ks              else if(c=='(')
RlPr,AU Q`{x                  return '<';[_)H4p#Q q
             else if(c==')')
'riiZ8ot6T                  return '>';
0v0Ui"Mda-b'rj9A%g              else 6mVNe,oD o
                 return '>';x6[h1OkQ
        case '*':,^(B}W"p,pnMz x v
        case '/':BdNO\'ES/cW9S
             if(c=='+'||c=='-')
{!~|[2br5v                  return '>';W,bN u!B!]O
             else if(c=='*'||c=='/')._,nz F\7?(r2{ aM&fF
                 return '>';
)k9y%b4k$YY)W:g              else if(c=='(')5B#Hpi&Bt2Z#[
                 return '<';
rEdiDnC              else if(c==')')3pY#|Yze
                 return '>';
*w {"g,vW0C+d              else i_#S\7y n
                 return '>';
;g8RzQ'x1SW"_         case '(':
TPjE,l)B%C;f9L              if(c=='+'||c=='-'))R*x IDCa
                 return '<'; m]{heB+XDU
             else if(c=='*'||c=='/')
Z6Dv-ZeB                  return '<'; Tz$Rkr`$`0j2C
             else if(c=='(')
r3vpAB-J Cc M5tpc                  return '<';j+x0Z9Jo&E,w:f
             else if(c==')').Xu9b(R9?BuGx~
                 return '=';9t*L+trv8?7P
             else2w,\a*R,x1KM|K5e
                 return 'E';`A#XU.~-Jy
        case ')':0V1fW"n}L9\9p7C9X
             if(c=='+'||c=='-')I8_%J"C{'OV
                 return '>';
(UHoe/L)z0K              else if(c=='*'||c=='/')F5[!^"S0n M
                 return '>';
0Np-wNu tx              else if(c=='(')A1}*o7kb$u~
                 return 'E';
#}dM:];[q8T              else if(c==')')Z*p*fg/a{P9s
                 return '>';#D+Sk3H!Jm
             else
~9P(yX qR3SR                  return '>';0P TzA m4L
        case '#':
~J.iAXgy(u              if(c=='+'||c=='-')
&VUpp a6u i                  return '<';E"`Q xW
             else if(c=='*'||c=='/')8r6?#v Ke `
                 return '<';
VJ|"xt(R              else if(c=='(')
9MMr6yzpx                  return '<';~P9bg;V3OR eIl A m
             else if(c==')')n:m V*c H9o1@9o"A#c
                 return 'E';!nbo-UNyfur
             else
*tK!F"\*k0n9g                  return '=';
f-D+]+?.jj         default:JU{ ~7SR
             break;,`-agE#o P0y/r Q
    }
^hy[ N"Q(oI'Nvi     return 0;    sb2?Ry[j3L|
}
"_&p arm c
5]-??\Gw&D#c9[1[ int isOpr(char c)
H)O/Fxg1}1j {.~jK!xK qj
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') a z!l p }3f A_
        return 0;
/yX9Y;U(] D8C z     else s4Wz*upq5`/u
        return 1;
yJS'K;KX } { W"TTk.ytc
dra%uU-c
float operate(float x, char opr, float y)%RQxi vR
{5CuL K-`0oU9{A:W
    float result; {j1S$DS;\
    switch (opr) Bm|+N)J7k,EZ3i
    {
*t3n6Hry5RI!bp*w         case '+':
:C.N\wJQ g              result = x + y;+oj]F7F9T5U
             break;4W N4nV5O,mt5E4A
        case '-':
$H%mV?'^9s.{;zg              result = x - y;'\/A6zq_4j7e0\A
             break;
,rt(\f~3A4J         case '*': c5Y G8XB}~I
             result = x * y;)GUfM6GxzT7V
             break;G ]A f'yR.il
        case '/':
d!Kw3u/FI|6_JA              if (y == 0)
['Q$B:l/M(f+f(n7N              {
0JC9^eQY!W(B                 printf("Divided by zero!\n");
+E*`$X kK                 return 0;,I%J"GGn-z T
             }
9m&q1U4pT2wN              else,b*P-sf4O!`
             {*p8\I7w%xE&^N
                 result = x / y;
Q_Jl }&tE                  break;"`&e(J$C*b H Z u.`
             } f*d`9e4w)P'r
       default:
4U u5p#i,hsZL@#is              printf("Bad Input.\n"); d4DDr6I
             return 0;-vO(T0F dLGG
    }S.p MQ?+V IL
    return result;)p|7r+N~9^U6z
}   
%p"~L*`(F
AKaZ4V^+_/Ygw4^$d float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/A~FIlo:iM(z
{qP,[ p| _T-o
    Stack optr,opnd;
R qx:U i     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
Y$W2Z^+Y     char c;Gy)Ew;zu9w
    char buf[16];
[]k6{ M5s     int i=0;
*J`2s n:P[-X(B     "G QE+OjN
    InitStack(optr); /*用于寄存运算符*/
%^'Va7YM*Xb+Ui1b     InitStack(opnd); /*用于寄存操作数和计算结果*/
6x:K;v ejz.K     memset(buf,0,sizeof(buf)); c~ue ^&E
    2Q$tp-jy8R6[
    printf("Enter your expression:");;v W9?TG R!\
        U7G9KN*a#|L5[#|)Y|
    opr_in.ch='#';
ei!M ~$o} ~8Ox*h     Push(optr,opr_in); /*'#'入栈*/
1F V(S |L&GT K(o     GetTop(optr,opr_top);
T+vv+AU*Oj4a     c=getchar();
T/|o,i8IQ)a0k     while(c!='='||opr_top.ch!='#')
c X-Ov h5m l,VD o/L d     { BU?l|2K
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
h!S.X:a V6l         {`} {#V R gw
            buf[i]=c;
p` K kE7z%t7]             i++;
3O p&y/@x             c=getchar();
]3O*P f%@e6|,^         }
1}8TX$KRYS         else /*是运算符*/
Yi-\ A Z)j8_L         {7W8Z1i3Z7x%V
            buf[i]='\0';3luE$a7?Y JVz,i
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
S"eBmm6o F             {k!{ g}+zs$i
                 opn_in.data=(float)atof(buf);W?n(?P+}tQ
                 Push(opnd,opn_in);~jxN9Ma$uCw
                 printf("opnd入栈:[%f]\n",opn_in.data);)nB'^BWW
                 i=0;d)m%l'u:Y e
                 memset(buf,0,sizeof(buf));
R J*? CySni)KB]             }
.\{*C"|+Z]             opr_in.ch=c;
(mY'hEc&A             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/@XS(|e/_w4M+[ h
            {pU#\S(\ ^
                case '<': /*优先级小于栈顶结点,则运算符入栈*/I^!z}E#l
                     Push(optr,opr_in);__ YT8aV-N9o
                     printf("optr入栈:[%c]\n",opr_in.ch);
c0E1mLw                      c=getchar();a-e W [(['Iu I~3y@
                     break;
7Bgy/Nq^                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/UiK/\x)e%c.V `
                     Pop(optr,e);
#F _.T6AvQ}                      printf("optr出栈:去掉括号\n");
:N7SaT3S&v                      c=getchar();|'xOry`$g^aH
                     break;
`eS2c#f                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
tq%t wAfC5A6m                      Pop(optr,opr_t);
r!\Bs[ea0v                      printf("optr出栈:[%c]\n",opr_t.ch);
K-Xcl {aI%w j                      if(Pop(opnd,b)<0) Un P2MNj
                     {3K_\.I}a_\&I a
                         printf("Bad Input!\n"); Du:j3pe1P(UZ#{/m
                         fflush(stdin);,d&x/} Iv.~$WF
                         return -1;
1E'r4_$eL                      }#\!KE ot {rr
                     printf("opnd出栈:[%f]\n",b.data);q7j~efZ
                     if(Pop(opnd,a)<0)#_-tVx-n L'G;G
                     {
#vjGf {P                          printf("Bad Input!\n");
__dv;o u                          fflush(stdin);
q%Fu jS\                          return -1;i$M:mx.M
                     }4A,~ P Nz6z}2V+s
                     printf("opnd出栈:[%f]\n",a.data);-Q J1zu{Tr%G!q'Z
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*{R p5[ Id5v(x
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/f"w3o+u)Ghq
                     printf("结果入栈:[%f]\n",opn_tmp.data);`&\-FP~W MZB
                     break;I Wd8vaira\3nP
            }2] Z9A)TG
        }
TGX|5NNN0R0d         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
)\j)K|2R'a.[;^E#G i     }'Ke;K F2zsz!Ck rP
    GetTop(opnd,opn_tmp);
!O+w*e,\)X&_N]UF     DestroyStack(optr);
%HO2b*q l+~U     DestroyStack(opnd); @y4^`y3NP+eA&J.e
    return opn_tmp.data;
"W$~+vc ?8i }
~J] HjDJ7T*` o~n #z r3p5cpJL
char *killzero(char *res,float result)
Doq,O |&@-w~ {
d4K!g1W,a)o-s     int i;/t4W;l&C4l ]1?
*m.u ni!j
    sprintf(res,"%f",result);im&Xz?5ly0C
    i=(int)strlen(res)-1;p^6bF.y2F4h
    while(i&&res[i]=='0')
&vYK5WK)I     {lFqi*x
        res[i]='\0';(JMh'RB1Eia
        i--;&y!@D&Q k _L
    }
Af!P&Z8_*jE9K     if(res[i]=='.')
.cQ \]J         res[i]='\0';
F o7g@#N/Vm     return res;
4u){jX6i%e$ft }
#@MSQ+Q &b]a`#~qxz
int main()
]7[Ff ^3uh {
@E1D%i!adj4d     char ch;| mI tc,r,L+vf
    char res[64];3a0eCd7j~8g*Lk
    float result;
i fC J$P6i'O     while(1)+nJi0LY?z VJ
    { f&_5u!P(^/Su
        result=compute();
!d k k(Zq gQ         printf("\nThe result is:%s\n",killzero(res,result));Ca%qHl)o2T!L
        printf("Do you want to continue(y/n)?:") ;
4]_;ka2`f&G^I,vQ         ch=getch();
p3~2?k}W1x(ovU7w         putchar(ch);sDyP([,pl,pP
        if(ch=='n'||ch=='N')D:Y2F6m jdjq.t
            break;0_&OoA$h
        elseG;g#mlmXOJ/v\
            system("cls");
\(n CUn,{/f`     };]/g-^[ c
    return 0;
~.} ^]*} }[/i][/i][/i][/i][/i][/i]M-e0NpO
rb0\z-@-T
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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