棧計算器c語言
1. 計算機c語言中 什麼是棧和隊列
棧(Stack)是僅限制在表的一端進行插入和刪除運算的線性表,稱插入、刪除這一端為棧頂,另一端稱為棧底。表中無元素時為空棧。棧 的修改是按後進先出的原則進行的,我們又稱棧為LIFO表(Last In First Out)。通常棧有順序棧和鏈棧兩種存儲結構。 棧的基本運算有六種: ·構造空棧:InitStack(S) ·判棧空: StackEmpty(S) ·判棧滿: StackFull(S) ·進棧: Push(S,x) ·退棧: Pop(S) ·取棧頂元素:StackTop(S) 在順序棧中有"上溢"和"下溢"的現象。 ·"上溢"是棧頂指針指出棧的外面是出錯狀態。 ·"下溢"可以表示棧為空棧,因此用來作為控制轉移的條件。 順序棧中的基本操作有六種:·構造空棧·判棧空·判棧滿·進棧·退棧·取棧頂元素 鏈棧則沒有上溢的限制,因此進棧不要判棧滿。鏈棧不需要在頭部附加頭結點,只要有鏈表的頭指針就可以了。 鏈棧中的基本操作有五種:·構造空棧·判棧空·進棧·退棧·取棧頂元素 隊列(Queue)是一種運算受限的線性表,插入在表的一端進行,而刪除在表的另一端進行,允許刪除的一端稱為隊頭(front),允許插入的 一端稱為隊尾(rear) ,隊列的操作原則是先進先出的,又稱作FIFO表(First In First Out) 。隊列也有順序存儲和鏈式存儲兩種存儲結 構。 隊列的基本運算有六種: ·置空隊:InitQueue(Q) ·判隊空:QueueEmpty(Q) ·判隊滿:QueueFull(Q) ·入隊:EnQueue(Q,x) ·出隊:DeQueue(Q) ·取隊頭元素:QueueFront(Q) 順序隊列的"假上溢"現象:由於頭尾指針不斷前移,超出向量空間。這時整個向量空間及隊列是空的卻產生了"上溢"現象。 為了克服"假上溢"現象引入循環向量的概念,是把向量空間形成一個頭尾相接的環形,這時隊列稱循環隊列。 判定循環隊列是空還是滿,方法有三種: ·一種是另設一個布爾變數來判斷; ·第二種是少用一個元素空間,入隊時先測試((rear+1)%m = front)? 滿:空; ·第三種就是用一個計數器記錄隊列中的元素的總數。 隊列的鏈式存儲結構稱為鏈隊列,一個鏈隊列就是一個操作受限的單鏈表。為了便於在表尾進行插入(入隊)的操作,在表尾增加一個尾指 針,一個鏈隊列就由一個頭指針和一個尾指針唯一地確定。鏈隊列不存在隊滿和上溢的問題。在鏈隊列的出隊演算法中,要注意當原隊中只 有一個結點時,出隊後要同進修改頭尾指針並使隊列變空。
2. 怎樣用c語言編一個簡單的計算器最簡單的
//簡單計算器,含加減乘除、乘方運算。
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2 因為在math.h中已定義OVERFLOW的值為3,故去掉此行
typedef int Status; // Status是函數的類型,其值是函數結果狀態代碼,如OK等
typedef int Boolean; // Boolean是布爾類型,其值是TRUE或FALSE
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
//***************************************************************************
//棧的儲存結構
typedef struct{
//運算符棧
char *base;
char *top;
int stacksize;
}SqStack1;
typedef struct{
//運算數棧
float *base;
float *top;
int stacksize;
}SqStack2;
//***************************************************************************
//以下是運算符棧的基本操作函數
Status InitStack(SqStack1 &S){
//初始化一個棧
S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack
Status DestroyStack(SqStack1 &S){
//銷毀棧S
free(S.top);
free(S.base);
return OK;
}//DestroyStack
char GetTop(SqStack1 S){
//若棧不空,則返回S的棧頂元素,並返回OK;否則返回ERROR
if(S.top==S.base)return ERROR;
return *(S.top-1);
}//Gettop
Status Push(SqStack1 &S,char e){
//插入元素e為新的棧頂元素
if(S.top-S.base>=S.stacksize){
//棧滿,追加儲存空間
S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}//Push
Status Pop(SqStack1 &S,char &e){
//若棧不空,則刪除S的棧頂元素,用e返回其值;並返回OK;否則返回ERROR
if(S.top==S.base)return ERROR;
e=*(--S.top);
return OK;
}//Pop
//***************************************************************************
//以下是運算數棧的基本操作函數
Status InitStack(SqStack2 &S){
//初始化一個棧
S.base=(float *)malloc(STACK_INIT_SIZE*sizeof(float));
if(!S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack
Status DestroyStack(SqStack2 &S){
//銷毀棧S
free(S.top);
free(S.base);
return OK;
}//DestroyStack
float GetTop(SqStack2 S){
//若棧不空,則返回S的棧頂元素,並返回OK;否則返回ERROR
if(S.top==S.base)return ERROR;
return *(S.top-1);
}//Gettop
Status Push(SqStack2 &S,float e){
//插入元素e為新的棧頂元素
if(S.top-S.base>=S.stacksize){
//棧滿,追加儲存空間
S.base=(float *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(float));
if(!S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}//Push
Status Pop(SqStack2 &S,float &e){
//若棧不空,則刪除S的棧頂元素,用e返回其值;並返回OK;否則返回ERROR
if(S.top==S.base)return ERROR;
e=*(--S.top);
return OK;
}//Pop
//***************************************************************************
//以下是相關的運算符判斷函數
char Precede(char A,char B){
//比較運算符A, B的優先關系,A,B的范圍僅限於'+','-','*','/','^','(',')','='
//返回'>','<','='
switch(A){
case '+':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '<';
case '/':return '<';
case '^':return '<';
case '(':return '<';
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '-':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '<';
case '/':return '<';
case '^':return '<';
case '(':return '<';
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '*':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '>';
case '/':return '>';
case '^':return '<';
case '(':return '<';
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '/':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '>';
case '/':return '>';
case '^':return '<';
case '(':return '<';
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '^':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '>';
case '/':return '>';
case '^':return '>';
case '(':return '<';
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '(':switch(B){
case '+':return '<';
case '-':return '<';
case '*':return '<';
case '/':return '<';
case '^':return '<';
case '(':return '<';
case ')':return '=';
case '=':printf("表達式錯誤!\n");exit(0);
default:printf("表達式錯誤!\n");exit(0);
}
case ')':switch(B){
case '+':return '>';
case '-':return '>';
case '*':return '>';
case '/':return '>';
case '^':return '>';
case '(':printf("表達式錯誤!\n");exit(0);
case ')':return '>';
case '=':return '>';
default:printf("表達式錯誤!\n");exit(0);
}
case '=':switch(B){
case '+':return '<';
case '-':return '<';
case '*':return '<';
case '/':return '<';
case '^':return '<';
case '(':return '<';
case ')':printf("表達式錯誤!\n");exit(0);
case '=':return '=';
default:printf("表達式錯誤!\n");exit(0);
}
default:printf("表達式錯誤!\n");exit(0);
}
}//Precede
Status InOP(char c){
//判斷c是否是運算符,是則返回TRUE,否則返回FALSE
switch(c){
case '+':return TRUE;
case '-':return TRUE;
case '*':return TRUE;
case '/':return TRUE;
case '^':return TRUE;
case '(':return TRUE;
case ')':return TRUE;
case '=':return TRUE;
default:return FALSE;
}
}//InOP
//***************************************************************************
float Operate(float a,char theta,float b){
switch(theta){
case '+':return a+b;
case '-':return a-b;
case '*':return a*b;
case '/':
if(b==0){
printf("分母不能為0!\n");
exit(0);
}
else return a/b;
case '^':
if(a==0&&b<=0){
printf("0的指數必須大於0!\n");
exit(0);
}
else return (float)pow(a,b);
default:printf("表達式錯誤!\n");exit(0);
}
}//Operate
Status EvaluateExpression(){
//算術表達式求值
char c,x,theta,prec;
//c是每次讀取的字元,x是存放脫括弧後的多餘的括弧,theta是運算符,prec是c的前一個字元
float a,b,result;//a、b是每次從運算數棧中取出的要進行運算的數,result存放最終結果
float cc,flag,ii,minus=1;
//cc存放由字元串轉化而來的浮點數,flag用於標記是否已讀取過小數點,
//ii存放小數部分需要縮小的倍數,minus用於記錄該數前是否有負號
SqStack1 OPTR;
SqStack2 OPND;
InitStack(OPTR);InitStack(OPND);
Push(OPTR,'=');
prec='=';scanf("%c",&c);
while(c!='='||GetTop(OPTR)!='='){
cc=0;flag=0;ii=10;
if(c=='-'&&(prec=='='||prec=='(')){minus=-1;prec=c;scanf("%c",&c);}
//若某「-」前面是「=」(第一個符號就是「-」)或「(」,則此為負號,不是減號
else if(!InOP(c)){
while(!InOP(c)){
if(c>=48&&c<=57){
if(flag==0)cc=cc*10+c-48;//小數點之前
else if(flag==1){cc=cc+(c-48)/ii;ii*=10;}//小數點之後
else {printf("小數點錯誤!\n");exit(0);}//小數點有錯
}
else if(c=='.')flag++;//讀到小數點
else {printf("表達式錯誤!\n");exit(0);}
prec=c;scanf("%c",&c);
}
cc*=minus;minus=1;
Push(OPND,cc);
}//不是運算符則進OPND棧
else
switch(Precede(GetTop(OPTR),c)){
case '<':Push(OPTR,c);prec=c;scanf("%c",&c);break;//棧頂元素優先順序低
case '=':Pop(OPTR,x);prec=c;scanf("%c",&c);break;//脫括弧並接收下一字元
case '>'://退棧並將運算結果入棧
Pop(OPTR,theta);
Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}
}
result=GetTop(OPND);
printf("%f\n",result);
//DestroyStack(OPTR);
//DestroyStack(OPND);
return OK;
}//EvaluateExpression
void main(){
printf(" **********************\n");
printf(" * 歡迎使用計算器! *\n");
printf(" **********************\n");
printf("請輸入表達式,以「=」結束:\n");
printf("(支持實數間的加(+)、減(-)、乘(*)、除(/)、乘方(^)、單目減(-)運算)\n");
EvaluateExpression();
exit (0);
}