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) 将首先尝试提取一个值,然后检查它是否仍在数组的边界内。如果没有,那么它已经发生了段错误。