算數表示式求值--c語言課程設計

niuniuyi~發表於2021-01-01

算數表示式求值

1.可多位的整數運算
2.進行加減乘除四則運算
3.可進行多次計算

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>
#define Stack_Size 100
#define maxn 110

int color(int num){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),num);
	return 0;
}

char priority[7][7]={ 
    {'>','>','<','<','<','>','>'},  
    {'>','>','<','<','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'<','<','<','<','<','=','0'},   // 此行"("=")"表示左右括號相遇,括號內運算已完成 
    {'>','>','>','>','0','>','>'},  
    {'<','<','<','<','<','0','='}    // "=" 表示整個表示式求值完畢 
	};                               //  "0"表示不可能出現這種情況 ( 語法錯誤 )
 
struct OPTR{
	char elem[Stack_Size];//用來存放運算子 
	int top;//棧頂 
};

struct OPND{
	int elem[Stack_Size];//用來存放運算元 
	int top;//棧頂 
};

void InitStack1(struct OPTR *S)//構造運算子棧(空棧) 
{ 
	S->top=-1; 
}

void InitStack2(struct OPND *S)//構造運算元棧(空棧) 
{ 
	S->top=-1; 
}

void Push1(struct OPTR *S,char ch)// 運算子棧插入ch為新的棧頂元素 
{
	if(S->top==Stack_Size-1){
	    printf("棧已滿,入棧失敗!");
	    return;
	} 
	S->top++;      
	S->elem[S->top]=ch;
	return;
} 

void Push2(struct OPND *S,int ch)// 運算元棧插入ch為新的棧頂元素 
{
	if(S->top==Stack_Size-1){
	    printf("棧已滿,入棧失敗!");
	    return;
	} 
	S->top++;     
	S->elem[S->top]=ch;
	return;
} 

void Pop1(struct OPTR *S)//刪除運算子棧S的棧頂元素 ,用p返回其值 
{
	if(S->top==-1){
		printf("棧空,出棧失敗!");
		return;
	}
//	*p=S->elem[S->top];//棧頂元素賦給p
	S->top--;//修改棧頂指標
	return; 
}

void Pop2(struct OPND *S)//刪除運算元棧S的棧頂元素 ,用p返回其值 
{
	if(S->top==-1){
		printf("棧空,出棧失敗!");
		return;
	}
//	*p=S->elem[S->top];//棧頂元素賦給p
	S->top--;//修改棧頂指標
	return; 
}

char GetTop1(struct OPTR *S)//用p返回運算子棧S的棧頂元素
{
	if(S->top==-1){
		printf("棧空,取值失敗!");
		return -1; 
	} 
	char p=S->elem[S->top];//棧頂元素賦值給p
	return p; 
} 

int GetTop2(struct OPND *S)//用p返回運算元棧S的棧頂元素
{
	if(S->top==-1){
		printf("棧空,取值失敗!");
		return -1; 
	} 
	int p=S->elem[S->top];//棧頂元素賦值給p
	return p; 
} 

int In(char ch)//判斷ch是否為運算子 
{
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#'||ch=='='){
		return 0;
    }
    return -1;
}

char Precede(char t1,char t2)//判斷運算子t1和t2的優先順序 
{
	int i,j;
	switch(t1){
		case'+':i=0;break;
        case'-':i=1;break;
		case'*':i=2;break;
		case'/':i=3;break;
		case'(':i=4;break;
		case')':i=5;break;
		case'#':i=6;break;  // #是表示式的結束符		
	}
	switch(t2){
		case'+':j=0;break;
        case'-':j=1;break;
		case'*':j=2;break;
		case'/':j=3;break;
		case'(':j=4;break;
		case')':j=5;break;
		case'#':j=6;break;
	}
	return priority[i][j];
}

int Operate(int a,char theta,int b)//對a和b進行二元運算theta
{
	if(theta=='+') return a+b;
	if(theta=='-') return b-a;
	if(theta=='*') return a*b;
	if(theta=='/') return b/a;
} 



int main(){
	system("mode 100,30");
	int flag;
	do{
	struct OPTR *S1;
	S1=(struct OPTR *)malloc(sizeof(struct OPTR));
	InitStack1(S1);
	struct OPND *S2;
	S2=(struct OPND *)malloc(sizeof(struct OPND));
	InitStack2(S2);
	Push1(S1,'#');
	char s[maxn]; 
	color(11);
	printf("請輸入算數表示式(正整數),並以=結束\n");
	scanf("%s",&s);
	char c=s[0];
	int k=1;
	while(c!='='||GetTop1(S1)!='#'){//表示式未讀完或者運算子未完 
		int y=0;
		if(c>='0'&&c<='9'){
			while(c>='0'&&c<='9'){//讀入連續的數字 
				y=y*10+(c-'0');
				c=s[k++];
			}
			Push2(S2,y); 
		}
		else{
				if(In(c)==-1){
				printf("運算子或表示式不合法!計算失敗!");
				return 0;
			}
			char x;
			int m,n;
			switch(Precede(GetTop1(S1),c)){//不是運算元則說明是運算子 ,和運算子棧的頂元素進行優先順序比較 
				case'<'://棧頂元素優先順序低
				    Push1(S1,c);
					c=s[k++];
					break;
				case'=':
				    Pop1(S1);//脫括號 
					c=s[k++];//讀取下一個字元 
					break;	
				case'>':
				    x=GetTop1(S1);Pop1(S1);
					m=GetTop2(S2);Pop2(S2);	
					n=GetTop2(S2);Pop2(S2); 
					Push2(S2,Operate(m,x,n));
					break;
				default:
				     printf("語法錯誤"); break;	
			} 
		} 
	}
	int result=GetTop2(S2);
	printf("%d",result);
	color(3);
	printf("\n是否繼續計算1/0:");
    scanf("%d",&flag);
    if(flag==0){
    	printf("☆☆感謝您的使用 ☆☆"); 
	}
    }while(flag!=0);
return 0; 	
}

相關文章