首次输入后,Ada循环停止

时间:2014-09-07 00:38:02

标签: ada

您好我正在编写一个程序,它从文件读取输入并确定该数字既不是素数也不是复合数,是复合数还是素数。基本上我的问题是我无法让我的程序在一次输入后继续停止,即使我的文件中有更多的数字需要评估。这是我的代码:

WITH Ada.Text_IO, Ada.Integer_Text_IO;
USE Ada.Text_IO, Ada.Integer_Text_IO;

PROCEDURE TestPrime IS
   PACKAGE Boolean_Io IS NEW Ada.Text_Io.Enumeration_Io(Boolean);
   USE Boolean_Io;

   N       : Integer;
   X       : Natural   := 2;
   S       : Integer;
   IsPrime : Boolean   := True;
   C       : Character;
BEGIN
   WHILE NOT End_Of_File LOOP
      Excep:
         BEGIN
      Get(N);
      IF N = 0 OR N = 1 THEN
         Put_Line(N'Img & " is neither prime nor composite");
      END IF;
      LOOP
         S := N mod X;
         IF S = 0 THEN
            IsPrime := False;
         END IF;
         EXIT WHEN X = N - 1;
         X := X + 1;
      END LOOP;
      IF IsPrime = True THEN
         Put_Line(N'Img & " is prime");
      ELSE
         Put_Line(N'Img & " is composite");
      END IF;
       EXCEPTION
           WHEN Data_Error =>
              Put_Line("Data error: You must enter a number!!");
              Get(C);
       END Excep;

   END LOOP;
END TestPrime;

我只是问我的程序卡在哪里以及为什么会这样。任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

由于您还没有描述确切的症状(我),我不确定这是否是问题的全部根源。但是,声明

X : Natural := 2;

将在的过程开始时初始化X。它不会在每次循环时重新初始化X,因为声明不在循环内部。因此,在程序处理完第一个号码N后,X将在您完成后N-1。由于您没有重新初始化它,X将具有相同的值。然后,如果您文件中的第二个数字小于第一个数字,X将从大于此数字的数字开始;因为你继续将它递增1并且当它等于[the new N] - 1时才退出循环,这将是 loooooooooooooooooooooooooongong 等待。

您可以在外部循环的开头说X := 2来重新初始化它。另一种可能性是将X声明为循环内的本地,而不是整个过程的本地;

之类的东西
WHILE NOT End_Of_File LOOP
    Excep:
        DECLARE
            X : Natural := 2;
        BEGIN

等等。

基思的评论值得关注。还有其他一些事情:作为一种实践,我总是写一些像exit when X >= N - 1;而不是exit when X = N - 1;的东西。如果你正确地做事,它不应该有所作为,但这种事情可以防止出现意外出错的事情。最后,查看您的程序,看看如果输入中有0或1,会发生什么。您打印了一条消息,但是仍然进入循环的其余部分,这意味着即使您正确地重新初始化X,您仍然会在2点开始X然后继续增加它直到它等于-1或0,这将永远不会发生。 (实际上,由于环绕,它将需要很长时间。)此外,当N为2时,请仔细检查您的逻辑。您将得到错误的答案或程序将挂起。好的,另外一件事:在你的内循环中,当你设置IsPrime := false;时,你仍然会经历剩下的循环,这是浪费时间。尝试改为

     IF S = 0 THEN
        IsPrime := False;
        exit;    -- No need to keep looping!
     END IF;