当前位置: 代码迷 >> 综合 >> C程序设计语言 5-10
  详细解决方案

C程序设计语言 5-10

热度:11   发布时间:2024-01-29 09:33:54.0

练习5-10 编写程序expr,以计算从命令行输入的逆序波兰表达式的值,其中每个运算符或操作数用一个单独的参数表示。例如,命令:expr 2 3 4 + * 将计算表达式2*(3+4)的值。

给结果之前先记录一下书上这个牛逼的程序:

P101,允许输入参数的模式匹配程序。

#include <stdio.h>
#include <string.h>
#define MAXLINE 1000int getline(char *line, int max);int main(int argc, char *argv[]) {char line[MAXLINE];long lineno = 0;int c, except = 0, number = 0, found = 0;while (--argc > 0 && (*++argv)[0] == '-')while (c = *++argv[0])switch (c) {case 'x':except = 1;break;case 'n':number = 1;break;default:printf("find: illegal option %c\n", c);argc = 0;found = -1;break;}if (argc != 1)printf("Usage: find -x -n pattern\n");elsewhile (getline(line, MAXLINE) > 0) {lineno++;if ((strstr(line, *argv) != NULL) != except) {if (number)printf("%ld:", lineno);printf("%s", line);found++;}}return found;
}int getline(char *line, int max) {int c, i;for (i = 0; i < max - 1 && (c = getchar()) != EOF && c != '\n'; ++i)*(line + i) = c;if (c == '\n') {*(line + i) = c;++i;}*(line + i) = '\0';return i;
}

下面是练习5-10答案:

#include <stdio.h>
#include <string.h>
#include <ctype.h>#define NUMBER '0'
#define MAXCHAR 1000
#define MAXSTACK 100int sp = 0;
int stack[MAXSTACK];int atoi(char s[]);
int pop(void);
void push(int c);int main(int argc, char *argv[]) {int c, op2, type, number, i;printf("--------------------------------------------------\n");printf("Note: This simplified calculator can only take in '+', '-',\n");printf("'`'(multiple), '/', and integer number~\n");printf("--------------------------------------------------\n");while (--argc > 0) {printf("argc:%d\n", argc);c = (*++argv)[0];printf("%c\n", c);if (c >= '0' && c <= '9'){for (i = 0; c >= '0' && c <= '9'; i++)c = *(*argv + i);if (c == '\0'){number = atoi(*argv);c = NUMBER;}}switch (c) {case NUMBER:push(number);break;case '+':push(pop() + pop());break;case '-':op2 = pop();push(pop() - op2);break;case '`':push(pop() * pop());break;case '/':if (0 == (op2 = pop())) {printf("Error: '0' cannot be divided.\n");return 0;}push(pop() / op2);break;default: printf("Error: Unknown operator(s)\n");printf("Up tp now, the answer is:%d\n", pop());return 0;}}printf("Answer is: %d\n", pop());return 1;
}int pop(void) {if (sp <= 0){printf("return: no value remain in stack.\n");return 0;}elsereturn stack[--sp];
}void push(int op) {if (sp >= MAXSTACK) {printf("return: stack has not enough space.\n");return;}elsestack[sp++] = op;return;
}int atoi(char s[]) {int i, sign, val;sign = (s[i] == '-') ? -1 : 1;if (s[i] == '+' || s[i] == '-')i++;for (val = 0; isdigit(s[i]); i++)val = 10 * val + (s[i] - '0');return sign * val;
}

说明一下拿“`"(键盘上tab键上面哪个键)做乘号的原因:

main函数一般情况下把接受的参数当作字符串处理,但是当指令中出现"^", "&", "*", "|"四个符号的时候会将其作为模式参数处理。经过不完全的测试,“^”符号可以使main函数在下一行继续追加参数;“&”符号可以调取其他程序,在“&”后面追加其他程序的路径或路径名可以打开其他程序,而且如果被调取的程序也可以接受命令行参数的话,还可以继续在后面增加参数命令;“*”符号会打印当前程序路径下所有的文件,所以在该程序中如果使用“*”作为main函数的参数,会得到不想要的结果;“|”符号功能不确定,看上去有点像linux的管道命令,连接不同程序用。

下面是一个供测试用的main函数,编译后在命令行调取,追加相应参数可以观察到结果。

#include <stdio.h>void main(int argc, char *argv[]) {while (--argc >= 0) {printf("argc:%d, argv[argc-1]:%s\n", argc, argv[argc]);}return;
}