📄 kalk.c
字号:
//这是一个用c语言编写的科学计算器
//可以进行四则运算,乘方运算和sin、cos、lg、ln的运算
//刚编出来的,经过调试,可以正常计算
//贴上来和各位分享
//希望各位能指出其中的繁冗之处
//或者是找出bug
//谢谢!
typedef char SElemType;
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "process.h"
#include "iostream.h"
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACK_INCREMENT 2 /* 存储空间分配增量 */
typedef struct SqStack
{
double *base; /* 在栈构造之前和销毁之后,base的值为NULL */
double *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack; /* 顺序栈 */
void InitStack(SqStack &S)
{ // 构造一个空栈S
if(!(S.base=(double *)malloc(STACK_INIT_SIZE*sizeof(double))))
exit(OVERFLOW); // 存储分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
double ClearStack(SqStack &S)
{//将栈置为空栈
S.top=S.base;
return OK;
}
double GetTop(SqStack S,double &e)
{ // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top>S.base)
{
e=*(S.top-1);
return OK;
}
else
return ERROR;
}
void Push(SqStack &S,double e)
{ // 插入元素e为新的栈顶元素
if(S.top-S.base>=S.stacksize) // 栈满,追加存储空间
{
S.base=(double *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(double));
if(!S.base)
exit(OVERFLOW); // 存储分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INCREMENT;
}
*(S.top)++=e;
}
double Pop(SqStack &S,double &e)
{ // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base)
return ERROR;
e=*--S.top;
return OK;
}
SElemType Precede(SElemType t1,SElemType t2)
{ // 根据表3.1,判断t1,t2两符号的优先关系
char f;
switch(t2)
{
case '+':
case '-':if(t1=='('||t1=='=')
f='<'; // t1<t2
else
f='>'; // t1>t2
break;
case '*':
case '/':if(t1=='*'||t1=='/'||t1==')'||t1=='s'||t1=='l'||t1=='g'||t1=='c')
f='>'; // t1>t2
else
f='<'; // t1<t2
break;
case '(':if(t1==')')
{
printf("Error!\n");
exit(ERROR);
}
else
f='<'; // t1<t2
break;
case ')':switch(t1)
{
case'(':f='='; // t1=t2
break;
case'=':printf("Error!!\n");
exit(ERROR);
default :f='>'; // t1>t2
}
break;
case'=':switch(t1)
{
case'=' :f='='; // t1=t2
break;
case'(' :printf("Error!!!\n");
exit(ERROR);
default :f='>';
}
break;// t1>t2
case'^':if(t1=='('||t1=='^'||t1=='=')
f='<';
else
f='>';
break;
case's':
case'c':
case'g':
case'l':switch(t1)
{
case')':
case'l':
case'g':
case'c':
case's':printf("Error!");exit(ERROR);
case'(':
case'=':
case'+':
case'-':
case'*':
case'/':
case'^':f='<';break;
}
break;
}
return f;
}
double Operate1(double a,SElemType theta,double b)
{//做四则运算和乘方运算
double c;
switch(theta)
{
case'+':c=a+b;break;
case'-':c=a-b;break;
case'*':c=a*b;break;
case'/':c=a/b;break;
case'^':c=pow(a,b);break;
}
return c;
}
double Operate2(SElemType theta,double a)
{//做sin、cos、lg、ln的运算
double c;
switch(theta)
{
case's':c=sin(a);break;
case'c':c=cos(a);break;
case'l':c=log(a);break;
case'g':c=log10(a);break;
}
return c;
}
double In(SElemType c)
{ // 判断c是否为7种运算符之一
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'=':
case'^':
case's':
case'l':
case'g':
case'c':return 1;
default:return 0;
}
}
void main()
{ printf("\nwe defined:s()=sin(),c()=cos(),l()=ln(),g()=lg()\n");
SqStack OPTR,OPND;
int e;
double a,b,x,theta;
double d,f;
char c;
char z[60];
int i;
InitStack(OPTR);
InitStack(OPND);
do
{
Push(OPTR,'=');
printf("Please Enter:\n");
c=getchar();
GetTop(OPTR,theta);
while(c!='='||theta!='=')//判断c和栈顶元素是否为等号
{
if(In(c))
{
switch(Precede(theta,c))
{
case '<'://栈顶元素优先权底
Push(OPTR,c);
c=getchar();
GetTop(OPTR,theta);
break;
case '='://脱括号并接收下一字符
Pop(OPTR,theta);
GetTop(OPTR,theta);
if(theta=='s'||theta=='l'||theta=='c'||theta=='g')//对特殊运算符号的处理
{
Pop(OPND,f);
Pop(OPTR,theta);
Push(OPND,Operate2(theta,f));
GetTop(OPTR,theta);
c=getchar();
break;
}
else
{
c=getchar();
break;
}
case '>'://退栈并将运算结果入栈
if(theta=='+'||theta=='-'||theta=='*'||theta=='/'||theta=='^')
{
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
f=Operate1(a,theta,b);
Push(OPND,f);
GetTop(OPTR,theta);
break;
}
else break;
}
}
else if(c>='0'&&c<='9'||c=='.')//对数字的处理
{
i=0;
do
{
z[i]=c;i++;
c=getchar();
}
while((c<='9'&&c>='0')||c=='.');
z[i]=0;
d=atof(z);
Push(OPND,d);
}
else//c为非法字符
{
printf("error\n");
exit(ERROR);
}
}
GetTop(OPND,x);
printf("%f",x);
ClearStack(OPTR);
ClearStack(OPND);
printf("\nWant to use it again?Yes:1,No:0");
scanf("%d",&e);
x=getchar();
}
while(e);//循环使用以上程序或者出程序的判断点
printf("\nThanks for using the calulating device!!!");
printf("\npress any key to continue...");
x=getchar();
x=getchar();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -