C-奇怪输出中的命令行参数
Command line arguments in C- weird output
所以我编写了一个简单的反向波兰计算器的代码,该计算器仅适用于使用命令行参数的正数。它将数字存储在堆栈中。 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)
然后我收到所有操作员的 'segmentation fault (core dumped)' 消息。
为了了解我程序的控制流程,我把一部分代码改成这样:
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) 我的第一个程序适用于所有操作员,“*”除外。可能是什么原因?为什么控制转到了else部分?
2) 交换条件后,我访问了哪些我没有权限访问的内存?如果它是 NULL,那么不应该打破 while 循环并继续吗?
PS。这是我的第一个问题,所以如果我的写作风格有任何错误,或者问题太长,请告诉我!我们从错误中吸取教训:)
另外,我的编译器-GCC,OS-Ubuntu.
网友xing说的很对
为了扩展它,&&
运算符从左到右计算。如果左侧条件无效,则右侧条件将不会被评估,因为 return 值已知为 0(假)。
运行 ./pcalc 2 3 *
将扩展为 ./pcalc 2 3 <all the files/directories in current working directory>
因此它永远不会将运算符压入运算符堆栈。
while(--argc>0 && (c=(*++argv)[0]))
将在提取第一个元素之前首先检查它是否仍在参数数组中。
while((c=(*++argv)[0]) && --argc>0)
将首先尝试提取一个值,然后检查它是否仍在数组的边界内。如果没有,那么它已经发生了段错误。
所以我编写了一个简单的反向波兰计算器的代码,该计算器仅适用于使用命令行参数的正数。它将数字存储在堆栈中。 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)
然后我收到所有操作员的 'segmentation fault (core dumped)' 消息。
为了了解我程序的控制流程,我把一部分代码改成这样:
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) 我的第一个程序适用于所有操作员,“*”除外。可能是什么原因?为什么控制转到了else部分?
2) 交换条件后,我访问了哪些我没有权限访问的内存?如果它是 NULL,那么不应该打破 while 循环并继续吗?
PS。这是我的第一个问题,所以如果我的写作风格有任何错误,或者问题太长,请告诉我!我们从错误中吸取教训:)
另外,我的编译器-GCC,OS-Ubuntu.
网友xing说的很对
为了扩展它,&&
运算符从左到右计算。如果左侧条件无效,则右侧条件将不会被评估,因为 return 值已知为 0(假)。
运行 ./pcalc 2 3 *
将扩展为 ./pcalc 2 3 <all the files/directories in current working directory>
因此它永远不会将运算符压入运算符堆栈。
while(--argc>0 && (c=(*++argv)[0]))
将在提取第一个元素之前首先检查它是否仍在参数数组中。while((c=(*++argv)[0]) && --argc>0)
将首先尝试提取一个值,然后检查它是否仍在数组的边界内。如果没有,那么它已经发生了段错误。