【问题标题】:Why is this recursive Pascal procedure not being caught in an infinite loop?为什么这个递归 Pascal 过程没有陷入无限循环?
【发布时间】:2021-05-14 08:29:29
【问题描述】:

我想知道为什么下面的递归 Pascal 过程实际上会终止:

procedure reverseWordRecursive;

  var
  word : char;

begin
  read(word);
  if word = '.' then
    writeln
  else
    begin
      reverseWordRecursive;
      write(word)
    end;
end; {reverseWordRecursive}

该过程的行为与代码可能暗示的不同。当您运行代码时,read(word) 的调用仅在过程开始时运行一次。每次递归调用开始时不会要求用户输入单个char,而是输入char 的整个string

为什么它没有在“read(word)”调用中陷入无限循环?它不应该要求用户永远输入一个单词吗?

过程如何知道每个递归调用实际使用相应的下一个字符?

【问题讨论】:

  • 它会一直递归直到输入是.
  • 对不起,我没有澄清程序的奇怪行为。我现在编辑它。汤姆回答了。还是谢谢你。

标签: recursion infinite-loop pascal


【解决方案1】:

Read() 过程在用于读取标准输入时,将所有键入的字符存储到缓冲区中,包括终止 CR/LF (Enter) 的条目。

Read() 返回的值取决于传递给Read() 的参数类型。例如,如果参数是字符串,则返回除终止 CR/LF 之外的所有字符(ReadLn() 也将返回 CR/LF)。如果变量是Char,则返回一个字符,其余输入的字符保留在缓冲区中,稍后可以通过再次调用Read() 来读取。

因此,在您的代码中,读取过程将标准输入读入缓冲区,直到点击 Enter

假设您输入 ABC 然后输入 Enter kbd>.

此时,由于参数是char,第一个输入的字符“A”将返回到您的代码中。

char 被评估,如果不是 '.'该过程被递归调用。现在,输入缓冲区中有字符,因此从缓冲区中读取下一个字符“B”。 'C' 也是如此,最后是 '.'。

这将终止递归调用,并开始展开堆栈,这以相反的顺序发生,C、B 和 A。

【讨论】:

  • 谢谢。我现在知道了。这是我第一次看到这个怪癖。 :)
【解决方案2】:

当 Pascal 程序从标准输入流中读取时,它们通常不会一次读取单个字符,而是读取一行字符并将其存储在缓冲区中,然后从该缓冲区中读取字符。这种缓冲在幕后自动发生。

这就是为什么下面的程序

program example(input);
var
   c : char;
begin
   writeln('Reading a character');
   read(c);
   writeln('The character read was ', c);
end.

将等待您输入一行字符,即使它只读取一个字符。

【讨论】:

    猜你喜欢
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多