使用’*’乘以时,C程序的输出令人惊讶

解决了K&R中的5-10练习:

编写程序expr,它从命令行计算反向波兰语表达式,其中每个运算符或操作数是一个单独的参数。 例如,expr 2 3 4 + *评估2 *(3 + 4)。

在带有’*’字符的表达式中似乎存在问题,即使是基本的问题,例如:2 2 *。 由于一些奇怪的原因,’*’没有放入运算符数组,而所有其他字符如’+’,’ – ‘,’/’通常都是。 我已经隔离了代码的一部分(while循环),这似乎是错误的。 推送function来自第4章,只需要编译代码。

#include  void push(double f); main(int argc, char *argv[]) { int a = 0; int b; char operator[10]; while (--argc > 0) { if (isdigit(*argv[argc])) push(atof(argv[argc])); else if (*argv[argc]=='+' || *argv[argc]=='-' || *argv[argc]=='*' || *argv[argc]=='/') operator[a++] = *argv[argc]; } for (b = 0; b < a; b++) printf("%c", operator[b]); printf("\n"); 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; else printf("error: stack full, can't push %g\n", f); } 

产量

 [user@machine Desktop]$ ./prog + + ++ [user@machine Desktop]$ ./prog * [user@machine Desktop]$ ./prog * * [user@machine Desktop]$ ./prog + / * - -/+ 

你的shell正在解释*并扩展它。 对于shell,’*’表示“匹配所有文本”,这就是像ls *.c这样的命令工作的原因。 输入echo * ,你会明白我的意思。 将您的参数放在单引号中以防止shell解释它们。

例如,

 ./prog '*' ./prog 2 2 '*' ./prog '2' '2' '*' 

请注意,如果您将所有参数放在引号内,那么整个内容将作为argv一个条目提供给您的程序,这可能不是您想要的。

例如,此命令将使用文本2 2 *填充argv[1] ,而不是在argv[1]argv[2]argv[3]中将其分解为2*

 ./prog '2 2 *' 

您还可以使用反斜杠而不是引号来转义需要转义的单个字符。 如果你告诉shell \*你的程序将得到一个文字\*

例如,

 ./prog 2 2 \* 

这种模式匹配通常称为通配。