Recursion 在Pascal中将数组元素传递给循环中的递归函数时
因此,在这个程序中,我们在一个数组Tab1的10个元素中使用随机值,然后我们得到每个Tab1元素的阶乘,并将其放入Tab2,使用两种方法:迭代法和递归法。当使用迭代函数时,Tab2充满阶乘,没有问题,但当我使用递归函数时,程序立即退出。如果你能帮助我深入理解这个问题,我将不胜感激……我在维基百科上读到关于分段错误的文章,其中说,这是因为程序试图到达一个记忆位置,但它没有进入的权限,但问题是当我从Tab1中选择一个特殊元素时,例如Tab1[5]然后把它传给Calc2中的Factorier,它工作得一样好,有什么想法吗Recursion 在Pascal中将数组元素传递给循环中的递归函数时,recursion,segmentation-fault,pascal,Recursion,Segmentation Fault,Pascal,因此,在这个程序中,我们在一个数组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
- 您可以将重复代码部分提取到过程/函数中。在这种情况下,
循环重复3次以写出选项卡数组的内容for
- 您可以将
和Write
合并到一条语句中。例如WriteLn
WriteLn('Tab2:Iterative method')代码>-它是一种更紧凑的形式
- 我无法在设置中重现此问题:
- 您能否提供有关编译器及其编译时选项和操作系统的更多详细信息
只是一个随机值:它逐运行更改。您是如何使用它进行验证的?你知道它的现值是多少吗?我调用了Tab1[5]
factorie(10)代码>来自主块,我没有遇到任何问题。这个问题在您的运行时环境中是间歇性的吗
- 迭代函数只获取并返回
。我认为您应该将返回类型更改为整数
,就像您以递归方式所做的那样。这两个版本之间的运行时差异(存在一些溢出:请参阅负值):LongInt
- 您可以将重复代码部分提取到过程/函数中。在这种情况下,
循环重复3次以写出选项卡数组的内容for
- 您可以将
和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]