代码之家  ›  专栏  ›  技术社区  ›  EPKasper

Ada循环在第一次输入后停止

ada
  •  0
  • EPKasper  · 技术社区  · 11 年前

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

    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 回复  |  直到 11 年前
        1
  •  1
  •   ajb    11 年前

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

    X : Natural := 2;
    

    将初始化 X 在程序开始时 只有 。它不会重新初始化 十、 每次它通过循环时,因为声明不在循环内。因此,在程序处理第一个数字之后 N , 十、 N-1 当你完成后。因为你不重新初始化它, 十、 将具有相同的值。如果文件中的第二个数字小于第一个数字, 十、 将以大于此的数字开始;因为您一直将其递增1,并且只有当它等于时才退出循环 [the new N] - 1 ,这将是 噢,噢,噢 等待

    你可以说 X := 2 在外部循环的开头重新初始化它。另一种可能是声明 十、 作为循环内部的局部,而不是整个过程的局部;类似的东西

    WHILE NOT End_Of_File LOOP
        Excep:
            DECLARE
                X : Natural := 2;
            BEGIN
    

    等等

    基思的评论值得关注。还有几件事:作为实践,我总是会写一些像 exit when X >= N - 1; 而不是 exit when X = N - 1; 。如果你做得正确,这应该不会有什么不同,但这种事情可以防止意外出错时被吊死。最后,看看你的程序,看看如果输入中有0或1会发生什么。你打印了一条信息 进入循环的其余部分,这意味着即使重新初始化 十、 正确,您仍将启动 十、 然后继续增加,直到等于-1或0,这是永远不会发生的。(事实上,由于包装,这会发生,但这需要很长时间。)此外,当 N 为2。你要么得到错误的答案,要么程序将挂起。好的,还有一件事:在你的内循环中,当你设定 IsPrime := false; ,您仍然要完成循环的其余部分,这是浪费时间。改为尝试

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