Pascal中的循环嵌套:repeat循环中使用for循环

5

到目前为止,你们都非常有帮助,这里又有一个让你们头疼的问题!

我有一个基本的单词猜测游戏,使用Pascal编写,适用于Delphi 7控制台,其中猜测(正确或错误)存储在名为“guesses”的固定数组中。现在我需要测试一下他们是否已经猜过那个字母。我有以下代码...

Write ('Guess a letter: ');
Readln (guess);
Guess := UpCase(Guess);
repeat
  for i := 1 to 20 do
  begin
    if guess = guesses[i] then
      begin
        guessed := true;
      end
    else begin
      guessed := false;
    end;
  end;
until (guessed = true) or (i = 20) ;

我的问题是它会循环执行20次for循环,并应该在第一个字母中结束,因为它不在“guesses”数组中,但它继续重复。在循环了20次for循环并没有找到猜测字母的任何条目之后,它应该退出,并将布尔值“guessed”设置为false。

非常感谢您的帮助!


这不是完整的代码,对吧?如果是的话,我不理解Delphi/Pascal的作用域。如果我的猜测正确,请发布完整的代码。 - mkro
显然不行,因为没有声明任何变量。 - Warren P
1
循环变量只有在循环包含break语句时才会被定义。如果将guessed设置为true,您可以轻松地使用break。继续搜索毫无意义。 - jpfollenius
2个回答

9
你编写的代码毫无意义。
  1. 为了在找到猜测值时退出for循环,请在guessed := true下面添加一个break。

  2. 为什么要使用一个永远为真,一个可能永远不为真的条件重复相同的逻辑?我猜你在repeat循环中展示了部分代码而没有全部展示。在这种情况下,stackoverflow上的一个好习惯是在你真正有100行代码但不想在这里展示的地方放入类似于:do_something_here();的东西。

  3. 如果您显示变量声明,我们就可以看到类型。

如果:

  1. 从for循环中退出。
  2. 只有在每种情况下都执行某些不同的操作(例如要求用户输入一些新输入)才需要执行While循环。

以下是至少有用的一些代码:

(1)它会要求您输入一些内容,并重复此过程,直到您输入与硬编码列表中的元素匹配的内容。

(2)它将在您给出某些输入的情况下终止,而不像您的代码可能永远不会终止。它还不会在找到匹配项后浪费时间在其他元素上。

(3)它简单地显示了您应该验证输入,否则您将遇到异常。如果您在代码中什么也没有输入并只是按下回车键会发生什么?你会得到一个无尽的循环。

procedure Demo;
var
  guess:Char;
  guesses:Array of Char;
  i: Integer;
  guessed:Boolean;
begin
 repeat
  setup_guesses(guesses); // not shown
  Write ('Guess a letter: ');
  Readln (guess);
  Guess := UpCase(Guess);
  if (Ord(Guess)>='A') and (Ord(Guess)<='Z') then begin
   guessed := false;
   for i := Low(guesses) to High(Guesses) do // why hard code 1..20???
   begin
     if guess = guesses[i] then
       begin
         guessed := true;
         break;
       end;
   end;
  end;
 until (guessed = true);
 if guessed then
   WriteLn('An element in guesses matched your input')
 else
   WriteLn('No element in guesses array matches your input')
end;

感谢您的帮助和快速回复!我会研究您的代码并尝试做出改进! - Chunky1318
1
P - 除了这一行 if Length(Guess)<>1 then break; :) - user532231
P - 没有问题,但在我看来没什么用;或者说能否从控制台读取一个字符,而 Length <> 1 呢? - user532231
guessed := guess = guesses[i]; - Premature Optimization
2
UpCase接受一个Char,所以是的,那些是Char变量。个人认为长形式的IF THEN语句比a:= b = c更易读。 - Warren P

7
我的问题是它跟随for循环20次,应该在第一个字母不在“猜测”数组中并且不断重复时结束。在循环了for循环20次并且没有找到猜测字母的条目后,它应该以布尔值“guessed”为假退出。
你不能在for循环外使用循环变量I:
Pascal For Loop 设计选择: 循环变量必须是通常范围内的序数类型
正常终止后,循环变量未定义
循环变量不能在循环中更改
循环参数可以更改,但它们只被评估一次,因此不影响循环控制

http://courses.cs.vt.edu/~cs3304/Spring00/notes/Chapter-7/tsld026.htm


好的观点。循环变量在离开后技术上是未定义的。关注这些细节总是明智的。 - Warren P
1
并且有一个编译器提示,在第15行。 - Premature Optimization
一个例外是针对结果变量。它在循环之外定义。写function Search(aItem: TObject): integer; begin for result := 0 to List.Count-1 do if List[result]=aItem then exit; result := -1; end;是完全安全的。 - Arnaud Bouchez
Arnaud:这在哪里有记录?可能是意外的实现细节。 - Marco van de Voort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接