当前位置:文档之家› C语言计算器程序源代码

C语言计算器程序源代码

//strcmp(s1,s2) 当s1大于s2时,返回1 ,s1小于s2时,返回-1,相等时,返回0

#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "math.h"
#define MAX 256
#define STACK_SIZE 128
#define WORD_LEN 8

#define POP 1
#define PUSH 0
#define ERR -1
#define END 2

#define OPER 0
#define NUM 1
#define WORD 2

#define ADD 1
#define SUB 2
#define MUL 3
#define DIV 4
#define POW 5
#define FAC 6
#define BRA_L 7
#define BRA_R 8
#define SIN 9
#define COS 10
#define TAN 11
#define CTG 12
#define LG 13 //以10为底的常用对数
//#define LN 14
//#define LOG 15

//行标为当前操作符代号,列标为栈顶元素代号
//2表示计算结束,0表示当前操作符进栈,1表示栈顶操作符出栈
// \0 + - * / ^ ! ( ) sin cos tg ctg lg
int Priority[14][14]={2, 1, 1, 1, 1, 1, 1,-1,-1, 1, 1, 1, 1, 1, /* \0 */
0, 1, 1, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* + */
0, 1, 1, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* - */
0, 0, 0, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* * */
0, 0, 0, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* / */
0, 0, 0, 1, 1, 1, 1, 0,-1, 0, 0, 0, 0, 0, /* ^ */
0, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, /* ! */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* ( */
-1,1, 1, 1, 1, 1, 1, 1,-1, 1, 1, 1, 1, 1, /* ) */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* sin */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* cos */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* tg */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* ctg */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0}; /* lg */

char KeyWord[36][WORD_LEN+1]={"sin", //前12个为函数,多余的用于扩展
"cos",
"tan",
"tg",
"ctg",
"lg",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"help", // 后面为命令,多余的为扩展
"version",
"set",
"digit", //精度,小数点后的位数
"color",
"radian", //弧度
"degree", //角度
"file",
"clr",
"clear",
"window", //窗口模式
"fullscr", //全屏模式
"",
"",
"",
"",
"",
"",
"",
"",
""};


int OperCode(char c)
{
int code;

switch(c)
{
case '\0':code=0;br

eak;
case '+':code=1;break;
case '-':code=2;break;
case '*':code=3;break;
case '/':code=4;break;
case '^':code=5;break;
case '!':code=6;break;
case '(':code=7;break;
case ')':code=8;break;
case 's':code=9;break; //sin
case 'c':code=10;break; //cos
case 't':code=11;break; //tg
case 'C':code=12;break; //ctg
case 'l':code=13;break; //log
default:code=-1;break;
};
return code;
}

int WordCode(char* word)
{

int i;
for(i=0;i<25;i++)
if(strcmp(KeyWord[i],word)==0)
break;
if(i>=25)
return -1;
else
return i;
}

void help()
{
printf("显示帮助信息!\n");
return;
}

void version()
{
printf("显示版本信息!\n");
return;
}

void Err(int errcode,int position,char *p)
{
printf("\n ERR:%d Position:%d %s",errcode,position,p);
return;
}

double long factorial(int i)
{
if(i==1 || i==0)
return(1.0);
else
return(i*factorial(i-1));
}


main()
{
char Expression[MAX+1];

int Operator[STACK_SIZE];
int OperStackTop;

double long Number[STACK_SIZE];
int NumStackTop;

double long NumList[STACK_SIZE];
int NumCursor,NumListSize;

int OperList[STACK_SIZE];
int OperCursor,OperListSize;

int WordList[STACK_SIZE];
int WordCursor,WordListSize;

int Index[MAX+1];
int IndexCursor,IndexSize;

char Word[WORD_LEN+1];

double long num,num1,num2,weight,tempnum;
int Oper;

int isDecimal,isErr,isNumber,isEnd;

char CurrentOper;

int i,j,k,m,n;
char ch;

num=0.0;
num1=0.0;
num2=0.0;
tempnum=0.0;

Oper=-1;

while(1)
{
for(i=0;i<=MAX;i++) //表达式初始化,中间表索引初始化
{
Expression[i]='\0';
Index[i]=-1;
}

for(i=0;i{
Operator[i]='0';
Number[i]=0.0;

NumList[i]=0.0;
OperList[i]=-1;
WordList[i]=-1;
}
NumStackTop=-1; //栈顶指针初始化
OperStackTop=0; //操作符栈压入\0
Operator[OperStackTop]=OperCode('\0');

NumCursor=0; //各种中间表指针初始化,各种中间表的长度初始化
NumListSize=0;
OperCursor=0;
OperListSize=0; //操作符表中先写入第一个操作符'\0'
WordCursor=0;
WordListSize=0;

IndexCursor=0;
IndexSize=0;
// Index[0]=OPER;

printf("Cal>"); //初始化完成,输出提示符

i=0;
while((ch=getchar())!='\n')
{
if(i>MAX) /*输入超长,则出错*/
{
Err(0,i,"输入的表达式长度超过规定值!\n");
isErr=1;
break;
}
if(isupper(ch))
ch=tolower(ch);

Expression[i]=ch;
i++;
}
if(isErr==1)
{
isErr=0;
continue;
}
if(strlen(Expression)==0) //直接回车
continue;

if(strcmp("end",Expression)==0 ||strcmp("exit",Expression)==0 || strcmp("quit",Expr

ession)==0)
break;

//一下代码为编译预处理,主要处理负号,并检查括号是否配对
k=0;
for(i=0;Expression[i]!='\0';i++)
{
if((i==0&&Expression[i]=='-') || (i>0&&Expression[i]=='-'&&Expression[i-1]=='('))
{
for(j=strlen(Expression);j>i;j--)
Expression[j]=Expression[j-1];
Expression[i]='0';
}
if(Expression[i]=='(') //检查括号
k++;
if(Expression[i]==')')
k--;
}
if(k>0) //如果括号不配对
{
Err(1,-1,"缺少右括号 )\n");
continue;
}
if(k<0)
{
Err(1,-1,"缺少左括号 (\n");
continue;
}

//编译预处理结束

i=0; //词法分析
while(1)
{

if(Expression[i]=='\0')
{
OperList[OperListSize]=OperCode(Expression[i]);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
// printf("IndexSize=%d,Index[IndexSize]=%d,Expression[i]=%c\n",IndexSize,Index[IndexSize],Expression[i]);
break;
}

isDecimal=0;
isNumber=0;
while(isdigit(Expression[i])||Expression[i]=='.') //读取数字
{
isNumber=1;
if(Expression[i]=='.')
{
if((i<(MAX-1) && !isdigit(Expression[i+1])) || (i+1)==MAX) //不正确的小数点位置
{
Err(2,i,"小数点位置不正确!\n");
isErr=1;
isNumber=0;
i++;
break;
}
isDecimal=1;
weight=0.1;
i++;
continue;
}
if(isDecimal==0)
num=num*10.0+(double long)(Expression[i]-'0');
else
{
num=num+(double long)(Expression[i]-'0')*weight;
weight=weight*0.1;
}

i++;
} //数字读完
if(isErr==1)
break;
if(isNumber==1) //如果刚才成功读取了数字,则数字入栈
{
NumList[NumListSize]=num;
NumListSize++;
isNumber=0;
num=0.0;

Index[IndexSize]=NUM;
// printf("IndexSize=%d,Index[IndexSize]=%d\n",IndexSize,Index[IndexSize]);
IndexSize++;
}


for(k=0;k<=WORD_LEN;k++)
Word[k]='\0';
j=0;
while(isalpha(Expression[i]))
{
if(j>=WORD_LEN) //超过长度仍然未匹配,则出错
{
Err(3,i,"单词长度超过规定值/未定义的单词:");
printf("%s\n",Word);
isErr=1;
break;
}
Word[j]=Expression[i];
j++;

// printf("WORD:%s\n",Word);

if(WordCode(Word)==-1) //匹配不成功
{
if(!isalpha(Expression[i+1]))//匹配不成功,但是下一个字符已经不是字母,
{
Err(4,i,"未定义的单词:"); //则出错,并跳出循环
printf("%s\n",Word);
isErr=1;
break;
} //匹配不成功且还能继续读取字符,则继续读取下一个字母
i++;
continue;
}
else //匹配成功,则单词入表,读取下一个字符
{
switch(Wo

rdCode(Word))
{
case 0:ch='s';
break;
case 1:ch='c';
break;
case 2:
case 3:ch='t';
break;
case 4:ch='C';
break;
case 5:ch='l';
break;
default:ch='\0';
WordList[WordListSize]=WordCode(Word);
WordListSize++;
Index[IndexSize]=WORD;
IndexSize++;
break;
};
if(ch!='\0')
{
OperList[OperListSize]=OperCode(ch);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
}
i++;

break;
}
} //单词读完

if(isErr==1)
break;

if(Expression[i]==' ')
i++;


if(!isdigit(Expression[i]) && !isalpha(Expression[i]) && Expression[i]!='\0')
{
if(OperCode(Expression[i])==-1)
{
isErr=1;
Err(5,i,"未定义的操作符:");
printf("%c\n",Expression[i]);
break;
}
else
{
OperList[OperListSize]=OperCode(Expression[i]);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
i++;
}
} //操作符读完
if(isErr==1)
break;


} //词法分析结束

if(isErr==1)
{
isErr=0;
continue;
}

/* for(k=0;kprintf("NumList[%d]=%f\n",k,NumList[k]);
for(k=0;kprintf("OperList[%d]=%d\n",k,OperList[k]);
for(k=0;kprintf("WordList[%d]=%d\n",k,WordList[k]);

for(k=0;kprintf("Index[%d]=%d\n",k,Index[k]);

printf("\n\n IndexCursor=%d IndexSize=%d,\n",IndexCursor,IndexSize);

printf("OperStacktop=%d,Operator[OperStackTop]=%d,NumStackTop=%d\n",OperStackTop,Operator[OperStackTop],NumStackTop);
// continue;

*/
isEnd=0;
IndexCursor=0;
while(1)
{
if(Index[IndexCursor]==NUM)
{
if(NumCursor<0 || NumListSize<0)
{
Err(10,-1,"索引列表与操作数列表信息不匹配\n");
isErr=1;
break;
}
NumStackTop++;
Number[NumStackTop]=NumList[NumCursor];
NumCursor++;
IndexCursor++;
continue;
} //数字处理
if(Index[IndexCursor]==OPER)
{
m=OperList[OperCursor];
n=Operator[OperStackTop];

switch(Priority[m][n])
{
case ERR:Err(20,IndexCursor,"不可预见的错误!\n");
isErr=1;
break;
case PUSH:OperStackTop++;
Operator[OperStackTop]=m;
OperCursor++;
IndexCursor++;
break;
case END:isEnd=1;
break;
case POP:Oper=Operator[OperStackTop];
OperStackTop--;
switch(Oper)
{
case BRA_L: IndexCursor++

;
OperCursor++;
break;
case ADD:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;

tempnum=num1+num2;
NumStackTop++;
Number[NumStackTop]=tempnum;

num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(11,IndexCursor,"加法运算缺少操作数!\n");
isErr=1;
}
break;
case SUB:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;

tempnum=num1-num2;
NumStackTop++;
Number[NumStackTop]=tempnum;

num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(12,IndexCursor,"减法运算缺少操作数!\n");
isErr=1;
}
break;
case MUL:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;

tempnum=num1*num2;
NumStackTop++;
Number[NumStackTop]=tempnum;

num1=0.0;
num2=0.0;
tempnum=0.0;

}
else
{
Err(13,IndexCursor,"乘法运算缺少操作数!\n");
isErr=1;
}
break;
case DIV:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
if(num2==0.0)
{
Err(14,IndexCursor,"除数为 0 ,不能进行除法运算!\n");
isErr=1;
break;
}

num1=Number[NumStackTop];
NumStackTop--;

tempnum=num1/num2;
NumStackTop++;
Number[NumStackTop]=tempnum;

num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(15,IndexCursor,"除法运算缺少操作数!\n");
isErr=1;
}

break;
case POW:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;

tempnum=pow(num1,num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(16,IndexCursor,"乘方运算缺少操作数!\n");
isErr=1;
}
break;
case FAC:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

tempnum=factorial(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;
}
else
{
Err(17,IndexCursor,"阶乘运算缺少操作数!\n");
isErr=1;
}
break;
case SIN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

tempnum=sin(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(18,IndexCursor,"正弦函数缺少参数!\n");
isErr=1;
}
break;
case COS:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

tempnum=cos(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(19,IndexCursor,"余弦函数缺少参数!\n");
isErr=1;
}
break;
case TAN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

tempnum=tan(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(20,IndexCursor,"正切函数

缺少参数!\n");
isErr=1;
}
break;
case CTG:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

tempnum=1.0/tan(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(21,IndexCursor,"余切函数缺少参数!\n");
isErr=1;
}
break;
/* case LN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
if(num2<=0.0)
{
Err(20,IndexCursor,"自然对数函数真数:");
printf(" %f 小于0!\n",num2);
isErr=1;
break;
}

tempnum=log(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(17,IndexCursor,"自然对数函数缺少参数!\n");
isErr=1;
}
break; */
case LG:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;

if(num2<=0.0)
{
Err(23,IndexCursor,"常用对数函数真数:");
printf(" %f 小于0!\n",num2);
isErr=1;
break;
}

tempnum=log10(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;

num2=0.0;
tempnum=0.0;

}
else
{
Err(22,IndexCursor,"常用对数函数缺少参数!\n");
isErr=1;
}
break;
default:Err(100,IndexCursor,"运算符(代码:");
printf(" %d )暂不支持!\n",Oper);
isErr=1;
break;
/*#define SIN 9
#define COS 10
#define TAN 11
#define CTG 12
#define LOG 13 */
}; //switch 语句结束
break;
};//switch
if(isErr==1 || isEnd==1)
break;

continue;

} //运算符处理
if(Index[IndexCursor]==WORD)
{
printf(" 单词尚未处理!\n");
break;

}//在这里处理单词

}//核心计算结束

if(isErr==1)
{
isErr=0;
continue;
}




if(NumStackTop>0)
{

Err(1000,-1,"多余的操作数:");
printf("%f!\n",Number[NumStackTop]);
}
else
if(NumStackTop==0 && isEnd==1)
{
if(fabs(Number[NumStackTop])>1e20)
printf(" %.20e\n",Number[NumStackTop]);
else
printf(" %f\n",Number[NumStackTop]);
isEnd=0;
}

}//主循环结束

}//主函数结束

相关主题
文本预览
相关文档 最新文档