我的程序在 for 和 if 之间来回弹跳,我不知道为什么



我正在做一些功课,有一个问题,我必须制作一个程序来告诉我用户给出的两个数字之间有多少个素数。出于某种原因,当我使用 F8 测试程序时,我可以看到程序在"for"和"if"之间来回跳动,没有明显的原因。是的,我必须使用这种语言。

我尝试重新调整IDE,希望它只是一些错误(就像Android Studio上经常发生的那样(。我不知道还能尝试什么,这是我第一次使用Lazarus和PASCAL。

program PrimoEntre;
var
a, b, i, q: Integer;
begin
write('Ingrese el primer valor: ');
readln(a);
write('Ingrese el segundo valor: ');
readln(b);
for i:=a to b do  //It starts bouncing back and forth from here...
begin
q:=2;
if((b>=2)AND(b<=10)) then //...to here.
begin
while((q>=2) and (q<=b)) do
begin
if(a<>b) then
begin
if((a MOD b)=0) then
begin;
//i ES NO PRIMO
if(q=b) then
begin
writeln('No existen numeros primos entre ', a, ' y ', b, '.');
end;
q:=(q+1);
end;
end
else
begin
if(q=b) then
begin
//i ES PRIMO
writeln(i, ' es primo.');;
q:=1
end;
end;
end;
end
else
begin
while((q>=2) and (b<=10)) do
begin
if(a<>b) then
begin
if((a MOD b)=0) then
begin
//i ES NO PRIMO
if(q=b) then
begin
writeln('No existen numeros primos entre ', a, ' y ', b, '.');
end;
q:=(q+1);
end;
end
else
begin
if(q=b) then
begin
//i ES PRIMO
writeln(i, ' es primo.');
q:=1
end
end;
end;
end;
end;
readln();
end.

我希望输出为以下之一:
-控制台每次找到a和b之间的质数时都会写入-
控制台说a和b之间没有任何素数。

相反,没有结果。程序只是卡住了,我必须手动终止它。

你说你正在尝试在范围内找到质数...b. 问题是 您正在以非常不必要的复杂方式执行此操作,主要原因 你的程序到处跳跃是你让它这样做是因为 您正在使q变量的值到处跳跃。

我认为你应该放慢脚步,想想你想做什么:

  • 您希望迭代ab范围内的整数。 您的for循环确实如此 这很好,i的价值就是你正在测试的素数。我正要去 将其称为外部for循环。

  • 出错的地方是不必要地执行while循环来测试素数。

  • 一旦你建立了你正在测试的i值,你想要做的是 测试是否存在任何 1 或i以外的i因子。 为此,您 可以使用一个简单的内部for循环,该循环迭代值j(所谓的避免 与您的q混淆(以确定i是否可以被余数为零的j整除,使用mod测试: 如果是这样,那么继续内部j循环就没有意义了。

  • 接下来要考虑的是 循环for j := ... to ...应该是。 考虑价值观是没有意义的 由于显而易见的原因,高于i平方根的j如果i的因数大于此值,则还必须具有 哪个更低。

  • 如果j循环完成而未找到因子,则i为素数。

尝试对内部、j循环进行编码,您将看到结果如何 比现有代码更简单(更可预测(,而且很少 编码错误的机会,并且由于执行而更容易调试 只是为i的每个值"落"它.

顺便说一句,我完全同意关于结构化编码作为一般命题@TomBrunberg,但我认为您在这里需要的两个嵌套for循环实际上并不需要分成不同的过程/函数,尽管您可以尝试 一旦你让代码正常工作。

错误的原因混合了以下事实:问题高度依赖于您的输入,以及您没有在else原因中处理某些情况。

例如,我用a=20b=30运行了您的程序。程序运行到for循环,这是正确的。但是,(b>2) and (b<=10)条件为 false,这使得编译器转到else分支。然而,它在那里遇到的第一件事是while (q>=2) and (b<=10)从一开始就是错误的。正如您在问题中所说,它会在那里反弹。

使用a=2b=9,您的程序具有完全不同的行为。

如何解决?我想你首先必须澄清你想要什么。然后,我认为,修复将是显而易见的。

您的程序缺乏结构,因为整个程序都塞满了主过程。

由于前一个,它有太多的"缩进级别"或"逻辑链",无法读取和管理。对于缩进级别或逻辑链,我的意思是例如您的:

'for<condition> - if<condition> - while<condition> - if<condition> - if<condition> - if<condition> - writeln(). 

由于条件的长链,很难评估改变会产生什么影响,当你试图修复某些事情时,你可能会发现自己陷入越来越深的麻烦。

我建议你放弃你现在拥有的东西,根据主操作将你的程序划分为过程/函数:例如GetUserEntry(var a, b: integer)function IsPrime(x: integer): booleanprocedure ShowResult()和主程序(GetUserEntryfor a to b if IsPrime then add to outstringShowResult(outstring)(。

最后,使用适当的缩进设置代码的格式,使其可读。

相关内容

最新更新