E x c e r c i s e 4 − 1 Excercise\quad 4-1 Excercise4−1:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int strindex(char s[],char t[]);
int strrindex(char s[],char t[]);int main(void)
{char s[100]="qwoulddfsdfdsgdsgdsgdsouldasdasdasd";char t[100]="ould"; int l_index=strindex(s,t);int r_index=strrindex(s,t); printf("l_index=%d\n",l_index); printf("r_index=%d\n",r_index); return 0;
}int strindex(char s[],char t[])
{int i,j,k;for(i=0;s[i]!='\0' ;i++){for(j=i,k=0;t[k]!='\0' && s[j]==t[k];j++,k++);if((k>0)&&(t[k]=='\0'))return i;} return -1;
}int strrindex(char s[],char t[])
{int i,j,k;int t_len=strlen(t);int s_len=strlen(s);if(t_len>s_len){return -1; }else{for(i=s_len-t_len;i>=0 ;i--){for(j=i,k=0;t[k]!='\0' && s[j]==t[k];j++,k++);if((k>0)&&(t[k]=='\0'))return i; } return -1;}
}
E x c e r c i s e 4 − 2 Excercise\quad 4-2 Excercise4−2:输出如图1所示。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>double atof_myself(char s[]);int main(void)
{char s1[100]="123.789e1";char s2[100]="123456123456.789e-10"; char s3[100]="123.789"; double d1=atof_myself(s1);double d2=atof_myself(s2);double d3=atof_myself(s3); printf("d1=%lf\n",d1);printf("d2=%lf\n",d2); printf("d3=%lf\n",d3); return 0;
}double atof_myself(char s[])
{double val,power,power_more;int i,sign,sign_more,power_more_index;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; } if((s[i]=='e') ||(s[i]=='E')){i++;sign_more=(s[i]=='-')? -1:1;if((s[i]=='-')||(s[i]=='+')){i++;} for(power_more_index=0;isdigit(s[i]);i++){power_more_index=10*power_more_index+(s[i]-'0'); }power_more=1.0;for(i=0;i<power_more_index;i++){power_more=power_more*10.0; } if(sign_more==-1){return ((sign * val/power)/power_more); }else{return ((sign * val/power)*power_more); } }else{return (sign * val/power); }
}
E x c e r c i s e 4 − 3 Excercise\quad 4-3 Excercise4−3:
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <math.h> /* for fmod() */#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */int getop(char []);
void push(double);
double pop(void);/* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;case '\n':printf("\t%.8g\n", pop());break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && c != '.' && c != '-'){ return c; /* not a number */}if(c == '-'){i = 0; c = getch(); s[++i] = c; }else{i = 0; }if (isdigit(c)) /* collect integer part */while (isdigit(s[++i] = c = getch()));if (c == '.') /* collect fraction part */while (isdigit(s[++i] = c = getch()));s[i] = '\0';if (c != EOF){ ungetch(c);}if (i == 1 && s[0] == '-') // if s[0] == '-' && s[1] == '\0', return minus operatorreturn '-'; return NUMBER;
}#define BUFSIZE 100char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */int getch(void) /* get a (possibly pushed-back) character */
{return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c) /* push character back on input */
{if (bufp >= BUFSIZE)printf("ungetch: too many characters\n");elsebuf[bufp++] = c;
}
E x c e r c i s e 4 − 4 Excercise\quad 4-4 Excercise4−4:
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <math.h> /* for fmod() */#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();/* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/ case '\n':printf("\t%.8g\n", pop());break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if(sp > 0){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && c != '.' && c != '-'){ return c; /* not a number */}if(c == '-'){i = 0; c = getch(); s[++i] = c; }else{i = 0; }if (isdigit(c)) /* collect integer part */while (isdigit(s[++i] = c = getch()));if (c == '.') /* collect fraction part */while (isdigit(s[++i] = c = getch()));s[i] = '\0';// if (c != EOF)// { // ungetch(c);// }if (i == 1 && s[0] == '-') // if s[0] == '-' && s[1] == '\0', return minus operatorreturn '-'; return NUMBER;
}#define BUFSIZE 100char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */int getch(void) /* get a (possibly pushed-back) character */
{return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c) /* push character back on input */
{if (bufp >= BUFSIZE)printf("ungetch: too many characters\n");elsebuf[bufp++] = c;
}
E x c e r c i s e 4 − 5 Excercise\quad 4-5 Excercise4−5:
#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();/* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/
/****************************************************/ case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break;
/****************************************************/ case '\n':printf("\t%.8g\n", pop());break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if(sp > 0){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && c != '.' && c != '-'){ return c; /* not a number */}if(c == '-'){i = 0; c = getch(); s[++i] = c; }else{i = 0; }if (isdigit(c)) /* collect integer part */while (isdigit(s[++i] = c = getch()));if (c == '.') /* collect fraction part */while (isdigit(s[++i] = c = getch()));s[i] = '\0';// if (c != EOF)// { // ungetch(c);// }if (i == 1 && s[0] == '-') // if s[0] == '-' && s[1] == '\0', return minus operatorreturn '-'; return NUMBER;
}#define BUFSIZE 100char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */int getch(void) /* get a (possibly pushed-back) character */
{return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c) /* push character back on input */
{if (bufp >= BUFSIZE)printf("ungetch: too many characters\n");elsebuf[bufp++] = c;
}
E x c e r c i s e 4 − 6 Excercise\quad 4-6 Excercise4−6:其实这一题的意图似乎还是很模糊的,我这里的做法是提供26个变量(分别对应26个小写英文字母),然后再提供一个数组用来存储这26个变量的值。如果要对某个变量赋值可以类似 x = n n n . n n n x=nnn.nnn x=nnn.nnn来操作,其中 x x x表示26个小写英文字母中的任何一个, n n n . n n n nnn.nnn nnn.nnn表示即将赋值给变量的值,这个值可以为负数,负数的话在最前面需要加上 − - −,比如 − n n n . n n n -nnn.nnn −nnn.nnn。某个变量在参与运算之前需要先进行赋值操作,否则可能拿到的是默认值 0.0 0.0 0.0,变量参加运算的一个例子为 a 8 + a8+ a8+实际是变量 a a a的值和8进行加法运算。这里还记录了最近赋值或参与运算的是那个变量,并且 _ \_ _符号对应的命令操作会将这个最近赋值或参与运算的变量以及对应的值打印出来。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define SETVARIABLE 's' /* signal that a variable is being assigned */
#define GETVARIABLE 'g' /* signal that a variable is being retrieved */
#define NUMVARS 26 /* number of variables supported (a-z) */enum boolean {FALSE, TRUE};int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();
void view_stack(); /* initially as space such that malformed use of '=' won't cause segfaults */
char last_recent = ' ';
/* array to store the double values for variables.
Supports variables a through z (lower case). Initial value is 0*/
double varVals[NUMVARS] = {0.0}; /* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;
/****************************************************/ case SETVARIABLE:if (strlen(s) > 2 && s[1] == '='){int v = s[0]; /* stores variable */int i = 1; /* start at 1 since while loop needed ++i for a few reasons */while (s[++i] != '\0') /* this removes the variable name= part of s e.g. if s == "a=123.45" after loop s == "123.45" */s[i - 2] = s[i]; /* shifts chars two to the left by 2 */s[i - 2] = '\0'; /* since '\0' isn't copied, terminate string manually */varVals[v - 'a'] = atof(s); /* convert string to double and store it in array */}elseprintf("error: set variable length too small or incorrectly formatted (%s)\n", s);break;case GETVARIABLE:push(varVals[s[0] - 'a']); /* convert the variable name to stored value */break;
/****************************************************/ case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break; // case '\n':// printf("\t%.8g\n", pop());// break;case '\n':view_stack();break; case '_':printf("The last recently used variable is %c=%8g\n",last_recent, varVals[last_recent-'a']);break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/* push: push f onto value stack */
void view_stack()
{int i=sp;if (sp >0){while(i>0){printf("view_stack:%8g\n",val[i-1]);i=i-1;}}elseprintf("view_stack:Stack is empty\n");
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if((sp > 0) &&(sp < MAXVAL)){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;char setVar = FALSE;i = 0;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-'){ return c; /* not a number */}if (c >= 'a' && c <= 'z'){last_recent=c;
/* get next char and check if it was an equal symbol.*/ if ((s[++i] = c = getch()) == '='){ setVar = TRUE;c = getch();s[++i] = c; }else{if (c != EOF){ ungetch(c);}return GETVARIABLE;}}if(c == '-'){ c = getch(); s[++i] = c; }if (isdigit(c)) /* collect integer part */{ while (isdigit(s[++i] = c = getch()));}if (c == '.') /* collect fraction part */{ while (isdigit(s[++i] = c = getch()));}s[i] = '\0';if (c != EOF){ ungetch(c);}
/* if s[0] == '-' && s[1] == '\0', return minus operator */ if (i == 1 && s[0] == '-') return '-'; if (setVar){ return SETVARIABLE; } return NUMBER;
}#define BUFSIZE 100char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */int getch(void) /* get a (possibly pushed-back) character */
{return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c) /* push character back on input */
{if (bufp >= BUFSIZE)printf("ungetch: too many characters\n");elsebuf[bufp++] = c;
}
E x c e r c i s e 4 − 7 Excercise\quad 4-7 Excercise4−7:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define SETVARIABLE 's' /* signal that a variable is being assigned */
#define GETVARIABLE 'g' /* signal that a variable is being retrieved */
#define NUMVARS 26 /* number of variables supported (a-z) */enum boolean {FALSE, TRUE};int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();
void view_stack(); /* initially as space such that malformed use of '=' won't cause segfaults */
char last_recent = ' ';
/* array to store the double values for variables.
Supports variables a through z (lower case). Initial value is 0*/
double varVals[NUMVARS] = {0.0}; /* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;
/****************************************************/ case SETVARIABLE:if (strlen(s) > 2 && s[1] == '='){int v = s[0]; /* stores variable */int i = 1; /* start at 1 since while loop needed ++i for a few reasons */while (s[++i] != '\0') /* this removes the variable name= part of s e.g. if s == "a=123.45" after loop s == "123.45" */s[i - 2] = s[i]; /* shifts chars two to the left by 2 */s[i - 2] = '\0'; /* since '\0' isn't copied, terminate string manually */varVals[v - 'a'] = atof(s); /* convert string to double and store it in array */}elseprintf("error: set variable length too small or incorrectly formatted (%s)\n", s);break;case GETVARIABLE:push(varVals[s[0] - 'a']); /* convert the variable name to stored value */break;
/****************************************************/ case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break; // case '\n':// printf("\t%.8g\n", pop());// break;case '\n':view_stack();break; case '_':printf("The last recently used variable is %c=%8g\n",last_recent, varVals[last_recent-'a']);break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/* push: push f onto value stack */
void view_stack()
{int i=sp;if (sp >0){while(i>0){printf("view_stack:%8g\n",val[i-1]);i=i-1;}}elseprintf("view_stack:Stack is empty\n");
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if((sp > 0) &&(sp < MAXVAL)){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;char setVar = FALSE;i = 0;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-'){ return c; /* not a number */}if (c >= 'a' && c <= 'z'){last_recent=c;
/* get next char and check if it was an equal symbol.*/ if ((s[++i] = c = getch()) == '='){ setVar = TRUE;c = getch();s[++i] = c; }else{if (c != EOF){ ungetch(c);}return GETVARIABLE;}}if(c == '-'){ c = getch(); s[++i] = c; }if (isdigit(c)) /* collect integer part */{ while (isdigit(s[++i] = c = getch()));}if (c == '.') /* collect fraction part */{ while (isdigit(s[++i] = c = getch()));}s[i] = '\0';if (c != EOF){ ungetch(c);}
/* if s[0] == '-' && s[1] == '\0', return minus operator */ if (i == 1 && s[0] == '-') return '-'; if (setVar){ return SETVARIABLE; } return NUMBER;
}#define BUFSIZE 100char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */int getch(void) /* get a (possibly pushed-back) character */
{return (bufp > 0) ? buf[--bufp] : getchar();
}void ungetch(int c) /* push character back on input */
{if (bufp >= BUFSIZE)printf("ungetch: too many characters\n");elsebuf[bufp++] = c;
}/*ungets() actually takes a little bit of thought. Should thefirst character in "s" be sent to ungetch() first, or shouldit be sent last? I assumed that most code calling getch()would be of this form:char array[...];int i; while (...) {array[i++] = getch();} In such cases, the same code might call ungets() as:ungets(array);and expect to repeat the while loop to get the same stringback. This requires that the last character be sent firstto ungetch() first, because getch() and ungetch() work with a stack. To answer K&R2's additional question for this problem,it's usually preferable for something like ungets() to justbuild itself on top of ungetch(). This allows us to change ungetch() and getch() in the future, perhaps to use a linked list instead, without affecting ungets().
*/
void ungets(const char *s)
{ int i, len;len = strlen(s);if(BUFSIZE - bufp >= len) // ungets() must do its own bounds checking{for(i = strlen(s) - 1; i >= 0; i--)ungetch(s[i]);}elseprintf("error: insufficient space in buffer, can't execute ungets()\n");
}
E x c e r c i s e 4 − 8 Excercise\quad 4-8 Excercise4−8:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define SETVARIABLE 's' /* signal that a variable is being assigned */
#define GETVARIABLE 'g' /* signal that a variable is being retrieved */
#define NUMVARS 26 /* number of variables supported (a-z) */enum boolean {FALSE, TRUE};int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();
void view_stack(); /* initially as space such that malformed use of '=' won't cause segfaults */
char last_recent = ' ';
/* array to store the double values for variables.
Supports variables a through z (lower case). Initial value is 0*/
double varVals[NUMVARS] = {0.0}; /* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;
/****************************************************/ case SETVARIABLE:if (strlen(s) > 2 && s[1] == '='){int v = s[0]; /* stores variable */int i = 1; /* start at 1 since while loop needed ++i for a few reasons */while (s[++i] != '\0') /* this removes the variable name= part of s e.g. if s == "a=123.45" after loop s == "123.45" */s[i - 2] = s[i]; /* shifts chars two to the left by 2 */s[i - 2] = '\0'; /* since '\0' isn't copied, terminate string manually */varVals[v - 'a'] = atof(s); /* convert string to double and store it in array */}elseprintf("error: set variable length too small or incorrectly formatted (%s)\n", s);break;case GETVARIABLE:push(varVals[s[0] - 'a']); /* convert the variable name to stored value */break;
/****************************************************/ case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break; // case '\n':// printf("\t%.8g\n", pop());// break;case '\n':view_stack();break; case '_':printf("The last recently used variable is %c=%8g\n",last_recent, varVals[last_recent-'a']);break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/* push: push f onto value stack */
void view_stack()
{int i=sp;if (sp >0){while(i>0){printf("view_stack:%8g\n",val[i-1]);i=i-1;}}elseprintf("view_stack:Stack is empty\n");
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if((sp > 0) &&(sp < MAXVAL)){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;char setVar = FALSE;i = 0;while ((s[0] = c = getch()) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-'){ return c; /* not a number */}if (c >= 'a' && c <= 'z'){last_recent=c;
/* get next char and check if it was an equal symbol.*/ if ((s[++i] = c = getch()) == '='){ setVar = TRUE;c = getch();s[++i] = c; }else{if (c != EOF){ ungetch(c);}return GETVARIABLE;}}if(c == '-'){ c = getch(); s[++i] = c; }if (isdigit(c)) /* collect integer part */{ while (isdigit(s[++i] = c = getch()));}if (c == '.') /* collect fraction part */{ while (isdigit(s[++i] = c = getch()));}s[i] = '\0';if (c != EOF){ ungetch(c);}
/* if s[0] == '-' && s[1] == '\0', return minus operator */ if (i == 1 && s[0] == '-') return '-'; if (setVar){ return SETVARIABLE; } return NUMBER;
}char buf=EOF; /* buffer for ungetch */int getch(void) /* get a (possibly pushed-back) character */
{return (buf!=EOF) ? buf : getchar();
}void ungetch(int c) /* push character back on input */
{if (buf!=EOF)printf("ungetch: too many characters\n");elsebuf = c;
}
E x c e r c i s e 4 − 9 Excercise\quad 4-9 Excercise4−9:
E x c e r c i s e 4 − 10 Excercise\quad 4-10 Excercise4−10:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define SETVARIABLE 's' /* signal that a variable is being assigned */
#define GETVARIABLE 'g' /* signal that a variable is being retrieved */
#define NUMVARS 26 /* number of variables supported (a-z) */
#define MAXLINE 1000 /* number of variables supported (a-z) */enum boolean {FALSE, TRUE};int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();
void view_stack();
int getline(char s[], int lim);/* initially as space such that malformed use of '=' won't cause segfaults */
char last_recent = ' ';
/* array to store the double values for variables.
Supports variables a through z (lower case). Initial value is 0*/
double varVals[NUMVARS] = {0.0}; /*********************************/
char line[MAXLINE];
int line_i;
/*********************************/
/* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while (getline(line, MAXLINE) != 0){line_i=0;while ((type = getop(s)) != '\0') {switch (type) {case NUMBER:push(atof(s));break;/****************************************************/ case SETVARIABLE:if (strlen(s) > 2 && s[1] == '='){int v = s[0]; /* stores variable */int i = 1; /* start at 1 since while loop needed ++i for a few reasons */while (s[++i] != '\0') /* this removes the variable name= part of s e.g. if s == "a=123.45" after loop s == "123.45" */s[i - 2] = s[i]; /* shifts chars two to the left by 2 */s[i - 2] = '\0'; /* since '\0' isn't copied, terminate string manually */varVals[v - 'a'] = atof(s); /* convert string to double and store it in array */}elseprintf("error: set variable length too small or incorrectly formatted (%s)\n", s);break;case GETVARIABLE:push(varVals[s[0] - 'a']); /* convert the variable name to stored value */break; /****************************************************/ case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break; /****************************************************/case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break; // case '\n':// printf("\t%.8g\n", pop());// break;case '\n':view_stack();break; case '_':printf("The last recently used variable is %c=%8g\n",last_recent, varVals[last_recent-'a']);break; default:printf("error: unknown command %s\n", s);break;}}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/* push: push f onto value stack */
void view_stack()
{int i=sp;if (sp >0){while(i>0){printf("view_stack:%8g\n",val[i-1]);i=i-1;}}elseprintf("view_stack:Stack is empty\n");
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if((sp > 0) &&(sp < MAXVAL)){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>
int getch(void);
void ungetch(int);/* getop: get next character or numeric operand */
int getop(char s[])
{int i, c;char setVar = FALSE;i = 0;while ((s[0] = c = line[line_i++]) == ' ' || c == '\t');s[1] = '\0';if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-'){ return c; /* not a number */}if (c >= 'a' && c <= 'z'){last_recent=c;
/* get next char and check if it was an equal symbol.*/ if ((s[++i] = c = line[line_i++]) == '='){ setVar = TRUE;c = line[line_i++];s[++i] = c; }else{if (c != '\0'){ line_i=line_i-1;}return GETVARIABLE;}}if(c == '-'){ c = line[line_i++]; s[++i] = c; }if (isdigit(c)) /* collect integer part */{ while (isdigit(s[++i] = c = line[line_i++]));}if (c == '.') /* collect fraction part */{ while (isdigit(s[++i] = c = line[line_i++]));}s[i] = '\0';if (c != '\0'){ line_i=line_i-1;}
/* if s[0] == '-' && s[1] == '\0', return minus operator */ if (i == 1 && s[0] == '-') return '-'; if (setVar){ return SETVARIABLE; } return NUMBER;
}// /* getop: get next character or numeric operand */
// int getop(char s[])
// {// int i, c;// char setVar = FALSE;// i = 0;// while ((s[0] = c = getch()) == ' ' || c == '\t');// s[1] = '\0';// if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-')// { // return c; /* not a number */// }// if (c >= 'a' && c <= 'z')// {// last_recent=c;
// /* get next char and check if it was an equal symbol.*/ // if ((s[++i] = c = getch()) == '=')// { // setVar = TRUE;// c = getch();// s[++i] = c; // }// else// {// if (c != EOF)// { // ungetch(c);// }// return GETVARIABLE;// }// }// if(c == '-')// { // c = getch(); // s[++i] = c; // }// if (isdigit(c)) /* collect integer part */// { // while (isdigit(s[++i] = c = getch()));// }// if (c == '.') /* collect fraction part */// { // while (isdigit(s[++i] = c = getch()));// }// s[i] = '\0';// if (c != EOF)// { // ungetch(c);// }
// /* if s[0] == '-' && s[1] == '\0', return minus operator */ // if (i == 1 && s[0] == '-') // return '-'; // if (setVar)// { // return SETVARIABLE; // } // return NUMBER;
// }/* getline: get line into s, return length */
int getline(char s[], int lim)
{int c, i;i = 0;while (--lim > 0 && (c = getchar()) != EOF && c != '\n')s[i++] = c;if (c == '\n')s[i++] = c;s[i] = '\0';return i;
}
E x c e r c i s e 4 − 11 Excercise\quad 4-11 Excercise4−11:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h> #define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
#define SETVARIABLE 's' /* signal that a variable is being assigned */
#define GETVARIABLE 'g' /* signal that a variable is being retrieved */
#define NUMVARS 26 /* number of variables supported (a-z) */enum boolean {FALSE, TRUE};int getop(char []);
void push(double);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStack();
void view_stack(); /* initially as space such that malformed use of '=' won't cause segfaults */
char last_recent = ' ';
/* array to store the double values for variables.
Supports variables a through z (lower case). Initial value is 0*/
double varVals[NUMVARS] = {0.0}; /* reverse Polish calculator */
int main()
{int type;double op2;char s[MAXOP];while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:push(atof(s));break;
/****************************************************/ case SETVARIABLE:if (strlen(s) > 2 && s[1] == '='){int v = s[0]; /* stores variable */int i = 1; /* start at 1 since while loop needed ++i for a few reasons */while (s[++i] != '\0') /* this removes the variable name= part of s e.g. if s == "a=123.45" after loop s == "123.45" */s[i - 2] = s[i]; /* shifts chars two to the left by 2 */s[i - 2] = '\0'; /* since '\0' isn't copied, terminate string manually */varVals[v - 'a'] = atof(s); /* convert string to double and store it in array */}elseprintf("error: set variable length too small or incorrectly formatted (%s)\n", s);break;case GETVARIABLE:push(varVals[s[0] - 'a']); /* convert the variable name to stored value */break;
/****************************************************/ case '+':push(pop() + pop());break;case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("error: zero divisor\n");break;case '%':op2 = pop();if (op2 != 0.0)push(fmod(pop(),op2));elseprintf("error: zero divisor\n");break;
/****************************************************/ case '?':showTop();break;case '#':duplicate();break;case '~':swapItems();break;case '!':clearStack(); break;
/****************************************************/case '$':push(sin(pop()));break;case '@':push(exp(pop()));break;case '^':op2 = pop();push(pow(pop(),op2));break; // case '\n':// printf("\t%.8g\n", pop());// break;case '\n':view_stack();break; case '_':printf("The last recently used variable is %c=%8g\n",last_recent, varVals[last_recent-'a']);break; default:printf("error: unknown command %s\n", s);break;}}return 0;
}#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack *//* push: push f onto value stack */
void push(double f)
{if (sp < MAXVAL)val[sp++] = f;elseprintf("error: 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("error: stack empty\n");return 0.0;}
}/* push: push f onto value stack */
void view_stack()
{int i=sp;if (sp >0){while(i>0){printf("view_stack:%8g\n",val[i-1]);i=i-1;}}elseprintf("view_stack:Stack is empty\n");
}/**********************************************************/
void showTop(void)
{if(sp > 0)printf("Top of stack contains: %8g\n", val[sp-1]);elseprintf("The stack is empty!\n");
}void duplicate(void)
{double temp = 0.0; if((sp > 0) &&(sp < MAXVAL)){temp = pop();push(temp);push(temp); }elseprintf("The stack is empty!\n"); }void swapItems(void)
{double item1 = 0.0;double item2 = 0.0; if(sp >= 2){item1 = pop();item2 = pop();push(item1);push(item2); }elseprintf("The stack is empty!\n");
}/* pop only returns a value if sp is greater than zero. So setting the
stack pointer to zero will cause pop to return its error */void clearStack(void)
{sp = 0;
}/**********************************************************/#include <ctype.h>/* getop: get next character or numeric operand */
int getop(char s[])
{int i;static int c=EOF; static int unget_flag=0; char setVar = FALSE;i = 0;if(unget_flag==1){if((c== ' ') || (c == '\t')){while ((s[0] = c = getchar()) == ' ' || c == '\t'); } else{s[0] = c; }unget_flag=0;}else{while ((s[0] = c = getchar()) == ' ' || c == '\t'); }s[1] = '\0';if (!isdigit(c) && !isalpha(c) && c != '.' && c != '-'){ return c; /* not a number */}if (c >= 'a' && c <= 'z'){last_recent=c;
/* get next char and check if it was an equal symbol.*/ if ((s[++i] = c = getchar()) == '='){ setVar = TRUE;c = getchar();s[++i] = c; }else{if (c != EOF){ unget_flag=1;} return GETVARIABLE;}}if(c == '-'){ c = getchar(); s[++i] = c; }if (isdigit(c)) /* collect integer part */{ while (isdigit(s[++i] = c = getchar()));}if (c == '.') /* collect fraction part */{ while (isdigit(s[++i] = c = getchar()));} s[i] = '\0';if (c != EOF){ unget_flag=1;}
/* if s[0] == '-' && s[1] == '\0', return minus operator */ if (i == 1 && s[0] == '-') return '-'; if (setVar){ return SETVARIABLE; } return NUMBER;
}
E x c e r c i s e 4 − 12 Excercise\quad 4-12 Excercise4−12:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>void itoa_myself(int n, char s[], int minmum);int main(void)
{char buffer[100];printf("INT_MIN: %d\n", INT_MIN);itoa_myself(INT_MIN, buffer,25);printf("Buffer : %s\n", buffer);printf("\\*******************************\\\n"); printf("378\n");itoa_myself(378, buffer,25);printf("Buffer : %s\n", buffer);printf("\\*******************************\\\n"); printf("-873\n");itoa_myself(-873, buffer,25);printf("Buffer : %s\n", buffer);return 0;
}void itoa_myself(int n, char s[],int minmum)
{static int i=0;static int recur_num=0; recur_num=recur_num+1;if(n<0){s[i++] = '-'; }if(n/10){itoa_myself(abs(n/10), s,minmum); } s[i++] = abs(n % 10) + '0'; if(i>minmum){printf("Elements overflow\n");}recur_num=recur_num-1;if(recur_num==0){ s[i] = '\0'; i=0;recur_num=0; }
}
E x c e r c i s e 4 − 13 Excercise\quad 4-13 Excercise4−13:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>void itoa_myself(int n, char s[], int minmum);
void reverse(char s[]);int main(void)
{char buffer[100];printf("INT_MIN: %d\n", INT_MIN);itoa_myself(INT_MIN, buffer,25);printf("Buffer : %s\n", buffer);return 0;
}void itoa_myself(int n, char s[], int minmum)
{int i, sign;sign = n;i = 0;do {s[i++] = abs(n % 10) + '0';} while ( n /= 10 );if (sign < 0)s[i++] = '-';while(i<minmum){s[i++] = ' '; } s[i] = '\0';reverse(s);
}void reverse(char s[])
{int c; static int first_flag=1; static int i=0; static int j=0;if(first_flag==1){first_flag=0;j=strlen(s)-1;}if ( i < j ) {c = s[i];s[i] = s[j];s[j] = c;i=i+1;j=j-1;reverse(s);}
}
E x c e r c i s e 4 − 14 Excercise\quad 4-14 Excercise4−14:
#include <stdio.h>#define swap(t,x,y) { \t temp=x; \x=y; \y=temp; \}int main(void)
{int a=6;int b=9;swap(int,a,b)printf("a=%d,b=%d\n", a,b);return 0;
}