Мой код в Pascal не хочет работать правильно. В чем проблема? - PullRequest
0 голосов
/ 07 апреля 2020

Я пишу программу: сумма действительных чисел с использованием рекурсивной функции. Что с этим не так? Он показывает мне только что последний введенный номер.

type
 Indexy = 1..100;
 TPoleReal = array [Indexy] of Real;

var
 j: word;
 r, realRes: real;
 tpr: TPoleReal;


function SoucetCisel(n: TPoleReal; j: word): real;
 begin
   if j>0 then begin
     SoucetCisel:=SoucetCisel + n[j];
     j:=j-1;
   end
 end;


begin i:=0; j:=0;
while not seekeof do begin
  read(r); Inc(j);
  tpr[j]:=r;
  writeln(j, ' ', tpr[j]);
end;
realRes:= SoucetCisel(tpr, j);
writeln(realRes);

end.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

В целях отладки я предлагаю вам упростить основную часть вашего кода до

begin
  i:=0;
  j:=0;
  tpr[j] := 1;
  Inc(j);
  tpr[2] := 2;
  realRes:= SoucetCisel(tpr, j);
  writeln(realRes);
end.

Это должно упростить понимание проблемы.

Первая проблема с вашей функцией SoucetCisel заключается в том, что она на самом деле не является рекурсивной.

Рекурсивная функция - это функция, которая вызывает себя с измененными аргументами, как в архетипической факториальной функции

function Factorial(N : Integer)
begin
  if N = 1 then
    Factorial := 1
  else
    Factorial := N * Factorial(N - 1);
end;

Рекурсивный вызов в это строка

Factorial := Factorial(N - 1);

Ваш SoucetCisel этого не делает, он просто добавляет начальное значение результата функции к значению n[j], поэтому он не является рекурсивным.

Другая проблема заключается в том, что, как написано, он не имеет определенного возвращаемого значения. Во всех реализациях Pascal, с которыми я сталкивался, возвращаемое значение не определено при входе в функцию и остается неопределенным до тех пор, пока ему не будет явно присвоено какое-либо значение. Результатом функции обычно является некоторое пространство в стеке, которое резервирует код функции, сгенерированный компилятором, но которое первоначально (при входе в функцию) содержит некоторое случайное значение, являющееся результатом предыдущего использования стека.

Итак то, из чего вычисляется результат вашей функции SoucetCisel, это

SoucetCisel := ARandomNumber + n[j]

, что, конечно, является еще одним случайным числом. Очевидно, что вы исправляете этот аспект своей функции, гарантируя, что явное присвоение результата функции будет выполнено немедленно при входе в функцию. Как правило, все пути выполнения через функцию должны вести через оператор, который явно присваивает значение результату функции.

Затем вам нужно переписать оставшуюся часть этого так, чтобы на самом деле он рекурсивен в соответствии с требованиями вашей задачи.

Пока вы делаете эти две вещи, я бы посоветовал вам использовать более полезное имя параметра, чем анонимный 'n'. 'n' обычно используется для обозначения неинтересного целого числа.

update Из вашего комментария я не уверен, было ли это серьезно. Если это так, рассмотрим эти две функции

function SumOfReals(Reals : TPoleReal; j : word): real;
var
   i : Integer;
begin
  SumOfReals := 0;
  for i := 1 to j do
    SumOfReals := SumOfReals + Reals[i];
end;

function SumOfRealsRecursive(Reals : TPoleReal; j : word): real;
var
  i : Integer;
begin
 SumOfRealsRecursive := Reals[j];
 if j > 1 then
   SumOfRealsRecursive := SumOfRealsRecursive + SumOfRealsRecursive(Reals, j -1);
end;

Обе эти функции выполняют одно и то же, а именно оценивают сумму содержимого массива Reals до индекса включительно j. Первый делает это итеративно, просто перебирая массив Reals, а второй делает это рекурсивно. Однако должно быть очевидно, что рекурсивная версия абсолютно бессмысленна в этом случае , потому что итеративная версия делает то же самое, но гораздо более эффективно, потому что она не включает в себя копирование всего массива Reals для каждого рекурсивного вызова, что делает рекурсивная версия.

0 голосов
/ 08 апреля 2020

Как я уже говорил вам в комментарии раньше. Попробуйте этот код для вашей pascal программы:

type
 Indexy = 1..100;
 TPoleReal = array [Indexy] of Real;

var
 j: word;
 r, realRes: real;
 tpr: TPoleReal;


function SoucetCisel(n: TPoleReal; j: word): real;
 begin
   if j>0 then begin
     SoucetCisel:=SoucetCisel(n, j-1) + n[j];
   end
 end;


begin i:=0; j:=0;
while not seekeof do begin
  read(r); Inc(j);
  tpr[j]:=r;
  writeln(j, ' ', tpr[j]);
end;
realRes:= SoucetCisel(tpr, j);
writeln(realRes);

end.
...