JAVA 中后缀递减中的 StackOverFlow

StackOverFlow in Postfix Decrement in JAVA

提问人:Tholkappiar 提问时间:5/20/2023 最后编辑:ReilasTholkappiar 更新时间:5/23/2023 访问量:73

问:

这很好用,因为我们在递归调用中使用了前缀递减运算符!

public static void main(String[] args) {
    doubt1(5);
}

前缀递减:

static void doubt(int num)
{
    if(num==0)
        return;
    System.out.println(num);
    doubt(--num);
}

后缀递减:

static void doubt1(int num)
{
    if(num==0)
        return;
    System.out.println(num);
    doubt1(num--);
}

但是当我们使用后缀递减时,它会导致堆栈流错误,我理解它为什么会导致错误,但我想知道,如果我们在递归调用中使用它不会给出溢出错误,我的问题是 ->为什么它没有给出错误,因为它计算并将值传递给递归调用,但不计算调用中的?num-1num-1num--

想要解释为什么它计算不在递归调用中吗?不是为什么会这样!num-1num--

Java 递归 堆栈溢出 postfix-operator prefix-operator

评论

0赞 DuncG 5/20/2023
假设 num 是 5。 与调用相同,而 和 都与调用相同,嵌套调用中的 num 现在是 4...等等doubt(num--)doubt(5)doubt(num-1)doubt(--num)doubt(4)

答:

1赞 Thomas Kläger 5/20/2023 #1
    doubt1(num--);

在内部实现为

    int tmp = num;
    num = num - 1;
    doubt1(tmp);

也就是说,它以递归方式调用具有原始值的方法,因此永远不会达到条件。doubt1num == 0

0赞 John Bollinger 5/20/2023 #2

调用方法时,将计算参数,并将结果值指定为方法参数的初始值。表达式 和 对 具有相同的副作用,但这对方法调用无关紧要。两者的计算结果不同:前者为递减前的 num 值,后者为递减后的值。运算符相对于操作数的顺序是助记符。num----numnumnum

因此,随着

int n = 1;
some_method(n--);

传递给的值为 1,但some_method()

int n = 1;
some_method(--n);

传递给的值为 0。some_method()

但是,在这两种情况下,值 0 都存储在开始的正文执行之前。nsome_method()

0赞 Reilas 5/20/2023 #3

首先,使用一元递减运算符时,操作发生在语句之后或之前。
表达式之后或之前相反。

因此,在这种情况下,和 之间会有区别。num----num

  • doubt(num--)在 call 语句之后递减,而不是在参数表达式之后递减。

  • double(--num),则相反,递减发生在参数表达式之前。

从本质上讲,从编译器的角度来看,对于语句,您有以下几点。doubt(--num)

  1. 获取num
  2. 递减num
  3. 应用为参数numdoubt
  4. 使用参数值执行doubt

或者,您拥有以下内容。doubt(num--)

  1. 获取num
  2. 应用为参数numdoubt
  3. 递减(没有效果,因为参数值已经设置)num
  4. 使用参数值执行doubt

从本质上讲,对于语句,在编译器拥有 并准备好调用 之后,它将递减 。
与有 ,然后递减,然后调用 相反。
doubt(num--)numdoubtnumnumdoubt