Recursion 在Pascal中将数组元素传递给循环中的递归函数时

Recursion 在Pascal中将数组元素传递给循环中的递归函数时,recursion,segmentation-fault,pascal,Recursion,Segmentation Fault,Pascal,因此,在这个程序中,我们在一个数组Tab1的10个元素中使用随机值,然后我们得到每个Tab1元素的阶乘,并将其放入Tab2,使用两种方法:迭代法和递归法。当使用迭代函数时,Tab2充满阶乘,没有问题,但当我使用递归函数时,程序立即退出。如果你能帮助我深入理解这个问题,我将不胜感激……我在维基百科上读到关于分段错误的文章,其中说,这是因为程序试图到达一个记忆位置,但它没有进入的权限,但问题是当我从Tab1中选择一个特殊元素时,例如Tab1[5]然后把它传给Calc2中的Factorier,它工作得

因此,在这个程序中,我们在一个数组Tab1的10个元素中使用随机值,然后我们得到每个Tab1元素的阶乘,并将其放入Tab2,使用两种方法:迭代法和递归法。当使用迭代函数时,Tab2充满阶乘,没有问题,但当我使用递归函数时,程序立即退出。如果你能帮助我深入理解这个问题,我将不胜感激……我在维基百科上读到关于分段错误的文章,其中说,这是因为程序试图到达一个记忆位置,但它没有进入的权限,但问题是当我从Tab1中选择一个特殊元素时,例如Tab1[5]然后把它传给Calc2中的Factorier,它工作得一样好,有什么想法吗

Program recursive;
Type
T = array [1..10] of LongInt;
Var
Tab1, Tab2 : T;
num : integer;

Function FactorielleIterative(N : integer) : integer;
Var
F, i : integer;
Begin
    F := 1;
    for i:=1 to N Do
        F := F*i;
    FactorielleIterative := F;
End;

Function FactorielleRecursive(N : LongInt) : LongInt;
Begin
        if (N=1) Then
            FactorielleRecursive := 1
        Else
        FactorielleRecursive := N * FactorielleRecursive(N-1);
End;

Procedure Fill(var Tab : T);
Var
i : Integer;
Begin
    Randomize;
    For i:=1 to 10 Do
    Begin
            Tab[i] := Random(10);
    End;
    For i:=1 to 10 Do
        Write('[', Tab[i], '] ');
End;

Procedure Calc1(Tab1 : T; var Tab2 : T);
Var
i : integer;
Begin
    For i:=1 to 10 Do
    Begin
            Tab2[i] := FactorielleIterative(Tab1[i]);
    End;
    For i:=1 to 10 Do
        Write('[', Tab2[i], '] ');
End;

Procedure Calc2(Tab : T; var Tab2 : T);
Var
i : integer;
Begin
    For i:=1 to 10 Do
    Begin
            Tab2[i] := FactorielleRecursive(Tab[i]);
    End;
    For i:=1 to 10 Do
        Write('[', Tab2[i], '] ');
End;

Begin

        Write('Tab1 : ');
        Writeln;
        Fill(Tab1);
        Writeln;
        Writeln;
        Write('Tab2 : Iterative method');
        Writeln;
        Calc1(Tab1, Tab2);
        Writeln;
        Writeln;
        Write('Tab2 : Recursive method');
        Writeln;
        Calc2(Tab1, Tab2);

     Readln;
End.
我的想法:

  • 我无法在设置中重现此问题:
注意:应删除未使用的变量

  • 您能否提供有关编译器及其编译时选项和操作系统的更多详细信息

  • Tab1[5]
    只是一个随机值:它逐运行更改。您是如何使用它进行验证的?你知道它的现值是多少吗?我调用了
    factorie(10)来自主块,我没有遇到任何问题。这个问题在您的运行时环境中是间歇性的吗

  • 迭代函数只获取并返回
    整数
    。我认为您应该将返回类型更改为
    LongInt
    ,就像您以递归方式所做的那样。这两个版本之间的运行时差异(存在一些溢出:请参阅负值):

小调:

  • 您可以将重复代码部分提取到过程/函数中。在这种情况下,
    for
    循环重复3次以写出选项卡数组的内容
  • 您可以将
    Write
    WriteLn
    合并到一条语句中。例如
    WriteLn('Tab2:Iterative method')-它是一种更紧凑的形式
    • 我的想法:

      • 我无法在设置中重现此问题:
      注意:应删除未使用的变量

      • 您能否提供有关编译器及其编译时选项和操作系统的更多详细信息

      • Tab1[5]
        只是一个随机值:它逐运行更改。您是如何使用它进行验证的?你知道它的现值是多少吗?我调用了
        factorie(10)来自主块,我没有遇到任何问题。这个问题在您的运行时环境中是间歇性的吗

      • 迭代函数只获取并返回
        整数
        。我认为您应该将返回类型更改为
        LongInt
        ,就像您以递归方式所做的那样。这两个版本之间的运行时差异(存在一些溢出:请参阅负值):

      小调:

      • 您可以将重复代码部分提取到过程/函数中。在这种情况下,
        for
        循环重复3次以写出选项卡数组的内容
      • 您可以将
        Write
        WriteLn
        合并到一条语句中。例如
        WriteLn('Tab2:Iterative method')-它是一种更紧凑的形式

      如果
      选项卡[]
      数组包含零值,则不会考虑会发生什么。这种情况是可能的,因为您调用
      Random(10)
      ,它将返回一个范围为0的值。。九,

      函数factoriellerIterative()
      中,零参数被视为“1”值(因为
      for
      循环未执行)

      函数FactorielleRecursive()
      中,零参数被视为“0”值,递归调用的结果是
      FactorielleRecursive(N-1)导致范围溢出


      解决方案很简单,所以我把它留给您来解决,以免破坏您的家庭作业。

      您没有考虑如果
      选项卡[]
      数组包含零值会发生什么。这种情况是可能的,因为您调用
      Random(10)
      ,它将返回一个范围为0的值。。九,

      函数factoriellerIterative()
      中,零参数被视为“1”值(因为
      for
      循环未执行)

      函数FactorielleRecursive()
      中,零参数被视为“0”值,递归调用的结果是
      FactorielleRecursive(N-1)导致范围溢出


      解决方法很简单,所以我让你自己来解决,以免破坏你的家庭作业。

      嗨,谢谢。这是真的,它将0传递给递归函数,而递归函数不能处理它。我做了随机(10)+1,现在它不会导致堆栈溢出,再次感谢你,汤姆。不客气!嗨,谢谢。这是真的,它将0传递给递归函数,而递归函数不能处理它。我做了随机(10)+1,现在它不会导致堆栈溢出,再次感谢你,汤姆。不客气!是的@汤姆布伦伯格发现了根本原因。抢手货非常感谢。铀的另一个结论是:如果你有有用的输出,请把它附在你的问题上。对我的警告:在我的复制过程中,我没有检查最小的输入值。是的@汤姆布伦伯格发现了根本原因。抢手货非常感谢。铀的另一个结论是:如果你有有用的输出,请把它附在你的问题上。对我的警告:在我的复制过程中,我没有检查最小的输入值。
      bash$ fpc so.pas && ./so
      Free Pascal Compiler version 3.2.0+dfsg-12 [2021/01/25] for x86_64
      Copyright (c) 1993-2020 by Florian Klaempfl and others
      Target OS: Linux for x86-64
      Compiling so.pas
      so.pas(6,1) Note: Local variable "num" not used
      Linking so
      76 lines compiled, 0.1 sec
      1 note(s) issued
      
      Tab2 : Iterative method
      [5040] 
      [720] 
      [2] 
      [1] 
      [720] 
      [5040] 
      [24] 
      [1] 
      [-25216] <<<<<<<<<<<<<<<<< Integer overflow
      [24] 
      
      Tab2 : Recursive method
      [5040] 
      [720] 
      [2] 
      [1] 
      [720] 
      [5040] 
      [24] 
      [1] 
      [40320] 
      [24]