捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.,Z:M k\!w,oR9H:Vg&^9C
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=?WDwe
/**************表达式计算器************/(] M0z+F E3N:pUj_
#include <stdio.h>
"E:yu.h1s #include <stdlib.h>
!Uu,ch*\m #include <string.h>
'bvNn |?/I8_ #include <conio.h>
B-g z8Z;|,z?;K#P #include <malloc.h>
'f5a3t XOWq i "{u@lE*m,{.Os"G
#define STACK_SIZE 100v/v7b n%y5`
#define APPEND_SIZE 10t` a;WU1q%l{B%B

-}N'j@Li\ struct SNode{
;mnJl'm0So i)M:C2R     float data; /*存放操作数或者计算结果*/
*Rz4V Hg|*vr"F!I5tyzw     char ch; /*存放运算符*/
g1zi'A_a(c }; D@Re3s:]4y
LJ:zJ |:nx7G+x
struct Stack{%k|3k fW.Dc!w3{
    SNode *top;
xY ~,Tey;o lj/a     SNode *base;vS1TX6O
    int size;F/TR,Q,Xv0p
};c{D ZmZ
%p s1Rg"FE
/*栈操作函数*/
? \KH#DqNp;Z int InitStack(Stack &S); /*创建栈*/
J3@ ?1l)Z int DestroyStack(Stack &S); /*销毁栈*/:]fO%V;d{nPG;B
int ClearStack(Stack &S); /*清空栈*/
1|mz*U#| co int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
:p2^{'LQ%o int Push(Stack &S,SNode e); /*将结点e压入栈*/
n6aYAdc(scz6K int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+EwwCdoB3Z| kSSM:`eh
/*表达式计算器相关函数*/
+q0z4m-jh-[pb AhD B char get_precede(char s,char c); /*判断运算符s和c的优先级*/
T'SNI6B int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/WmpO@l+~7y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6y0WH2k!Cg/n
float compute(); /*表达式结算器主函数*/
6c j&^9Lwz Q#t*a char *killzero(float result); /*去掉结果后面的0*/
6Er#vJZE0}U
r+q N(eJ int InitStack(Stack &S)X}1pO*Kq c ]b
{
u*Nx8U1]~7C8G     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));N XL ed-NC l9i-n3{%Z
    if(S.base==NULL)
E7nt1Ur?|!W%S     {,? s"I*x%`c*o#?
        printf("动态分配内存失败!"); ~)TO7W lIUr3Pxh}
        return -1;~$VjN*R4|E-y|
    }
|k(c RWVF     S.top=S.base;
^vP]eY}!t4m'_     S.size=STACK_SIZE;p0Vh1b/d"eHz2D
    return 0;
!YEZN|9H"L ~ T }
5N ]9hbh7oYt ;P_&VM1Xw$WB
int DestroyStack(Stack &S)
0Xd-J YRh { EbEm6~e"o d
    free(S.base);P%k;]&v(R[C
    return 0;
.b2eJ/R X }
H\:]+p:q3f
)v j~Eyd/GY int ClearStack(Stack &S)-^?K8V,^0Oq;F(u
{
+C ID6q9y7W"B     S.top=S.base;K ojib.cL0j'Q
    return 0;
-g$o H.y} d;_H!x }(H rH7jX dZ5O.@o

%E7ih"^"ldV` int GetTop(Stack S,SNode &e)$a9s Md7Q7_ \ u
{O4Gzm'C-x8C4}8I X Z7Y
    if(S.top==S.base)3}D5V"U;|U
    {V(y\&@ [ w
        printf("栈以为空!"); ZS,J8Ou g
        return -1;
5C1RT`Ko     }]3]-A Bff
    e=*(S.top-1);
;rR.A#W3IYmd     return 0;1z,?+d8Pr
}1vq:l@+O:R
hbiL+gi
int Push(Stack &S,SNode e)m9u aD*g FB1q
{
waY$uSK     if(S.top-S.base>=S.size) e Y)t+{+b&}Vz
    { [l?a Q`$m)k3@"~
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$} tk5mq(|L7J
        if(S.base==NULL) kG:f}"c2EHz%`T
        {Gx s r%P?&K
            printf("动态分配内存失败!");
f%|mWpC)LE             return -1;:k.B)~U^*u)r
        }
e+C:u`L I%x*Ff         S.top=S.base+S.size; p~R)f.O!i
        S.size+=APPEND_SIZE; BtAW[TCN8e
    }c9O,l#y-j
    *S.top=e;1I7k;M&kMwD
    S.top++;
7AjI:JXL m1V     return 0;
([u+f"Au }
$qU,m&q(j&d| "No*g3a?|/i
int Pop(Stack &S,SNode &e)m?,`F0a'Y'Mo
{*[;zk@K x;[0L ~
    if(S.top==S.base)
@.rN)`6k+CQL8Ls&A.R     {
)`v.Tw^+A         printf("栈为空!");
|Az(U:oX!^1r#r         return -1;
IU l} z T JN i     }
O$]#II&]3U,mR.L8X+f     e=*(S.top-1);
5F)r.M7V%B:^8~ OG6C     S.top--;
!vok8`F g     return 0;a[)f6^U
}
ktQ)d-g#|Z .n+G&[?BG;~4N
char get_precede(char s,char c)
:r-W-R1nO;k? {Pk,N~f o]
    switch(s)
z @NRJLYg     {#m1KL-lj.J,b3evI0@
        case '+':                 +r3B&n4VXuqiv _s
        case '-':
_~}K$eon k              if(c=='+'||c=='-')
yfZ }l                  return '>';][u*q1XW8Mn
             else if(c=='*'||c=='/')$uZ[Ju8~
                 return '<';
!{2t` G2Svq              else if(c=='(')
9g9]%KkN                  return '<'; BX2`[3e|
             else if(c==')')9uyM4t t
                 return '>';
I"dlo4B7}#Y              else ;p"]&NY.Fh n
                 return '>';
u7G'| lFa8Y         case '*':{ eKG;ie
        case '/':
J%B1mC;F\,o              if(c=='+'||c=='-')n Yq3wp&G!`da
                 return '>';
F&G:cp(H0`              else if(c=='*'||c=='/')
&~2tH0g7APs                  return '>';^%ab$v-^5U,c
             else if(c=='(')_Z)D8m$]
                 return '<';;m*L?.CL Pj_
             else if(c==')')/\uS!]*O?
                 return '>';$M$K9{GT D8E
             else8|8lW$oU2H
                 return '>';
[:IZ/v!iX         case '(':
H8?+b#Q5lL              if(c=='+'||c=='-')
3p(}Z1DD                  return '<';2Hv7T R v{G%`{\
             else if(c=='*'||c=='/')
bpn{L`                  return '<';
OH3LI0?,q:t)t)KJ7S7_              else if(c=='(')
]/},r"g!`q                  return '<';
-o/` lpXR;mp              else if(c==')')
Il @1B8F!k+z CNk+X$n                  return '=';
9gH$[G4ITU              else
,S.u$[,E+@.g9o                  return 'E';
Y Fb,z}B |         case ')':)R N)[ XQG&[
             if(c=='+'||c=='-')
q(V0Sc}                  return '>';
-uLc Yt zw              else if(c=='*'||c=='/').[P [7A6QI db{0c|
                 return '>';'ZW y-\ M2?,e"r'F5[
             else if(c=='(')hr ^!s8t4B-k)r
                 return 'E';JrV c(e%\
             else if(c==')')X8RKHH` p Sjm
                 return '>';5[ Mrhj@~3w
             else
%VE$^ ER#Vs                  return '>';
6Hk5?t H3PA-g         case '#':$O#Z/hz'ez+qaW;nn
             if(c=='+'||c=='-')2O*Xi(IV#m E R
                 return '<';V_.m!kq%r-t
             else if(c=='*'||c=='/')
EO0mSi#A _ mH6l                  return '<'; R}(J ap
             else if(c=='(')$w.`|+R:["hI
                 return '<';
8Xv H(T,K]1e              else if(c==')')L|#YQad]!K
                 return 'E';AJ)N }|b
             else2q9o{VQF
                 return '=';
7U2?%|'e#`M         default:
7S!I&}_@xHL'O              break;
}S(n9v6RV     }gx1@7\%H|*\
    return 0;    /kJ0T'[j)Nb(r3T_9| b
} b q0f+O-_V!vH

)R['E$E,u2\$b$uR int isOpr(char c) N Vne/Ly | d ^DK
{
9iT0o5a\7C8d     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')&Z%Pe-S`6i8k
        return 0;/T(E6HsT:{t
    else
` i!X(z V+NeE*x2z         return 1;p's#M m y
}H r@!C*L!X-|
:O*o4@1w0Lf*h0}
float operate(float x, char opr, float y)1nPa3A~1]X.^
{
0Hso w)r)pTQg     float result;
b6k'yc_`BJ$qy     switch (opr)MP-_ f5iI0e
    {r+f*`#y/CC%S
        case '+': 8C0uR;~[R
             result = x + y;xl~N!B
             break;
7fCto$d!|         case '-':
Pr+S5YHQ              result = x - y;8xf Z om0G^V
             break;*L p\S,|j
        case '*': 7TJ3Ni2o
             result = x * y;
$oBzFo!i-`!oc              break;'X$J1KLa1i],G1S
        case '/': .Z.O,I1T6th/h
             if (y == 0)
P]'tT2O$O0{)N              {
^W r:`e%OaE                 printf("Divided by zero!\n");#O:Zq-I7m*cn u
                return 0;
J~+a\yQ              }b/@|H)Y\2Xu
             else
;D#CD+z.Z l lV!N              {
XK AW2A.r                  result = x / y;QN ~-yu;F:l$e
                 break;
n:@,Ys`5c a              }
w+Ed]_;jhd-U        default: %k+wga$y'u4]
             printf("Bad Input.\n"); 8F0}H!wO:nO
             return 0;q1b Gs1El
    };dJ#LlA
    return result;
m_.pI'|ak }   
%~![x(X){coJW0h $P$w r,lx {C%} J/m
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
uS'^f)gQ0H {F*y:{*y+}q Mu
    Stack optr,opnd;
X;h}#VQl[     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
tc,H\I6N     char c;H0Jw a C8UyO&e i
    char buf[16];w)nOzf'gHM
    int i=0;_Q1SJ;Z&k9t:K
   
,|@D k/q Wt-^4a?     InitStack(optr); /*用于寄存运算符*/
vw0|J_.[     InitStack(opnd); /*用于寄存操作数和计算结果*/7r(xx0@g
    memset(buf,0,sizeof(buf));
!|UR:YsAx?w    
#qU9e6n6Q!?$yE$d     printf("Enter your expression:");
^x}S Fy8T X         4l$v'B} `H
    opr_in.ch='#';
O:C/V@,b_1M     Push(optr,opr_in); /*'#'入栈*/
Rqd9s%] t     GetTop(optr,opr_top);)S j2s:m*cDD
    c=getchar();!b'M?;R]
    while(c!='='||opr_top.ch!='#')
)j0i ? vW+W     {
Ma&OL4d ] k         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
)^ j| XiaWnn"L         {/eVL.mm#^dH
            buf[i]=c;-y)O.uE7X`8i
            i++;GM&O? Z
            c=getchar();
xN)?-EZoa@dm         }
B d&wM&BW {,T         else /*是运算符*/.~N H7R'z W
        {J~&q+V y*Q#l8e
            buf[i]='\0';
(w#V-_cuK/Iy             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
Td F'C X1u}mS1R             {
RA3bI.oVg                  opn_in.data=(float)atof(buf);
zZC;zI]'I                  Push(opnd,opn_in);
HK*Mbb3] q-e                  printf("opnd入栈:[%f]\n",opn_in.data);
2IC.f E6q`3x                  i=0;FS$P/n,t+\f1L
                 memset(buf,0,sizeof(buf)); M @V&s],g;d
            } ]@#b p:r&U.]6uX
            opr_in.ch=c;
SX @0|i[J x             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
p]J6p2V_             {
+Z+d {4\i                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
M;U k\l8`7nv                      Push(optr,opr_in);
y.`5]rxGe@                      printf("optr入栈:[%c]\n",opr_in.ch);Mf+b.sSVf
                     c=getchar();4g'z.h&VN-Jmq@
                     break;G3Z*bw*U!{o_
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/"N[m1tgsne^
                     Pop(optr,e);I?+pb_.wJR/C.t?
                     printf("optr出栈:去掉括号\n");`sjlbpq&V)O
                     c=getchar();p+s#f*syt!@
                     break;
#b)J e6]8SJ                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3dt+g&V$f,T#{1k                      Pop(optr,opr_t);RF;e j/o0Y { X%p
                     printf("optr出栈:[%c]\n",opr_t.ch);
-PB(DbxUc                      if(Pop(opnd,b)<0)
'o5D)Tny\ ? i:w                      {
6?&RW,rx o:i9J3?                          printf("Bad Input!\n");[,R8N u(dys/l
                         fflush(stdin);X zgvn qs
                         return -1;
6c Z@goM GH(Kl(~                      }.v)Rc!]Q!m)h0x\
                     printf("opnd出栈:[%f]\n",b.data);
/c}&C?\:I}@/I!C                      if(Pop(opnd,a)<0)
p-S6qI@w                      {
*D,b2n-y]{*N,jdX                          printf("Bad Input!\n");Sz_^x K
                         fflush(stdin);
X2mw q'QN _                          return -1;
,|u/Ob y n _(rn D                      }1C["r iT x(f{
                     printf("opnd出栈:[%f]\n",a.data);
P8rB*Ffc/}$~3J                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/9_"U h(]XMuW mY
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/aeK#e#s,Z|.W
                     printf("结果入栈:[%f]\n",opn_tmp.data);
0ce$Ms{dkb                      break;
{"UTJtR3k/_ `             }"H[:l%e-Y
        }
,y7E!G7uE)b         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
"r[.L[:W1?,WrXh     }~GV7{;@Kw
    GetTop(opnd,opn_tmp);
!}!GvP!pM;@k/n     DestroyStack(optr);1RS.[ PqW9t
    DestroyStack(opnd);)RFo6Se2]*wDyW4OAn
    return opn_tmp.data;aPCR2jGx V,d
}iz{ J {:UVc)U
ue#QWXQ+ZQ ~X
char *killzero(char *res,float result))Ho tKW ]3JV S
{
o m{d!P$hO'x     int i; O-}#?R#V^
\(vlM4NpC
    sprintf(res,"%f",result);
hO'Hd8vf-?     i=(int)strlen(res)-1;iN(I xvl(P l;RVa&o
    while(i&&res[i]=='0')
I&D)h$F r:BF9C     {
L,ts2t h g         res[i]='\0';
+X(el g)_ N}         i--;H8o'o)c1b*^%F
    } zo%TX ZvRE
    if(res[i]=='.')h/ax,O u H5xi
        res[i]='\0';
t;|~:j/e9k     return res;1\1V5UA3[0?_
}
['g&xy$e5Y O+e Ls(b6Hf
int main()4N6z%fvG4z@JO
{2o@T%D5M K
    char ch;fN%TDO.^(F
    char res[64];
4a3Ep;rDe ^:t@*O(IK     float result;&?$Mvnrs#awV5@+U
    while(1)
JtdZOE7X     {%\C2f&r;UrV
        result=compute();3p&H8ekZk }+{
        printf("\nThe result is:%s\n",killzero(res,result));
.p$X w$z?1?E2k         printf("Do you want to continue(y/n)?:") ;
+y+L A9O(I u         ch=getch();
/_i'})}IJR         putchar(ch);
EB%T Gn;QHL,M         if(ch=='n'||ch=='N') T4S#ZDLX$h*X
            break;
;t0jn"}f"S         else
L!oR;RiqJ             system("cls");
t `0l(]@     }:@o V-^)vh
    return 0;
zqO8KBg3kW }[/i][/i][/i][/i][/i][/i]
\{\C6P1u2\G A3q8kL7mZ`N9h
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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