所以我为一个简单的反向波兰计算器编写了一个代码,该计算器仅对正数使用命令行参数。它将数字存储在堆栈中。 push和pop的功能在一个单独的源文件中 我还写了另一个程序,检查我以前程序的控制流程 这是第一个程序:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
void push(double);
double pop(void);
int main(int argc, char *argv[])
{
int c;
double op2;
while(--argc>0 && (c=(*++argv)[0]))
if(isdigit(c))
push(atof(argv[0]));
else if(c=='+')
push(pop()+pop());
else if(c=='-')
{
op2=pop();
push(pop()-op2);
}
else if(c=='*')
push(pop() * pop());
else
{
op2=pop();
push(pop()/op2);
}
printf("\n%f\n", pop());
return 0;
}
运行此程序后,所有运算符都工作,除了'*'。例如,如果我的输入是'./pcalc 2 3 *',那么这就是我得到的输出:
error: stack emptyerror: stack emptyerror: stack emptyerror: stack empty
-nan
如果我在while循环中交换条件,就像这样
while((c=(*++argv)[0]) && --argc>0)
然后我收到所有运营商的“分段故障(核心转储)”消息。
要知道我的程序的控制流程,我将部分代码更改为:
while(--argc>0 && (c=(*++argv)[0]))
if(isdigit(c))
printf("\nentry1\n");
else if(c=='+')
printf("\nentry2\n");
else if(c=='-')
printf("\nentry3\n");
else if(c=='*')
printf("\nentry4\n");
else
printf("\nentry5\n");
该计划的其余部分与第一部分类似。在输入'./pcalc 2 3 *'时,我得到了这个输出:
entry1
entry1
entry5
entry5
entry5
entry5
entry5
error: stack empty
0.000000
这意味着控制没有用于星号的情况,而是转到了其他部分 当我交换while循环的条件时,我得到的输出与上面类似(对于所有运算符,它显示控制流,对于'*',它显示与上面相同的错误),除了它,它没有不显示任何运算符的堆栈空错误,而是显示分段错误(核心转储)消息。
所以这就是我想问的问题:
1)我的第一个程序适用于所有操作员,除了'*'。可能是什么原因?控制权为什么要转到其他部分?
2)在交换条件后,我访问的内存是什么,我没有权限?如果它是NULL,那么不应该打破while循环并继续?
PS。这是我的第一个问题,所以如果我的写作风格有任何错误,或者问题太长,请告诉我!我们从错误中吸取教训:)
另外,我的编译器-GCC,OS-Ubuntu。
答案 0 :(得分:1)
用户xing绝对正确。
要对其进行扩展,将从左到右对&&
运算符进行求值。如果左侧条件无效,则不会评估正确的条件,因为已知返回值为0(假)。
运行./pcalc 2 3 *
将扩展为./pcalc 2 3 <all the files/directories in current working directory>
,因此它永远不会将操作员推送到运营商的堆栈上。
while(--argc>0 && (c=(*++argv)[0]))
将首先检查它是否仍在arguments数组中。while((c=(*++argv)[0]) && --argc>0)
将首先尝试提取值,然后检查它是否仍在数组的边界内。如果没有,那么它已经被分割了。