对计算器程序的改善
用链栈实现并增加三角函数、反三角函数、平方根功能
#include
#include
#include
#include<string.h>
#define STACK_INIT_SIZE 100
/*定义栈初始容量*/
#define STACK_INCREMENT 10
/*定义栈增加容量*/
#define M 100
/*定义字符串的长度*/
#define DEBUG 0
/*定义调试模式*/
typedef enum{
OK=1,
ERROR=0
}Status;
typedef enum{
TRUE=1,
FALSE=0
}Bool;
typedef struct{
void* pBase;
void* pTop;
int elementSize;
int stackSize;
}Stack;
Stack* Stack_Construct(int sizeOfElement);
/*功能:构造一个栈
*参数:栈元素类型的长度
*返回:构造成功返回新构造的栈;否则返回NULL
*/
Stack* Stack_Construct(int sizeOfElement){
Stack *pStack;
pStack=(Stack*)malloc(sizeof(Stack));
if(pStack==NULL){
return NULL;
}
pStack->pBase=malloc(STACK_INIT_SIZE*sizeOfElement);
if(pStack->pBase==NULL){
free(pStack);
return NULL;
}
pStack->pTop=pStack->pBase;
pStack->elementSize=sizeOfElement;
pStack->stackSize=STACK_INIT_SIZE;
return pStack;
}
Status Stack_Init(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:成功返回OK;否则返回ERROR
*/
void Stack_Free(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:无
*/
void Stack_Clear(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:无
*/
Bool Stack_IsEmpty(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:若栈为空,返回true;否则返回false
*/
Bool Stack_IsFull(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:若栈已满,返回true;否则返回false
*/
int Stack_Length(Stack *pStack);
/*参数:pStack是指向栈的指针
*返回:栈的长度
*/
//char Stack_GetTop(Stack *pStack);
Status Stack_GetTop(Stack *pStack,void *pElem);
/*功能:取出栈顶元素
*参数:pStack是指向栈的指针
*返回:返回栈顶元素
*/
Status Stack_Push(Stack *pStack,void *pVoid);
/*功能:将pVoid指向的数据压入pStack指向的栈
*参数:pStack是指向栈的指针,pVoid是指向数据的指针
*返回:成功返回OK;否则返回ERROR
*/
Status Stack_Pop(Stack *pStack,void *pVoid);
/*功能:将pStack指向的栈的元素弹出存入pVoid指向的内存
*参数:pStack是指向栈的指针,pVoid是指向数据的指针
*返回:成功返回OK;否则返回ERROR
*/
//Status Stack_Traverse(Stack *pStack,Status(*visit)());
/*功能:对pStack指向的栈的每个元素执行visit操作
*参数:pStack是指向栈的指针,visit是函数指针
*返回:成功返回OK;失败返回ERROR
*/
float ConvertToFloat(char m[M],float r);
/*功能:将数字串转换为浮点数
*参数:m[M]是原数字串,r是浮点数即结果
*返回:返回结果浮点数r
*/
int Judge(char x);
/*功能:判断运算符的类型并分级
*参数:x是运算符的符号
*返回:字符所代表的级数
*/
int Culculate(int x1,int x2,char s);
/*功能:执行计算
*参数:x1是第一个数字
x2是第二个数字
s是运算符
*返回:返回运算结果
*/
Status Check(char left,char right);
/*功能:判断左右括号是否匹配
*参数:left是左括号,right是右括号
*返回:若左右括号匹配返回OK,否则返回ERROR
*/
Status CharIsSymbol(char c);
/*功能:判断字符是运算符
*参数:c是字符
*返回:若c为运算符返回OK;否则返回ERROR
*/
Status CharIsNum(char d);
/*功能:判断字符是数字
*参数:d是字符
*返回:若d是数字返回OK;否则返回ERROR
*/
int DoSingleOperation(char s[]);
/*功能:执行一行字符的计算
*参数:s[]是这一行字符串
*返回:返回运算结果
*/
Status Stack_Init(Stack *pStack){
pStack->pBase=malloc(STACK_INIT_SIZE*sizeof(char));
if(pStack->pBase==NULL){
return ERROR;
}
pStack->pTop=pStack->pBase;
pStack->stackSize=STACK_INIT_SIZE;
return OK;
}
void Stack_Free(Stack *pStack){
free(pStack->pBase);
pStack->pBase=NULL;
pStack->pTop=NULL;
pStack->stackSize=0;
free(pStack);
return;
}
void Stack_Clear(Stack *pStack){
pStack->pTop=pStack->pBase;
}
Bool Stack_IsEmpty(Stack *pStack){
if(pStack->pTop==pStack->pBase){
return TRUE;
}
else{
return FALSE;
}
}
Bool Stack_IsFull(Stack *pStack){
if((char*)pStack->pTop-(char*)pStack->pBase==pStack->stackSize){
return TRUE;
}
else{
return FALSE;
}
}
int Stack_Length(Stack *pStack){
return ((char*)pStack->pTop-(char*)pStack->pBase)/pStack->elementSize;
}
Status Stack_GetTop(Stack *pStack,void *pElem){
int* pt;
char* pt2;
if(pStack->pTop==pStack->pBase){
return ERROR;
}
if(pStack->elementSize == sizeof(int))
{
pt = (int*)((char*)pStack->pTop -pStack->elementSize);
*((int*)pElem) = *pt;
}else
{
pt2 = (char*)((char*)pStack->pTop -pStack->elementSize);
*((char*)pElem) = *pt2;
}
//pElem=(char*)pStack->pTop - pStack->elementSize;
return OK;
}
Status Stack_Push(Stack *pStack,void *pElem){
int newSize;
int* pt;
char* pt2;
void *pTemp;
if(Stack_Length(pStack)>=pStack->stackSize){
newSize=pStack->stackSize+STACK_INCREMENT;
pElem=realloc(pStack->pBase,newSize*sizeof(pStack->elementSize));
if(pTemp==NULL){
return ERROR;
}
else{
pStack->pBase=pTemp;
pStack->pTop = (char*)pStack->pBase+pStack->stackSize;
pStack->stackSize=newSize;
}
}
if(pStack->elementSize == sizeof(int))
{
pt = (int*)pStack->pTop;
*pt = *((int*)pElem);
}else
{
pt2 = (char*)pStack->pTop;
*pt2 = *((char*)pElem);
}
//*(pStack->pTop)=*pElem;
#if DEBUG
printf("%d",pStack->pTop); /*调试语句*/
#endif
pStack->pTop=(char*)pStack->pTop+pStack->elementSize;
#if DEBUG
printf("%d",pStack->pTop); /*调试语句*/
#endif
return OK;
}
Status Stack_Pop(Stack *pStack,void *pElem){
if(pStack->pTop==pStack->pBase){
return ERROR;
}
else{
pStack->pTop=(char*)pStack->pTop-pStack->elementSize;
// *pElem=*(pStack->pTop);
return OK;
}
}
/*Status Stack_Traverse(Stack *pStack,Status(*visit)()){
int i,j;
j=Stack_Length(pStack);
for(i=0;ipBase[i]))==ERROR){
return ERROR;
}
}
return OK;
}*/
float ConvertToFloat(char m[M]){
int i=0;
float value=0;
while(m[i]!='\0'&&m[i]!='.'){
value=value*10+(m[i]-'0');
i=i+1;
}
if(m[i]=='\0'){
return value;
}
i=i+1;
int weight=0.1;
while(m[i]!='\0'){
value=value+(m[i]-'0')*weight;
weight=weight/10;
i=i+1;
}
return value;
}
int Judge(char x){
if (x == '(') {
return 4;
}
else if (x == '+' || x == '-') {
return 1;
}
else if (x == '*' || x == '/') {
return 2;
}
else if (x == '^') {
return 3;
}
else if (x == ')') {
return 0;
}
}
int Culculate(int x1,int x2,char s){
int result = 0;
switch(s){
case '+':{
result=x1+x2;
break;
}
case '-':{
result=x1-x2;
break;
}
case '*':{
result=x1*x2;
break;
}
case '/':{
result=x1/x2;
break;
}
case '^':{
result=pow((double)x1,x2);
break;
}
}
return result;
}
Status Check(char left,char right){
if(left=='('&&right==')'){
return OK;
}
else{
return ERROR;
}
}
Status CharIsSymbol(char c){
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='^'){
return OK;
}
else{
return ERROR;
}
}
Status CharIsNum(char d){
if(d>='0'&&d<='9'){
return OK;
}
else{
return ERROR;
}
}
int DoSingleOperation(char s[]){
Stack* pIntStack; /*这个栈存放数字*/
Stack* pSymbolStack; /*这个栈存放除括号外的符号*/
Stack* pSymbolStack_2; /*这个栈存放括号*/
Status sta;
pIntStack=Stack_Construct(sizeof(int));
pSymbolStack=Stack_Construct(sizeof(char));
pSymbolStack_2=Stack_Construct(sizeof(char));
int len,n;
len=strlen(s);
s[len]='#';
len++;
int i;
int a,b,c=0,d=0;
int topele_int;
char topele_c;
char x[M];
for(i=0;i++ ){
if(s[i]=='('){
Stack_Push(pSymbolStack_2,&s[i]);
}
else if(s[i]==')'){
Stack_GetTop(pSymbolStack_2,&topele_c);
if(Check(topele_c,s[i])==1){
Stack_Pop(pSymbolStack_2,&x[d++]);
}
else{
printf("括号不匹配\n"); /*判断括号是否匹配*/
return 0;
}
}
}
i=0;
if(s[0]=='+'||s[0]=='-'||s[0]=='*'||s[0]=='/'||s[0]=='^'){
printf("运算符不能在开头\n"); /*除括号外的运算符不能在字符串开始处*/
return 0;
}
while(s[i]!='#'){
int x=0;
if(CharIsNum(s[i])==OK){
while(s[i]>='0'&&s[i]<='9'){
x*=10;
x+=s[i++]-'0';
}
Stack_Push(pIntStack,&x);
continue;
}
else{
char theta=s[i];
while(Stack_IsEmpty(pSymbolStack)==0 ){ //&&Stack_GetTop(pSymbolStack)!='('&&Judge(Stack_GetTop(pSymbolStack))>=Judge(s[i])
Stack_GetTop(pSymbolStack,&topele_c);
if(topele_c =='(' || Judge(topele_c) < Judge(s[i]))
break;
Stack_GetTop(pIntStack,&a);
Stack_Pop(pIntStack,&topele_int); /*这里的topele_int没有用处*/
Stack_GetTop(pIntStack,&b);
Stack_Pop(pIntStack,&topele_int);
if(a==0&& topele_c =='/'){ //Stack_GetTop(pSymbolStack)
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c=Culculate(b,a,topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack,&c);
Stack_Pop(pSymbolStack,&topele_c);
}
sta = Stack_GetTop(pSymbolStack,&topele_c);
if(sta== OK &&Judge(theta)==0&&Judge(topele_c)==4){
Stack_Pop(pSymbolStack,&topele_c);
}
if(Judge(theta)!=0){
Stack_Push(pSymbolStack,&theta);
}
i++;
}
}
while(Stack_IsEmpty(pSymbolStack)==0){
Stack_GetTop(pSymbolStack,&topele_c);
Stack_GetTop(pIntStack,&a);
Stack_Pop(pIntStack,&topele_int);
Stack_GetTop(pIntStack,&b);
Stack_Pop(pIntStack,&topele_int);
if(a==0&& topele_c=='/'){
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c=Culculate(b,a,topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack,&c);
Stack_Pop(pSymbolStack,&topele_c);
}
Stack_GetTop(pIntStack,&a);
printf("%d\n",a);
return a;
}
//int main(){
// char all[100]={0};
// int result=0;
// FILE *fp=fopen("C:/Users/zh/Desktop/1.txt","r"); /*以只读模式打开文件1*/
// if(fp==0){
// printf("The first txt can not be opened!"); /*若打开文件1失败,结束程序,否则继续运行*/
// return 0;
// }
// FILE *fp2=fopen("C:/Users/zh/Desktop/2.txt","w"); /*以写入模式打开文件2*/
// while(!feof(fp)){
// fgets(all,100,fp); /*对文件1逐行读取*/
// int len=strlen(all);
// if(len==0){ /*若为空行,则结束此次循环,开始执行下一行的程序*/
// continue;
// }
// if(all[len-1]=='\n'){
// all[len-1]='\0';
// }
// printf("%s\n",all);
// result=DoSingleOperation(all); /*对读入的一行进行运算*/
// fprintf(fp2,"%d\n",result); /*对读入的一行的运算结果打印到文件2中*/
// }
// fclose(fp); /*关闭文件1*/
// fclose(fp2); /*关闭文件2*/
// return 0;
//}
int main(){
int i;
printf("Please choose the mode of operation\nFrom file to file:0\tFrom the keyboard:1\n");
scanf("%d",&i);
switch(i){
case 0:{
char all[M]={0};
int result=0;
FILE *fp=fopen("C:/Users/zh/Desktop/1.txt","r"); /*以只读模式打开文件1*/
if(fp==0){
printf("The first txt can not be opened!"); /*若打开文件1失败,结束程序,否则继续运行*/
return 0;
}
FILE *fp2=fopen("C:/Users/zh/Desktop/2.txt","w"); /*以写入模式打开文件2*/
while(!feof(fp)){
fgets(all,M,fp); /*对文件1逐行读取,直到文件尾*/
int len=strlen(all);
if(len==0){ /*若为空行,则结束此次循环,开始执行下一行的程序*/
continue;
}
if(all[len-1]=='\n'){
all[len-1]='\0'; /*去掉每行字符的回车符*/
}
printf("%s\n",all);
result=DoSingleOperation(all); /*对读入的一行进行运算*/
fprintf(fp2,"%d\n",result); /*对读入的一行的运算结果打印到文件2中*/
}
fclose(fp); /*关闭文件1*/
fclose(fp2); /*关闭文件2*/
break;
}
case 1:{
printf("Please input the exxpression\n");
int j=0,result;
char all[M]={0};
char y;
gets(all);
/*while((y=getchar())!='\n'){
all[j]=y;
j++;
}*/
result=DoSingleOperation(all);
printf("%d\n",result);
break;
}
default:{
printf("error number\n");
break;
}
}
return 0;
}
三角和反三角函数再加上,代码改动量比较大
链栈的话,需要改数据结构,大体如下:
链表栈计算器代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define M 100
/*定义字符串的长度*/
//#define DEBUG 1
/*定义调试模式*/
typedef enum {
OK = 1,
ERROR = 0
}Status;
typedef enum {
TRUE = 1,
FALSE = 0
}Bool;
//数据
typedef struct _datatype
{
int dt;
char dc;
}Datatype;
//链栈结构
typedef struct _stacknode {
Datatype data;
struct _stacknode* next;
}Stack;
Stack* Stack_init(Stack* pStack)
{
pStack = (Stack*)malloc(sizeof(Stack));
pStack->next = 0;
return pStack;
}
void Stack_Free(Stack* pStack)
{
Stack* p;
while (pStack)
{
p = pStack->next;
free(pStack);
pStack = p;
}
}
Bool Stack_IsEmpty(Stack* pStack)
{
if (pStack == 0 || pStack->next == 0)
return TRUE;
else
return FALSE;
}
Status Stack_GetTop(Stack* pStack, int f,int* d,char* c)
{
Stack* p = 0;
if (pStack == 0 || pStack->next == 0)
return ERROR;
p = pStack;
while (p->next)
{
p = p->next;
}
if (f == 0)
*d = p->data.dt;
else
*c = p->data.dc;
return OK;
}
Status Stack_Push(Stack* pStack, int d = 0, char c = 0)
{
Stack* p, * t;
t = (Stack*)malloc(sizeof(Stack));
t->next = 0;
if (c == 0)
t->data.dt = d;
else
t->data.dc = c;
if (pStack == 0)
{
pStack = t;
}
else
{
p = pStack;
while (p->next)
p = p->next;
p->next = t;
}
return OK;
}
//f=0表示int类型,其他值表示char
Status Stack_Pop(Stack* pStack)
{
Stack* p, * t;
if (pStack == 0 || pStack->next == 0)
return ERROR;
p = pStack;
t = p->next;
while (t->next)
{
p = p->next;
t = t->next;
}
p->next = 0;
/*if (f == 0)
*d = p->data.dt;
else
*c = p->data.dc;*/
free(t);
return OK;
}
int Judge(char x);
/*功能:判断运算符的类型并分级
*参数:x是运算符的符号
*返回:字符所代表的级数
*/
int Culculate(int x1, int x2, char s);
/*功能:执行计算
*参数:x1是第一个数字
x2是第二个数字
s是运算符
*返回:返回运算结果
*/
Status Check(char left, char right);
/*功能:判断左右括号是否匹配
*参数:left是左括号,right是右括号
*返回:若左右括号匹配返回OK,否则返回ERROR
*/
Status CharIsSymbol(char c);
/*功能:判断字符是运算符
*参数:c是字符
*返回:若c为运算符返回OK;否则返回ERROR
*/
Status CharIsNum(char d);
/*功能:判断字符是数字
*参数:d是字符
*返回:若d是数字返回OK;否则返回ERROR
*/
int DoSingleOperation(char s[]);
/*功能:执行一行字符的计算
*参数:s[]是这一行字符串
*返回:返回运算结果
*/
int Judge(char x) {
if (x == '(') {
return 4;
}
else if (x == '+' || x == '-') {
return 1;
}
else if (x == '*' || x == '/') {
return 2;
}
else if (x == '^') {
return 3;
}
else if (x == ')') {
return 0;
}
}
int Culculate(int x1, int x2, char s) {
int result = 0;
switch (s) {
case '+': {
result = x1 + x2;
break;
}
case '-': {
result = x1 - x2;
break;
}
case '*': {
result = x1 * x2;
break;
}
case '/': {
result = x1 / x2;
break;
}
case '^': {
result = pow((double)x1, x2);
break;
}
}
return result;
}
Status Check(char left, char right) {
if (left == '(' && right == ')') {
return OK;
}
else {
return ERROR;
}
}
Status CharIsSymbol(char c) {
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '^') {
return OK;
}
else {
return ERROR;
}
}
Status CharIsNum(char d) {
if (d >= '0' && d <= '9') {
return OK;
}
else {
return ERROR;
}
}
int DoSingleOperation(char s[]) {
Stack* pIntStack = 0;/*这个栈存放数字*/
Stack* pSymbolStack = 0;/*这个栈存放除括号外的符号*/
Stack* pSymbolStack_2 = 0;/*这个栈存放括号*/
Status sta;
pIntStack = Stack_init(pIntStack);
pSymbolStack = Stack_init(pSymbolStack);
pSymbolStack_2 = Stack_init(pSymbolStack_2);
int len, n;
len = strlen(s);
s[len] = '#';
len++;
int i;
int a, b, c = 0, d = 0;
int topele_int;
char topele_c;
char x[M];
for (i = 0; i < len; i++) {
if (s[i] == '(') {
Stack_Push(pSymbolStack_2, 0, s[i]);
}
else if (s[i] == ')') {
Stack_GetTop(pSymbolStack_2,1, &topele_int,&topele_c);
if (Check(topele_c, s[i]) == 1) {
Stack_Pop(pSymbolStack_2);
}
else {
printf("括号不匹配"); /*判断括号是否匹配*/
return 0;
}
}
}
i = 0;
if (s[0] == '+' || s[0] == '-' || s[0] == '*' || s[0] == '/' || s[0] == '^') {
printf("运算符不能在开头"); /*除括号外的运算符不能在字符串开始处*/
return 0;
}
while (s[i] != '#') {
int x = 0;
if (CharIsNum(s[i]) == OK) {
while (s[i] >= '0' && s[i] <= '9') {
x *= 10;
x += s[i++] - '0';
}
Stack_Push(pIntStack, x);
continue;
}
else {
char theta = s[i];
while (Stack_IsEmpty(pSymbolStack) == 0) { //&&Stack_GetTop(pSymbolStack)!='('&&Judge(Stack_GetTop(pSymbolStack))>=Judge(s[i])
Stack_GetTop(pSymbolStack,1,0, &topele_c);
if (topele_c == '(' || Judge(topele_c) < Judge(s[i]))
break;
Stack_GetTop(pIntStack, 0,&a,0);
Stack_Pop(pIntStack);
Stack_GetTop(pIntStack,0, &b,0);
Stack_Pop(pIntStack);
if (a == 0 && topele_c == '/') { //Stack_GetTop(pSymbolStack)
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c = Culculate(b, a, topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack,c);
Stack_Pop(pSymbolStack);
}
sta = Stack_GetTop(pSymbolStack,1,0, &topele_c);
if (sta == OK && Judge(theta) == 0 && Judge(topele_c) == 4) {
Stack_Pop(pSymbolStack);
}
if (Judge(theta) != 0) {
Stack_Push(pSymbolStack,0, theta);
}
i++;
}
}
while (Stack_IsEmpty(pSymbolStack) == 0) {
Stack_GetTop(pSymbolStack,1,0, &topele_c);
Stack_GetTop(pIntStack, 0,&a,0);
Stack_Pop(pIntStack);
Stack_GetTop(pIntStack,0, &b,0);
Stack_Pop(pIntStack);
if (a == 0 && topele_c == '/') {
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c = Culculate(b, a, topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack, c);
Stack_Pop(pSymbolStack);
}
Stack_GetTop(pIntStack,0, &a,0);
printf("%d\n", a);
return a;
}
int main() {
char all[100] = { 0 };
int result = 0;
FILE* fp = fopen("1.txt", "r"); /*以只读模式打开文件1*/
if (fp == 0) {
printf("The first txt can not be opened!"); /*若打开文件1失败,结束程序,否则继续运行*/
return 0;
}
FILE* fp2 = fopen("2.txt", "w"); /*以写入模式打开文件2*/
while (!feof(fp)) {
fgets(all, 100, fp); /*对文件1逐行读取*/
int len = strlen(all);
if (len == 0) { /*若为空行,则结束此次循环,开始执行下一行的程序*/
continue;
}
if (all[len - 1] == '\n') {
all[len - 1] = '\0';
}
printf("%s\n", all);
result = DoSingleOperation(all); /*对读入的一行进行运算*/
fprintf(fp2, "%d\n", result); /*对读入的一行的运算结果打印到文件2中*/
}
fclose(fp); /*关闭文件1*/
fclose(fp2); /*关闭文件2*/
return 0;
}