捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. a,PxX J8K
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=Kv t?6e1B
/**************表达式计算器************/n-_sV5c
#include <stdio.h>2S.SA FN5@1v
#include <stdlib.h>
1}:d|(V|@9b #include <string.h>&v,n3G2a%W Kj
#include <conio.h> c2v}4~$XT
#include <malloc.h>
U1s1c"z%x V z/pw+p#GH
#define STACK_SIZE 100
A+e!YC;Q #define APPEND_SIZE 10&hs1W6bRx&\6q+W#j

+lvxAv|3C:ax.R struct SNode{
(G2f&D~ZBN     float data; /*存放操作数或者计算结果*/]E ?0^ Zp d6xJ
    char ch; /*存放运算符*/(u+lb"a.ntr'Qw~
};b m-O1b)}@$a j

tl#_Bk:o Z struct Stack{
@1Xrxp1ro7~A     SNode *top;
,O!LR)g k}     SNode *base;
]$WLUS q4M     int size;
N7d~v yhR;? };
p~S+cj{ /Q3T&Nt4c/~t0cj
/*栈操作函数*/ tw,d4h#O0{
int InitStack(Stack &S); /*创建栈*/
'N8B kG8H)n_,a int DestroyStack(Stack &S); /*销毁栈*/ Qd T!v3|hY
int ClearStack(Stack &S); /*清空栈*/
3R;c+T/CF*bK$Z xK int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
nr8IwvD int Push(Stack &S,SNode e); /*将结点e压入栈*/
Q~Y!H%h.x Z7W+| int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
{Z8odG A C]~6J&NH$|;z`'v
/*表达式计算器相关函数*/
(p j,A.C'{ M!{W5f char get_precede(char s,char c); /*判断运算符s和c的优先级*/
g\~+U2X int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/S/?#M,c.k}TC*I'ag
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
;m/pW^&WWt![(D+Q float compute(); /*表达式结算器主函数*/
;]eEza#y+w-ht char *killzero(float result); /*去掉结果后面的0*/ f/y N ^&sJQ
O)nS xDTt'i^
int InitStack(Stack &S)
C6qJ)k MT)H X:` {&q?jfN
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));:BBBb;e!bY+C
    if(S.base==NULL)3yy?#R{v5h
    {3GY3A0g3\yy
        printf("动态分配内存失败!");)@ _ K!r IRI
        return -1;
:f1B.S*Bh7J2O     }MJ `0b-[q^
    S.top=S.base;
,^$jS Bo     S.size=STACK_SIZE;/i3gD3laAob%u+V(b
    return 0;$w}%]7`i.M2nP
}bk:jw2U Nq G
{k~tN W!xqw
int DestroyStack(Stack &S)
,nC z$WW K5p?q {"]?[ C^)S6b
    free(S.base);R6G$? ] d3Uzy7k}&L
    return 0;
6x?H6V:V w v^ ~y }| x-z\.?lA;~
3kdv(\'X
int ClearStack(Stack &S)
S2|!TDB:dozo:C {8_s"yA`Owl
    S.top=S.base;
ubR3~!kt     return 0;8[m"MfHq$TT
},Ex#C#\MJ%C2K`?

4jW]9eG int GetTop(Stack S,SNode &e) z K3k(k d8Dh B
{
3f0DQQ&D D     if(S.top==S.base)
`w2XE`$j?     {p)_|e)O9J
        printf("栈以为空!");
YeA;O#{k)@.u         return -1;OL y!Q-{'V'@
    }
9z{-X^XRv5d     e=*(S.top-1);
QW1WA.e     return 0;9_FQ:m+t:z+y+?H|
}
7EJ_(j6I0P}-Z
5l\8MO q/jc X Q int Push(Stack &S,SNode e)
;y:gM"Yd2{ {.H+p+v~ p1A XGO
    if(S.top-S.base>=S.size)
\.SU[T'u_x8?6x4g4L     {1q.~ q;e5L-_-|*Id
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); [5w*]q-k B9Zf\0L
        if(S.base==NULL)
o'{&AURI         {4S(zH9FU'Q
            printf("动态分配内存失败!");N#x6U3x*x
            return -1;x'_9?f1o KW#{i
        }
:w#[tL7E         S.top=S.base+S.size;|5L W.^ C3kSk!y
        S.size+=APPEND_SIZE;_ p$ewQ
    }
l]~a G8s     *S.top=e;
,ZQ`OO[w*Szb8r     S.top++;S x#l:^9lP c;[ QZ5H}
    return 0;aS#b5q-Qet Z OH(Sr
}
A.r u0A1y:`NO.d :?+BYvvs,b~
int Pop(Stack &S,SNode &e)
-R |:G!qV ` Fy!Z { _#J%V5gIC$k @g
    if(S.top==S.base)
wQ8e6x|$T8o     {
-O(^-qDf         printf("栈为空!");!B:b)E$|qKL
        return -1;
RK4H7r\hi     }
/WiEq#Zc[?     e=*(S.top-1);
_"b'm"b0kZU;S     S.top--;
}Yu:yVb[9?8[+`A     return 0;_'w%Qp-Q/n
}
&T$e$SQ HXe+Wa"q F X4]C(fn+b(Bemz+Q
char get_precede(char s,char c)/ccj5|2^1I ~"\1xl
{ t@)z`:h@KfTv
    switch(s)9|yA/xS)w2eG
    {7jg?*~+Yj
        case '+':                 uS}$q Vu2a8NEY
        case '-':
(K*X.Z-@ K9d m              if(c=='+'||c=='-')
U Y/] gkriL1lg                  return '>';6sL~/m la.j#Q
             else if(c=='*'||c=='/')
O,`,`PR                  return '<';"J(g7X9S Ks
             else if(c=='(')&}_%x{!t8l"~
                 return '<';3nvXyc
             else if(c==')')
&v$[_U D;c                  return '>';
0V3n!K-r{ _r |              else
'M/C:ar'[)S+}?                  return '>';0s2cu Rd
        case '*':l4Bb+X z!oa
        case '/':R;K4Sb;g5D B
             if(c=='+'||c=='-')B9f'Z_![ J ~A)[
                 return '>';
B3D0yp?.Q)I              else if(c=='*'||c=='/')
bD%\4RegPU[                  return '>';)R'r:t8`;u$pc+^
             else if(c=='(')*U)w/h7HU uirNgm
                 return '<'; u3b D{O"QdG
             else if(c==')')&J&M`I E LEE L+U~u
                 return '>';:w'B:ygmOk
             else'vX%@7k,h&_5Z
                 return '>';
dM:eZ,R|,d         case '(':bB'J["Dh+T[c1b
             if(c=='+'||c=='-')yGNr/B/j2D M
                 return '<';
fG uYlt&J#a4NF              else if(c=='*'||c=='/')
DB,U7dAg                  return '<';
v'|!bzL'`              else if(c=='(')
rK'E!h Ud$U`6Kf9Rc                  return '<';
-X{:Q;`]              else if(c==')')
e2Z"nx t                  return '=';[8Ik!Qi
             else
f!?B3WjR.v R2y9p                  return 'E';
(dR xp,k*h a5b9O         case ')': {&@9N#x$u)nz Z
             if(c=='+'||c=='-')/Df8s)UNue B{
                 return '>';
r"]"w1jz!d {C              else if(c=='*'||c=='/')0D2t r[]:W
                 return '>';
$m0z KF6u~6D0\ g              else if(c=='(')#K;ak ^K%X,T'c
                 return 'E'; aq|"M,P-R(a8vH"m
             else if(c==')') z'GmPm
                 return '>';Ifh)?'Bx3_5m!B
             else
J C;K{~1k g7^)Sc                  return '>';
!U[Q`1CDL [         case '#':
:X Wk_~              if(c=='+'||c=='-') C'sh?M.fN
                 return '<'; N ct2IcT,_/V
             else if(c=='*'||c=='/')BQ#S${)w+g2_
                 return '<';
%WJ l@ x(^p~&S              else if(c=='(')
B9GW j4{~:[.O$o                  return '<';K,M}y$hC%?M
             else if(c==')')
{)d%FncoD                  return 'E'; qhwEY-Y
             else
J/u${;J#r R6P)X                  return '=';
.r I5a\V&aQ@         default:
3u |6V"`_bdd6_4`[              break;
H*I:GSmCNj     }
t0hY!OQ^iS~3Q     return 0;    o B/P[3V(a
}Gq.N/|B@;~
k:i~&iFbY
int isOpr(char c)s.to K0x'Xg|K d$t5P
{
H{fqT_/hT     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')8i1V7?u,|[M
        return 0;j l2lv$|8x
    else
4u-Yg/[K]tI.t2K         return 1;9Xj)}p!JOn
}
u+vE)M-\9J%f
x)B&N#Z-u float operate(float x, char opr, float y),f,wKd|i#x
{#`0W5Y,Rio
    float result; i&f`E(gnr:G*X(Jk
    switch (opr)
q*w'H0gK b     {
:hi7l E(Kna         case '+': *] l J%f'Zl pj1r
             result = x + y;
%R#a1S GA0YX'vU'w              break;+mG`_Ycf rY
        case '-': ;| ^~?X3wd
             result = x - y;MU {6`)WWBfV4g
             break;
!Wr'Y/b%P;c         case '*':
YN/rZ;^w+J)|%|1Y              result = x * y;
gla9L Xdq              break;
g.n$yEm3s         case '/':
r+?*MEG7_9Z              if (y == 0)
X"s;B'O's?)D              {@ r\+[8^
                printf("Divided by zero!\n"); h|z"cK(m
                return 0;
3iGsME7_ JV$K              }2a7~K"m]!@p
             elseHG.l)E p)P b
             {
N_X3p6ad~,H;Y                  result = x / y;
)M6L.`IDt'Yw-V                  break;4]TW]9?1Xs}"Z
             }^4{"f-o"`"[ C
       default: &Pmea vKf?
             printf("Bad Input.\n");
1j}f3_/W#?hN              return 0;
*K-NGX-A     }
7VTlf1}$Ed+K     return result;
CG-~[erzB }    P BY~;QS5^C qy
In9G g'TY u@;qUB4SA
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/tV(An_oq8b6B
{E;?/xSiA!\
    Stack optr,opnd;
,_.C_9D-|~     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
o F.~/xL9X     char c;!cV4Qu f'Y
    char buf[16];
?~p3mY     int i=0;
@V y Id     -F1DIA0E3j#JH
    InitStack(optr); /*用于寄存运算符*/6{4Q6y4b_x4h8OZ
    InitStack(opnd); /*用于寄存操作数和计算结果*/0T~U5`$`.M
    memset(buf,0,sizeof(buf));
(h'e6@-o'JX\O     D}(T7xX'Ii
    printf("Enter your expression:");$Au9NO2}p/Z
        
P9k$g;V2W[ wl     opr_in.ch='#';U-a5y*\8m%W$g
    Push(optr,opr_in); /*'#'入栈*/z!} [R ZYN*Z9C
    GetTop(optr,opr_top);*F#A6R0}~D0L A
    c=getchar();,M/O7Z6^;r]0[z
    while(c!='='||opr_top.ch!='#'){"U0Oni.E]
    {qa-Lt2t
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
x"jPD2E&Ft2jq4Z         {
`9k%N d*]7A/F9G             buf[i]=c;X C]}-LtT!H-i
            i++;n g\)D3bE1^lNS
            c=getchar();
1xQ7D"k)Jq:r|         } BM'kB0|;R
        else /*是运算符*/
O9D)O([ M'z         {c9w@;\w+Pj(U1n1^
            buf[i]='\0';
8O v-C6QN7{?*@]Q             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0P(e ^y!m8_6?%K.u
            {
x oycj                  opn_in.data=(float)atof(buf);
M2Y+r yz#Q X                  Push(opnd,opn_in); d3{+H-Jpa y
                 printf("opnd入栈:[%f]\n",opn_in.data);
8WuL Z&Ggn)CU                  i=0;
;hn~ p8I.Q ]2D                  memset(buf,0,sizeof(buf));-U'_.vML6E
            }
*[2}fl+x8j%Qp6g-z             opr_in.ch=c;
a9M(nU#?mJq             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ W/O:i;Dyt d7~ J5j
            {q~'|-P6A4W8R n P Z
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
@s jg^                      Push(optr,opr_in);
3EPN9pT                      printf("optr入栈:[%c]\n",opr_in.ch);B7?#WGBfeb
                     c=getchar();
"z @N:s$k7BF9~u1S                      break;Z(`:z:z0U9y{
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
PF}E(H@T                      Pop(optr,e);%Q:]wRj
                     printf("optr出栈:去掉括号\n");
'E4|v-|W                      c=getchar();EX7O6\+ypE
                     break;|s2_ W/E1c#Z~/a
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/|rZ@@ `MeP Y
                     Pop(optr,opr_t);
4]/Cm;cODireu                      printf("optr出栈:[%c]\n",opr_t.ch);%L,i i)g9e k1h5_(U"y
                     if(Pop(opnd,b)<0)
?)XM]"Is)o}/r                      {{Z8?8@+k
                         printf("Bad Input!\n");,F0i\P3K9Tk
                         fflush(stdin); wR:@|(xX!wn3^
                         return -1; iKJ.L8Lq
                     }
!e{7n Ly:@$b                      printf("opnd出栈:[%f]\n",b.data);'xb?+i{E!m f:Xa&K7b
                     if(Pop(opnd,a)<0)
1iG;[Y,e.@1l'p                      {ckG;[.|5V
                         printf("Bad Input!\n");
Q%XA!W[.ND L)y$a8me                          fflush(stdin);
"`~-x;i{r'K                          return -1; DvgTG{{Y7t
                     }
y8I Ry;n G`(Jp                      printf("opnd出栈:[%f]\n",a.data);6C!t!viy!r
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/&z$k#PL8YXF
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/[_9d4EH9o
                     printf("结果入栈:[%f]\n",opn_tmp.data);
y/@DZ Rd+y,m                      break;6pgXu(l)G!P i}/Q
            }U"yovT jd&S!B
        }
BS8W?Z         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                J9ZQg(o0lm]
    }
hmwu3T`(W2Z     GetTop(opnd,opn_tmp); l1D6noM mBr
    DestroyStack(optr);NJ*jO @#p
    DestroyStack(opnd); D9[ |uR N2]
    return opn_tmp.data;
Qn$\9K2B3yDD }
9_-cEL{v8Y
f&M!k#g ]&RV u9F char *killzero(char *res,float result)!ooo^-M7@"B
{
G_(eDM(Rx     int i;
'{ru5}sUF[f F([+GgH
    sprintf(res,"%f",result);/o}!hRN%_ T0I
    i=(int)strlen(res)-1; mc Z4z'Q\8i].r]
    while(i&&res[i]=='0')s+zhQgZ T
    {6l'kiD _
        res[i]='\0';hV!@xhz|L
        i--;
2w;I)GR)^I&WM,X     }
&b8G#j%O-_P qPN(mnu     if(res[i]=='.')
OI$g,h8];x R9g         res[i]='\0';
j(jM8IZi Y     return res;"mNw |N;e(I3Mu}+{
}
]r!dP9OG/r:^ $p1eiLi,wY
int main()
on1o6Y}6L5OO {"],p+BIW'U1G Tx
    char ch;
"XQ#A+W-u     char res[64];Q6U8Q7q'?0YI~
    float result;
1Aj(c[qa     while(1)
G.~/kA n     {pQjf2G3`
        result=compute();
*By`*C.o/W g \         printf("\nThe result is:%s\n",killzero(res,result));
h?],hJ pdX9Z.R         printf("Do you want to continue(y/n)?:") ; G7m%A|{$X?
        ch=getch();uE;^W-h0S
        putchar(ch);0P%ME_&d}1x^#F
        if(ch=='n'||ch=='N')iC&{x W? o
            break;
H$zw7~_$Q-~%V         else RK!Y2D&h}r
            system("cls");
2}4cn1CPHd'V4SH     }
P"cZ2wS:rNw0x#K     return 0;+|:N*x.Z3sTc ^
}[/i][/i][/i][/i][/i][/i]H_U,}(c6nFH

b*\ `\l5] ink0cF [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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