《C程序设计语言》练习 4-3
2018-01-04 09:52
232 查看
练习 4-3
在有了基本框架后,对计算器程序进行扩充就比较简单了。在该程序中加入
取模(%)运算符,并注意考虑负数的情况。
然而书上那个代码并不能用,
可能是因为我是windows系统的原因
windows的控制台敲回车才能输入,但回车自带换行
所以我改了一下代码
主要改的是 main 函数 和 getop函数
我在处理取模运算时,要判断两个数是否都为整形,所以加了一个变量
我将空白字符作为分隔符看待
比如 想计算 11 + 1 等于几
就输入 11’ ‘1 + =
控制台便会打印 2
要注意的是 ‘+’ 和 ‘-’ 如果后面直接跟数字,会被看作符号位
完整代码 :
发现 getop函数在处理 ‘+’ 和 ‘-’ 时写的代码有问题,
已修改
by 2018-1-4
在有了基本框架后,对计算器程序进行扩充就比较简单了。在该程序中加入
取模(%)运算符,并注意考虑负数的情况。
然而书上那个代码并不能用,
可能是因为我是windows系统的原因
windows的控制台敲回车才能输入,但回车自带换行
所以我改了一下代码
主要改的是 main 函数 和 getop函数
我在处理取模运算时,要判断两个数是否都为整形,所以加了一个变量
main() { int type; double op2, op3; 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(); op3 = pop(); if (op2 != (int)op2 || op3 != (int)op3) //要保证取模的两个数都是整数 printf("error: Only integers can get the modulus\n"); else if (op2 == 0) printf("error: zero divisor\n"); else if (op2 < 0) push(0); else push((int)op3 % (int)op2); break; case '=': //等于号用来取出栈中最上面的值 printf("\t%.8g\n", pop()); break; case '.': printf("error: There's no number in front of the decimal point"); break; case ' ' : //空白字符不处理 case '\n': case '\t': break; default: printf("error: unknown command %s\n", s); break; } } int getop(char s[]) { int i, c, c2; while ((c = getch()) == ' ' || c == '\n' || c == '\t') //去除多余的空白字符 ; if (c == '-' || c == '+') // '-' 和 '+' 有可能作为符号位 if (isdigit(c2 = getch()))//所以读取下一位,若是数字,则当做符号位 { s[i++] = c; c = c2; } else { ungetch(c2); return c; } if (isdigit(c)) { s[0] = c; i = 1; //数字的格式为 "xxx.xxx" // x 是数字 while (isdigit(c = getch())) s[i++] = c; if (c == '.') { s[i++] = c; while (isdigit(c = getch())) s[i++] = c; } //数字结束 s[i] = '\0'; if (c != '\n' && c!= ' ' && c != '\t') ungetch(c); return NUMBER; } else return c; }
我将空白字符作为分隔符看待
比如 想计算 11 + 1 等于几
就输入 11’ ‘1 + =
控制台便会打印 2
要注意的是 ‘+’ 和 ‘-’ 如果后面直接跟数字,会被看作符号位
完整代码 :
/*练习 4-3 在有了基本框架后,对计算器程序进行扩充就比较简单了。在该程序中加入 取模(%)运算符,并注意考虑负数的情况。*/ #include <stdio.h> //--------------main------------------------------------------------ #define MAXOP 100 //操作数与操作符的最大值 #define NUMBER '0' //getop得到数字或小数点时返回的值 int getop(char[]); void push(double); double pop(void); double atof(char s[]); int isspace(int); int isdigit(int); main() { int type; double op2, op3; 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(); op3 = pop(); if (op2 != (int)op2 || op3 != (int)op3) //要保证取模的两个数都是整数 printf("error: Only integers can get the modulus\n"); else if (op2 == 0) printf("error: zero divisor\n"); else if (op2 < 0) push(0); else push((int)op3 % (int)op2); break; case '=': //等于号用来取出栈中最上面的值 printf("\t%.8g\n", pop()); break; case '.': printf("error: There's no number in front of the decimal point"); break; case ' ' : //空白字符不处理 case '\n': case '\t': break; default: printf("error: unknown command %s\n", s); break; } } //-------------------------------------------------------------- //-------------获取字符------------------------------------------------- int getch(void); void ungetch(int); int getop(char s[]) { int i, c, c2; while ((c = getch()) == ' ' || c == '\n' || c == '\t') //去除多余的空白字符 ; if (c == '-' || c == '+') // '-' 和 '+' 有可能作为符号位 if (isdigit(c2 = getch()))//所以读取下一位,若是数字,则当做符号位 { s[i++] = c; c = c2; } else { ungetch(c2); return c; } if (isdigit(c)) { s[0] = c; i = 1; //数字的格式为 "xxx.xxx" // x 是数字 while (isdigit(c = getch())) s[i++] = c; if (c == '.') { s[i++] = c; while (isdigit(c = getch())) s[i++] = c; } //数字结束 s[i] = '\0'; if (c != '\n' && c!= ' ' && c != '\t') ungetch(c); return NUMBER; } else return c; } #define BUFSIZE 100 char buf[BUFSIZE]; //缓存的字符数组 int bufp = 0; //缓存数组指针 int getch(void) { if (bufp > 0) return buf[--bufp]; else return getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) printf("ungetch: too many characters\n"); else buf[bufp++] = c; } //-------------------------------------------------------------- //----------------栈操作---------------------------------------------- #define MAXVAL 100 //栈的最大长度 int op = 0; double val[MAXVAL]; void push(double d) { if (op < MAXVAL) val[op++] = d; else printf("error: stack full, can't push %g\n", d); } double pop(void) { if (op > 0) return val[--op]; else printf("error: stack empty\n"); return 0.0; } //-------------------------------------------------------------- //---------------转换成数字----------------------------------------------- double atof(char s[]) { double power, val; int sign, i, sign2, j, n; 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 = val * 10 + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = val * 10 + (s[i] - '0'); power *= 10; } if (s[i] == 'e' || s[i] == 'E') { i++; sign2 = (s[i] == '-') ? 1 : 0; if (s[i] == '-' || s[i] == '+') i++; for (n = 0; isdigit(s[i]); i++) n = n * 10 + (s[i] - '0'); for (j = 0; j < n; j++) power = (sign2) ? (power * 10) : (power / 10); } return val * sign / power; } int isspace(int x) { return (x == ' ' || x == '\t' || x == '\n') ? 1 : 0; } int isdigit(int x) { return (x >= '0' && x <= '9') ? 1 : 0; } //--------------------------------------------------------------
发现 getop函数在处理 ‘+’ 和 ‘-’ 时写的代码有问题,
已修改
by 2018-1-4
相关文章推荐
- 《C程序设计语言》练习 2-8
- 《C程序设计语言》练习 3-3
- 《C程序设计语言》练习 2-6
- 《C程序设计语言》练习 3-4
- 《C程序设计语言》练习 1-12
- 《C程序设计语言》------练习7-7、7-8
- 《C程序设计语言》练习 4-2
- 《C程序设计语言》练习 3-6
- 《C程序设计语言》练习 4-4
- 《C程序设计语言》学习笔记——练习4-1
- 《C程序设计语言》学习笔记——练习2-3
- 《C程序设计语言》练习3-3
- 《C程序设计语言》练习 2-9
- 《C程序设计语言》学习笔记——练习2-1
- 《C程序设计语言》学习笔记——练习2-4
- 《C程序设计语言》练习 2-10
- 《C程序设计语言》练习 1-6,1-7
- 《C程序设计语言》学习笔记——练习2-5
- 《C程序设计语言》练习 3-1
- 《C程序设计语言》练习2-1答案