您好我正在编写一个程序,它从文件读取输入并确定该数字既不是素数也不是复合数,是复合数还是素数。基本上我的问题是我无法让我的程序在一次输入后继续停止,即使我的文件中有更多的数字需要评估。这是我的代码:
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;
我只是问我的程序卡在哪里以及为什么会这样。任何帮助将不胜感激。谢谢!
答案 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;