为什么这个递归 Pascal 过程没有陷入无限循环?

Why is this recursive Pascal procedure not being caught in an infinite loop?

我想知道为什么下面的递归 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)”时没有陷入无限循环?它不应该永远要求用户输入一个词吗?

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

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

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

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

假设您输入 ABC . 后跟 输入 .

此时,由于参数是 char,第一个输入的字符 'A' 被 return 编辑到您的代码中。

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

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

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

这就是为什么下面的程序

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

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