The C programing language 第四章,课后题

chap4.c

/*The C programing language 第四章,课后题 */
#include <stdio.h>
//#include "chap2.c"
#include <ctype.h>
//#include "chap1.c"
#include <string.h>
#include  "chap4_calculator.c" //for 4-3 to 4-10
#define abs(x)  ((x > 0) ? (x) : -(x))
extern void calculator();
/*
4-1 strindex function which return the position of the righmost 
occurrence of t  in s , or -1 if there in none.
*/
int strindex(char s[], char t[])
{
    int i, j, k;
    int position = -1; 
    for(i = 0; s[i] != '\0'; i++)
    {
       for(j=i,k=0; s[j]!='\0' && t[k]!='\0' && t[k]==s[j];k++,j++);

       if(k>0 && t[k]=='\0')
          position = i;
    }         

    return position;
}
/*
看了答案之后,发现从右边进行扫描对比,效率更高
 */
int _strindex(char s[], char t[])
{
    int i, j, k;

    for(i = strlen(s)-strlen(t); i>=0; i--)
    {
        for(j=i,k=0; s[j]!='\0' && t[k]!='\0' && t[k]==s[j];k++,j++);

        if(k>0 && t[k]=='\0')
            return i;
    }         

    return -1;
}
void evaluated_strindex()
{
     char s[] = "afscbajcbai";
     char t[] = "cba";
     printf("rightmost positon : %d \n",strindex(s, t));
     printf("rightmost positon : %d \n",_strindex(s, t));
}

/*
Exercise 4-2 
convert string s to double
test :  
char s[] = "10.12e10";
printf("%g \n", _atof(s));
*/
double _atof(char s[])
{
    double val, power;
    int i, sign, exp;

    for(i = 0; isspace(s[i]); i++)
       ;

    sign = (s[i] == '-') ? -1: 1;    
    if(s[i] == '-' || s[i] == '+')
       i++;
    for(val = 0.0; isdigit(s[i]); i++)
       val = 10.0 * val + (s[i]-'0');

    if(s[i] == '.')
       i++;

    for(power = 1.0; isdigit(s[i]); i++)   
    {
       val = 10.0 * val + (s[i] - '0'); //继续加上去
       power *= 10.0;  //计算正数要除的数,还原小数点后面的值
    }   

    val = sign * val / power;  //把正负,小数 还原

    if(s[i] == 'e' || s[i] == 'E')
    { 
       sign = (s[++i] == '-') ? -1 : 1;
       if(s[i] == '-' || s[i] == '+') 
          i++;
       for(exp = 0; isdigit(s[i]); i++) //计算e的值 跟之前atoi是一样的原理
           exp = 10 * exp + (s[i] - '0');
       if(sign == -1) // 负数
          while(exp-- > 0)
              val /=10;
       else //正数
          while(exp-- > 0)
              val *= 10;
    }   
   return  val;

}
/* from 4-3  to 4-10 */
void calculator_()
{
   calculator();
}
/*
4-12 
atoi : convert n to  characters in s  by calling a recursive routine 
*/
void itoa(int n, char s[]) {
    static int i = 0;

    if (n/10)
        itoa(n/10, s);
    else {
        if (n < 0)
        s[i++] = '-';
    }
    // recursive 
    s[i++] = abs(n%10) + '0';
    s[i] = '\0';
}
/*4-13
reverse : reverses string  s in place
*/
void reverse(char s[])
{
    void reverse_r(char [], int index, int len);
    reverse_r(s, 0, strlen(s));
}
/*
reverse : reverses string s in place ;recrusive
*/
void reverse_r(char s[], int index, int len)
{
    int temp, j;
    j = len - (index + 1);/*why +1 */

    if (index < j) {
        temp = s[index];
        s[index] = s[j];
        s[j] = temp;
        reverse_r(s, ++index, len);
    }    
}//the why is :the len is begin 1 ,but the index is begin from 0
/*
4-14 
interchages two arguments of type t 
*/
#define swap(t, x, y) { t temp;\
                        temp = x; \
                        x = y; \
                        y = temp; \
                      }

main()
{
calculator_();
}

chap4_calculator.c //handle calculator

/*e
 calculator control of main
 while(getop(s))
  if(number )
    push it
  else if(operator)  
    pop operands
    do operation
    push result
  else if(newline) 
    pop and print top of stack
  else 
    error
  we seperator the funcion from sames source files
  includes : stack.c getop.c 

*/
#include <stdio.h>
#include "stack.c" // has push() and pop() funtions
#include "getop.c"  //has getop() function
#include <stdlib.h> // has atof()
//#include "chap4.c" // has _atof()  declare and defition by myself 
#include <string.h>//for strcmp()
#include <math.h> // for sin() exp() pow()
#define NUMBER '0'
#define MATHFUN 'n'
extern void push(double); /* store the digit into the top of  stack*/
extern double pop(void); /*  return with  the top of stack into */
extern void clear(void);/* clear the stack */
extern int getop(char []);/*  return with   an  operator or operand */
extern double mathfun(char []); /* access the math function through the function's name*/
//extern void ungets(char []) /* push back an entire string onto the input*/
void calculator()
{ 
  int type, i, var = 0;
  double op2, v;
  char strop[100];
  double variables[26];
  for (i = 0; i < 26; i++)
       variables[i] = 0.0;
  while ((type = getop_line(strop)) !=EOF) {  
      switch (type) {
      case NUMBER://handle didit 
          //  printf("debug strop : %s \n",strop);
          push(atof(strop));
          break; 
      case MATHFUN: //handle the math function 
          mathfun(strop);     
          break;
      case '+':
          push(pop() + pop());
          break;
      case '*':
          push(pop() * pop());
          break;
      case '-':
          printf("debug - :  \n");
          op2 = pop();
          push(pop() - op2);
          break;
      case '/':
          op2 = pop();
          if (op2 > 0.0)
              push(pop() / op2);
          else 
              printf("errot : zero  divisor \n");
          break;
      case '%':
          op2 = pop();
          if (op2 > 0.0)
              push((int)pop() % (int)op2);
          else 
              printf("errot : zero  divisor \n");
          break;
     case 'd': /* operator stack : duplicate the top element*/
         op2 = pop();
         push(op2);
         printf("ths number top of stack is : %.5g\n", op2);
         break;
     case 's': /* operator stack : swap the top two elements */
         op2 = pop();
         double temp = pop();
         push(op2);
         push(temp);
         printf("swap successful \n");
         break;
     case 'c': /* operator stack : clear the  stack  */
         clear();
         printf("clear the stack successful \n");
         break;
     case '=':
         if (var >= 'A' && var <= 'Z') {
             pop(); //pop the value of A
             variables[var-'A'] = pop(); //store the value of A into array variables
         }    
     case '\n':
         v = pop(); 
         printf("the result is : %g \n", v);
         break;
     default :
         if (type >= 'A' && type <= 'Z') 
              push(variables[type - 'A']);         
         else if (type == 'v')
              push(v);
         else 
         printf("error input ,unknown command %s\n",strop);
     }  
     var = type;
  }
 }
double mathfun(char s[])
{
    double temp;
    if (strcmp(s, "sin") == 0)  
        push(sin(pop()));
    else if (strcmp(s, "exp") == 0)    
        push(exp(pop()));
    else if (strcmp(s, "pow") == 0) {
        temp = pop();
        push(pow(pop(), temp));
    }
    else {
        printf("mathfun errot : input %s , I can't understading \n ", s);
    }
}

getop.c

/*
getop.c for getop() :
store the characters of input into string opstr 
and return the type of opstr
*/
#pragma once
#include <string.h> //for strlen()
#include <ctype.h> //for isdigit()
#include "getch.c"// for getch() ungetch() getline()
#define MAXSIZE 100;
#include <stdio.h>
extern int getch(void);
extern void ungetch(int);
extern int  _getline(char [], int limit);
int getop(char opstr[])
{
   int cr, next;
   int i = 0;

   while ((cr = getch()) == ' ' || cr == '\t');

   /* handle the mathfun */
   if (islower(cr)) 
   {
       opstr[i++] = cr;
       while (islower(opstr[i++] = cr = getch()));
       opstr[i-1] = '\0';
       printf("handle the mathfun : %s, lentgh=%d \n", opstr, (int)strlen(opstr));
       if (cr != EOF)
           ungetch(cr);
       if (strlen(opstr) > 1)
           return 'n';
       else 
           return cr;
   }        



   if (isdigit(cr)==0 && cr != '.' && cr != '-')//add provision the negative numners 
   { 
       opstr[i] = '\0';
       return cr;
   }

   if (cr == '-')
   {
       if (isdigit(cr = getch()) || cr == '.')//add provision the negative numners 
       {
           opstr[i++] = '-';
           opstr[i++] = cr;
           cr = getch();
       }
       else
       {   
           if (cr != EOF)
               ungetch(cr);
           opstr[i] = '\0';
           return '-';
       }
   }
   while(isdigit(cr)) 
   {
       opstr[i++] = cr;
       if (cr != EOF)
       cr = getch();
   }; // collect integer part

   if (cr == '.') {
       opstr[i] = '.';
       while(isdigit(opstr[++i] = cr = getch()))
         ; 
   }
   opstr[i] = '\0';
   // printf("debug  return ungetch  : %c \n", cr);
   if (cr != EOF)
       ungetch(cr);

       printf("collect the digit : %s, lentgh=%d \n", opstr, (int)strlen(opstr));
   return '0';
}
/*
_getline() exchange getch() 
*/
int li = 0; //li of line
char line[100];
int getop_line(char opstr[])
{
    int cr, next;
    int i = 0;

    if (line[li] == '\0') {
        if (!_getline(line, 100)) {
            //printf("line : %s, %c, li=%d \n", line, line[li-1], li-1);
            opstr[i] = '\0';
            return EOF;
         }
         //printf("line : %s, %c, li=%d \n", line, line[li], li);
         li = 0;    
    }
    while ((cr = line[li++]) == ' ' || cr == '\t')
        ;

    /* handle the mathfun */
    if (islower(cr)) 
    {
        opstr[i++] = cr;
        while (islower(opstr[i++] = cr = line[li++]));
        opstr[i-1] = '\0';
        printf("handle the mathfun : %s, lentgh=%d \n", opstr, (int)strlen(opstr));
        if (cr != EOF)
                li--;            
        if (strlen(opstr) > 1)
            return 'n';
        else 
            return cr;
    }        

    if (isdigit(cr)==0 && cr != '.' && cr != '-')//add provision the negative numners 
    { 
        opstr[i] = '\0';
        return cr;
    }

    if (cr == '-')
    {
        if (isdigit(cr = line[li++]) || cr == '.')//add provision the negative numners 
        {
            opstr[i++] = '-';
            opstr[i++] = cr;
            cr = line[li++];
        }
        else
        {   
            if (cr != EOF)
                li--;
            opstr[i] = '\0';
            return '-';
        }
    }
    while(isdigit(cr)) 
    {
        opstr[i++] = cr;
        if (cr != EOF)
            cr = line[li++];
    }; // collect integer part

    if (cr == '.') {
        opstr[i] = '.';
        while(isdigit(opstr[++i] = cr = line[li++]))
            ; 
    }
    opstr[i] = '\0';
    // printf("debug  return ungetch  : %c \n", cr);
    if (cr != EOF) 
        li--;    

    printf("collect the digit : %s, lentgh=%d \n", opstr, (int)strlen(opstr));
    return '0';
}

getch.c

#define BUFFSIZE 100
#pragma once 
#include <stdio.h>
#include <string.h>
char buf[BUFFSIZE]; // buffer for ungetch
int bufp = 0;// next free position in buf

int getch(void)
{
    return (bufp > 0)? buf[--bufp]: getchar();

}

void ungetch(int c)
{
  if(bufp < BUFFSIZE)
     buf[bufp++] = c;
  else 
    printf("ungetch : too many characters \n");

}
void ungets(char s[])
{
    int i = 0;
    for (i = strlen(s) - 1; i >= 0; i--) {
         buf[bufp++] = s[i];
    }    
}
/*将一行数据读入line中并返回其长度
  line 是一个数组,用来存放输入数据
  lim  是定义的行的最大长度 
 */
int _getline(char line[],int lim)
{
    int c,i;
    for(i=0;i<lim-1 && (c=getchar())!=EOF && c!='\n';i++)
        line[i] = c; 
    if(c == '\n')
    {
        line[i] = c;
        i++;
    }
    line[i] = '\0';
    return i;
}

stack.c

#define NUMBER '0'
#define MAXVAL 100
double val[MAXVAL]; //value stack
int sp=0; //next the free position
void push(double f)
{
    if (sp < MAXVAL)
        val[sp++] = f;
      //printf("stack : %g, \n", val[sp-1]);
}

double pop(void)
{
    if (sp > 0)
        return val[--sp]; 
    else 
       printf("pop : the stack is empty \n");
   return  0.0;
}
void clear(void)
{
    sp =0;
}

getch_4-8.c

/*
4-8
*/
#include <stdio.h>
char buf = '\0';
int getch() /*return a char */
{
    int c;
    if (buf != '0') {
        c = buf; 
        buf = '\0';
    }    
    else 
        c = getchar();    
    return c;    
}

 void ungetch(int cr)
 {
     if (buf != '\0')
         printf("ungetch : too many characters \n  ");        
     else    
         buf = cr;

 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值