`
carolaif
  • 浏览: 70470 次
  • 性别: Icon_minigender_2
  • 来自: 大连
最近访客 更多访客>>
社区版块
存档分类
最新评论

C程序设计语言(第二版) 4-6

阅读更多
#include<stdlib.h> 
#include<stdio.h> 
#include<ctype.h> 
#include<math.h> 
#include<string.h>
 
#define MAXOP 100 

#define TRUE 1 
#define FALSE 0 

#define MAX_ID_LEN  32 
#define MAXVARS     30 

#define NUMBER       0 
/* 4-6 these are new for this exercise*/ 
#define IDENTIFIER   1 
#define ENDSTRING    2 

/* 4-6 end of new stuff */ 
/* 4-6 this is new for this program */ 
struct varType{ 
   char name[MAX_ID_LEN]; 
   double val; 
}; 
/* 4-6 End of new stuff */ 

int Getop(char s[]); 
void push(double val); 
double pop(void); 
void showTop(void); 
void duplicate(void); 
void swapItems(void); 
//void clearStack(); 
//void dealWithName(char s[]);

/* 4-6 this is new for this program */ 
/* Changed clearStack(void) to clearStacks(struct varType var[])*/ 
void clearStacks(struct varType var[]); 
void dealWithName(char s[],  struct varType var[]); 
void dealWithVar(char s[], struct varType var[]); 
 
int pos = 0; 
struct varType last; 
 
/* 4-6 End of new stuff */ 
 



 
int main(void) 
{ 

    int type; 
    double op2; 
    char s[MAXOP]; 
    int flag = TRUE; 
	struct varType var[MAXVARS]; 
	
	clearStacks(var); 
    while((type = Getop(s)) != EOF) 
    { 
        switch(type) 
        { 
            case NUMBER: 
                push(atof(s)); 
                break; 
			case IDENTIFIER: 
				dealWithName(s, var); 
				break; 
            case '+': 
                push(pop() + pop()); 
				break; 
            case '*': 
                push(pop() * pop()); 
                break; 
            case '-': 
                op2 = pop(); 
                push(pop()- op2); 
                break; 
            case '/': 
                op2 = pop(); 
                if(op2) 
                    push(pop() / op2); 
                else 
                    printf("\nError: division by zero!"); 
                break; 
            case '%': 
                op2 = pop(); 
                if(op2) 
                    push(fmod(pop(), op2)); 
                else 
                    printf("\nError: division by zero!"); 
                break; 
            case '?': 
                showTop(); 
                break; 
            case '#': 
                duplicate(); 
                break; 
            case '~': 
                swapItems(); 
                break; 
            case '!': 
                clearStacks(var); 
            case '\n': 
                printf("\n\t%.8g\n", pop()); 
                break; 

			  /* 4-6 this is new for this program */ 
			  case ENDSTRING: 
				 break; 
			  case '=': 
				 pop(); 
				 var[pos].val = pop(); 
				 last.val = var[pos].val; 
				 push(last.val); 
				 break; 
			  case '<': 
				 printf("The last variable used was: %s (value == %g)\n", last.name, last.val); 
				 break; 
			  /* 4-6 End of new stuff */ 


            default: 
                printf("\nError: unknown command %s.\n", s); 
                break; 
        } 
    } 
    return EXIT_SUCCESS; 
}    

#define MAXVAL 100 
 
int sp = 0;          /* Next free stack position. */ 
double val[MAXVAL];  /* value stack. */ 
 
/* push: push f onto stack. */ 
void push(double f) 
{ 
    if(sp < MAXVAL) 
        val[sp++] = f; 
    else 
         printf("\nError: stack full can't push %g\n", f); 
} 
 
/*pop: pop and return top value from stack.*/ 
double pop(void) 
{ 
    if(sp > 0) 
        return val[--sp]; 
    else 
    { 
        printf("\nError: stack empty\n"); 
        return 0.0; 
    } 
} 
 
void showTop(void) //?
{ 
	double top=val[sp];
	
	printf("%u\n",top);
} 
 
 
void duplicate(void) //#
{ 
	int top=sp-1;
	double topVal;
	topVal=val[top];
	val[top+1]=topVal;
	sp++;
} 

void swapItems(void) //~
{ 
	double temp;
	int top= sp;
	int secTop = sp-1;
	temp = val[top];
	val[top]=val[secTop];
	val[secTop]=temp;


} 
 
/* 4-6 this is new for this program */ 
/* Altered to clear both the main stack and that of the variable 
structure */ 
void clearStacks(struct varType var[]) 
{ 
   int i; 
    
   /* Clear the main stack by setting the pointer to the bottom. */ 
   sp = 0; 
    
   /* Clear the variables by setting the initial element of each name 
   to the terminating character. */ 
   for( i = 0; i < MAXVARS; ++i) 
   { 
      var[i].name[0] = '\0'; 
      var[i].val = 0.0; 
   } 
} 
 
/* a string/name may be either a maths function or a variable */ 
void dealWithName(char s[], struct varType var[]) 
{ 
   double op2; 
    
   if(!strcmp(s, "sin")) 
      push(sin(pop())); 
   else if(!strcmp(s, "cos")) 
      push(cos(pop())); 
   else if (!strcmp(s, "exp")) 
      push(exp(pop())); 
   else if(!strcmp(s, "pow")) 
   { 
      op2 = pop(); 
      push(pow(pop(), op2)); 
   } 
   /* Finally if it isn't one of the supported maths functions we have 
a  
      variable to deal with. */ 
   else  { 
      dealWithVar(s, var); 
   } 
} 
 
/* Our identifier is not one of the supported maths function so we have  
   to regard it as an identifier. */ 
void dealWithVar(char s[], struct varType var[]) 
{ 
   int i = 0; 
    
   while(var[i].name[0] != '\0' && i < MAXVARS-1) 
   { 
      if(!strcmp(s, var[i].name)) 
      { 
         strcpy(last.name, s); 
                   last.val = var[i].val; 
         push(var[i].val); 
         pos = i; 
         return; 
      } 
      i++; 
   } 
    
   /* variable name not found so add it */ 
   strcpy(var[i].name, s); 
   /* And save it to the last variable */ 
   strcpy(last.name, s); 
   push(var[i].val); 
   pos = i; 
} 
/* 4-6 End of new stuff */ 




int getch(void); 
void unGetch(int); 
 
/* Getop: get next operator or numeric operand. */ 
int Getop(char s[]) 
{ 
    int i = 0; 
    int c; 
    int next; 
 
    /* Skip whitespace */ 
    while((s[0] = c = getch()) == ' ' || c == '\t') 
        ; 
    s[1] = '\0'; 

	//如果读入的是标识符...字母
	if(isalpha(c)) 
	{ 
		i = 0; 
        while(isalpha(s[i++] = c )) 
			c = getch();      
		s[i - 1] = '\0'; 
		if(c != EOF) 
			unGetch(c); 
		return IDENTIFIER; 
	} 
 
    /* Not a number but may contain a unary minus. */ 
    if(!isdigit(c) && c != '.' && c != '-') 
        return c;                
 
    if(c == '-') 
    { 
        next = getch(); 
        if(!isdigit(next) && next != '.') 
        { 
           return c; 
        } 
        c = next; 
    } 
	   else 
        c = getch(); 
  
    while(isdigit(s[++i] = c)) 
		c = getch(); 
    if(c == '.')                        /* Collect fraction part. */ 
        while(isdigit(s[++i] = c = getch())) 
                        ; 
    s[i] = '\0'; 
    if(c != EOF) 
        unGetch(c); 
    return NUMBER; 
} 
 
#define BUFSIZE 100 
 
char buf[BUFSIZE]; 
int bufp = 0; 
 
/* Getch: get a ( possibly pushed back) character. */ 
int getch(void) 
{ 
     return (bufp > 0) ? buf[--bufp]: getchar(); 
} 
 
/* unGetch: push character back on input. */ 
void unGetch(int c) 
{ 
    if(bufp >= BUFSIZE) 
        printf("\nUnGetch: too many characters\n"); 
    else 
        buf[bufp++] = c; 
}  

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics