「C4_koizumi」の編集履歴(バックアップ)一覧はこちら
C4_koizumi - (2009/12/07 (月) 23:40:31) の1つ前との変更点
追加された行は緑色になります。
削除された行は赤色になります。
#comment()
&bold(){Exersixe 4-1.}Write the function strrindex(s,t) , which returns the position of the rightmost occurrence of t in s , or -1 if there is none.
#highlight(linenumber.c){{
//Write the function strrindex(s,t) ,
//which returns the position of the rightmost occurrence of t in s ,
// or -1 if there is none.
int strrindex(char s[], char t[])
{
int i, j, k;
int rightmostIndex;
rightmostIndex = -1;
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')
rightmostIndex = i;
}
return rightmostIndex;
}
}}
&bold(){Exersixe 4-2.}Extend atof to handle scientific notation of the form 123.45e-6 where a floating-point number may be followed by e or E and an optionally signed exponent.
#highlight(linenumber.c){{
static double atof(char s[])
{
double val, power;
int i, sign;
int eVal,j;
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++;
if(s[i] == '-') {
i++;
for(eVal = 0; isdigit(s[i]); i++) {
eVal = 10 * eVal + (s[i] - '0');
}
for(j = 0; j < eVal; j++) {
power *= 10.0;
}
} else {
for(eVal = 0; isdigit(s[i]); i++) {
eVal = 10 * eVal + (s[i] - '0');
}
for(j = 0; j < eVal; j++) {
power /= 10.0;
}
}
}
return sign * val / power;
}
}}
&bold(){Exersixe 4-3.}Given the basic framework, it's straightforward to extend the calculator. Add the modulus ( % ) operator and provisions for negative numbers.
#highlight(linenumber.c){{
int main()
{
int type;
double op1,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);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if(op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero modulus\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
//getop: get next operator or number of operand
int getop(char s[])
{
int i, c, next;
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; //not number
i = 0;
if (c == '-') {
next = getch();
if(!isdigit(next)) {
ungetch(next);
return c;
}
s[++i] = c = next;
}
if (isdigit(c)) //collect number of int
while (isdigit(s[++i] = c = getch()))
;
if (c == '.')
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
}}
&bold(){Exersixe 4-4.}Add commands to print the top element of the stack without popping, to duplicate it, and to swap the top two elements. Add a command to clear the stack.
#highlight(linenumber.c){{
#include<stdio.h>
#include<stdlib.h> //for atof
#include<ctype.h> //for getop
#include<math.h>
static enum { MAXOP = 100, NUMBER = '0', MAXVAL = 100, BUFSIZE = 100};
static int getop(char []);
static void push(double);
static double pop();
static int getSp(void);
static void setSp(int);
static int getch(void); //for getop
static void ungetch(int); //for getop
int pr4_4()
{
int type;
double op1,op2;
double tmp1, tmp2;
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);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if(op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero modulus\n");
break;
case 'p': //print the top element of the stack without popping
tmp1 = pop();
push(tmp1);
printf("\t%.8g\n", tmp1);
break;
case 'd': //duplicate the top element of the stack
tmp1 = pop();
push(tmp1);
push(tmp1);
break;
case 's': //swap the top two elements
tmp1 = pop();
tmp2 = pop();
push(tmp1);
push(tmp2);
break;
case 'c': //clear the stack
setSp(0);
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
static int sp = 0;
static double val[MAXVAL];
static int getSp(void)
{
return sp;
}
static void setSp(int val)
{
sp = val;
}
// push: push f to val of stack
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
//pop: pop the top of val of stack and return
double pop(void)
{
if(sp > 0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
//getop: get next operator or number of operand
int getop(char s[])
{
int i, c, next;
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; //not number
i = 0;
if (c == '-') {
next = getch();
if(!isdigit(next)) {
ungetch(next);
return c;
}
s[++i] = c = next;
}
if (isdigit(c)) //collect number of int
while (isdigit(s[++i] = c = getch()))
;
if (c == '.')
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
static char buf[BUFSIZE];
static int bufp = 0;
static int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
static void ungetch(int c)
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
}}
&bold(){Exersixe 4-5.}Add access to library functions like sin , exp , and pow . See <math.h> in Appendix B, Section 4.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-6.}Add commands for handling variables. (It's easy to provide twenty-six variables with single-letter names.) Add a variable for the most recently printed value.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-7.}Write a routine ungets(s) that will push back an entire string onto the input. Should ungets know about buf and bufp , or should it just use ungetch ?
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-8.}Suppose that there will never be more than one character of pushback. Modify getch and ungetch accordingly.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-9.}Our getch and ungetch do not handle a pushed-back EOF correctly. Decide what their properties ought to be if an EOF is pushed back, then implement your design.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-10.}An alternate organization uses getline to read an entire input line; this makes getch and ungetch unnecessary. Revise the calculator to use this approach.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-11.}Modify getop so that it doesn't need to use ungetch. Hint: use an internal static variable.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-12.}Adapt the ideas of printd to write a recursive version of itoa ; that is, convert an integer into a string by calling a recursive routine.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-13.}Write a recursive version of the function reverse(s) , which reverses the string s in place.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-14.}Define a macro swap(t,x,y) that interchanges two arguments of type t . (Block structure will help.)
#highlight(linenumber.c){{
}}
#comment()
&bold(){Exersixe 4-1.}Write the function strrindex(s,t) , which returns the position of the rightmost occurrence of t in s , or -1 if there is none.
#highlight(linenumber.c){{
//Write the function strrindex(s,t) ,
//which returns the position of the rightmost occurrence of t in s ,
// or -1 if there is none.
int strrindex(char s[], char t[])
{
int i, j, k;
int rightmostIndex;
rightmostIndex = -1;
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')
rightmostIndex = i;
}
return rightmostIndex;
}
}}
&bold(){Exersixe 4-2.}Extend atof to handle scientific notation of the form 123.45e-6 where a floating-point number may be followed by e or E and an optionally signed exponent.
#highlight(linenumber.c){{
static double atof(char s[])
{
double val, power;
int i, sign;
int eVal,j;
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++;
if(s[i] == '-') {
i++;
for(eVal = 0; isdigit(s[i]); i++) {
eVal = 10 * eVal + (s[i] - '0');
}
for(j = 0; j < eVal; j++) {
power *= 10.0;
}
} else {
for(eVal = 0; isdigit(s[i]); i++) {
eVal = 10 * eVal + (s[i] - '0');
}
for(j = 0; j < eVal; j++) {
power /= 10.0;
}
}
}
return sign * val / power;
}
}}
&bold(){Exersixe 4-3.}Given the basic framework, it's straightforward to extend the calculator. Add the modulus ( % ) operator and provisions for negative numbers.
#highlight(linenumber.c){{
#include<stdio.h>
#include<stdlib.h> //for atof
#include<ctype.h> //for getop
#include<math.h>
static enum { MAXOP = 100, NUMBER = '0', MAXVAL = 100, BUFSIZE = 100};
static int getop(char []);
static void push(double);
static double pop();
static int getch(void); //for getop
static void ungetch(int); //for getop
int pr4_3()
{
int type;
double op1,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);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if(op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero modulus\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
static int sp = 0;
static double val[MAXVAL];
// push: push f to val of stack
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
//pop: pop the top of val of stack and return
double pop(void)
{
if(sp > 0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
//getop: get next operator or number of operand
int getop(char s[])
{
int i, c, next;
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; //not number
i = 0;
if (c == '-') {
next = getch();
if(!isdigit(next)) {
ungetch(next);
return c;
}
s[++i] = c = next;
}
if (isdigit(c)) //collect number of int
while (isdigit(s[++i] = c = getch()))
;
if (c == '.')
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
static char buf[BUFSIZE];
static int bufp = 0;
static int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
static void ungetch(int c)
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
}}
&bold(){Exersixe 4-4.}Add commands to print the top element of the stack without popping, to duplicate it, and to swap the top two elements. Add a command to clear the stack.
#highlight(linenumber.c){{
#include<stdio.h>
#include<stdlib.h> //for atof
#include<ctype.h> //for getop
#include<math.h>
static enum { MAXOP = 100, NUMBER = '0', MAXVAL = 100, BUFSIZE = 100};
static int getop(char []);
static void push(double);
static double pop();
static int getSp(void);
static void setSp(int);
static int getch(void); //for getop
static void ungetch(int); //for getop
int pr4_4()
{
int type;
double op1,op2;
double tmp1, tmp2;
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);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if(op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero modulus\n");
break;
case 'p': //print the top element of the stack without popping
tmp1 = pop();
push(tmp1);
printf("\t%.8g\n", tmp1);
break;
case 'd': //duplicate the top element of the stack
tmp1 = pop();
push(tmp1);
push(tmp1);
break;
case 's': //swap the top two elements
tmp1 = pop();
tmp2 = pop();
push(tmp1);
push(tmp2);
break;
case 'c': //clear the stack
setSp(0);
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
static int sp = 0;
static double val[MAXVAL];
static int getSp(void)
{
return sp;
}
static void setSp(int val)
{
sp = val;
}
// push: push f to val of stack
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
//pop: pop the top of val of stack and return
double pop(void)
{
if(sp > 0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
//getop: get next operator or number of operand
int getop(char s[])
{
int i, c, next;
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; //not number
i = 0;
if (c == '-') {
next = getch();
if(!isdigit(next)) {
ungetch(next);
return c;
}
s[++i] = c = next;
}
if (isdigit(c)) //collect number of int
while (isdigit(s[++i] = c = getch()))
;
if (c == '.')
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
static char buf[BUFSIZE];
static int bufp = 0;
static int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
static void ungetch(int c)
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
}}
&bold(){Exersixe 4-5.}Add access to library functions like sin , exp , and pow . See <math.h> in Appendix B, Section 4.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-6.}Add commands for handling variables. (It's easy to provide twenty-six variables with single-letter names.) Add a variable for the most recently printed value.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-7.}Write a routine ungets(s) that will push back an entire string onto the input. Should ungets know about buf and bufp , or should it just use ungetch ?
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-8.}Suppose that there will never be more than one character of pushback. Modify getch and ungetch accordingly.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-9.}Our getch and ungetch do not handle a pushed-back EOF correctly. Decide what their properties ought to be if an EOF is pushed back, then implement your design.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-10.}An alternate organization uses getline to read an entire input line; this makes getch and ungetch unnecessary. Revise the calculator to use this approach.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-11.}Modify getop so that it doesn't need to use ungetch. Hint: use an internal static variable.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-12.}Adapt the ideas of printd to write a recursive version of itoa ; that is, convert an integer into a string by calling a recursive routine.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-13.}Write a recursive version of the function reverse(s) , which reverses the string s in place.
#highlight(linenumber.c){{
}}
&bold(){Exersixe 4-14.}Define a macro swap(t,x,y) that interchanges two arguments of type t . (Block structure will help.)
#highlight(linenumber.c){{
}}