Rekurencja Pascal- problem z programem

0

Witam! Mam problem z poniższym programem. Chciałbym aby podawał największą wartość z tabeli. Niestety nie wiem czemu ale podaje za każdym razem wartość w pierwszej komórce tabeli. Jeśli to głupie pytanie, przepraszam, uczę się.

I jeszcze mam pytanie związane z funkcjami. Dlaczego gdy napisałem "surową" funkcję, która 10 razy wypisuje wartość tejże funkcji, pokazuje liczby -164, -176, i potem odejmuje 20 aż do -336.

PROGRAM prog;
uses crt;

   var a:integer;
       var tab:array[1..10] of integer;

function max(i:integer):integer;

BEGIN


     if max<tab[i] then  begin
     max:=tab[i];
     end;

     i:=i+1;

      if i<=10 then max(i);

END;


BEGIN
clrscr;
      randomize;
     for a:=1 to 10 do begin
        tab[a]:=random(30);
     end;

     for a:=1 to 10 do begin
        write(tab[a]:4);
     end;

    writeln;
    writeln;
    writeln('Najwieksza liczba to ',max(1));

    readln;

END.
0

Poczytaj o funkcjach, bo w funkcji Max robisz jakieś dziwne porównania, jak Max bez parametru i w ogóle nie wiadomo co chcesz osiągnąc tym błednym kodem. Najprościej zrób tak jak poniżej. I popracuj nad normalnym formatowaniem kodu, coś jak w stylu poniżej.

var
  a, Max : integer;
  tab : array[1..10] of integer;
begin
  randomize;
  for a := 1 to 10 do
  begin
    tab[a] := random(30);
  end;
  for a := 1 to 10 do
  begin
    write(tab[a] : 4);
  end;
  Max := 0;
  for a := 1 to 10 do
  begin
    if tab[a] > Max then
      Max := tab[a]
  end;
  writeln;
  writeln;
  writeln('Najwieksza liczba to ', Max);
  readln;
end.
0

Masz gotowca...:

program MaxValue;

{$APPTYPE CONSOLE}

var
  I, iMax: Integer;
  Tab: array [0 .. 9] of Integer;
begin
  Randomize();

  for I := 0 to 9 do
    begin
      Tab[I] := Random(30);
      WriteLn(Tab[I]: 4);
    end;

  iMax := 0;

  for I := 0 to 9 do
    if Tab[I] > iMax then
      iMax := Tab[I];

  Write(#10'Max = ', iMax);
  ReadLn;
end.

@ Ubiegłeś mnie...

0

Hehe, nie o to mi do końca chodzi. Tutaj jest przykład funkcji rekurencyjnej Fibonacciego:

var liczba: integer;
 
function fib(n:integer):integer;
begin
  if (n=1) or (n=0) then
    fib:=n
  else
    if n>1 then
      fib:=fib(n-1)+fib(n-2);
end;
 
begin
  writeln('Podaj n: ');
  readln(liczba);
  writeln('Wynik: ', fib(liczba));
end.

Jak widać funkcja sama w sobie odnosi się do siebie i nadaje sobie jakąś wartość. Poniżej daje wam program który działa i jest napisany rekurencyjnie z tą maksymalną wartością z tabeli

var liczba: integer;
  var a,j:integer;
     tab:array[1..10]of integer;

function max(i:integer):integer;

BEGIN

     if j<tab[i] then  begin
     j:=tab[i];
     end;

     i:=i-1;

      if i>=1 then max(i);
END;

BEGIN
clrscr;
      randomize;
     for a:=1 to 10 do begin
        tab[a]:=random(30);
     end;
     for a:=1 to 10 do begin
        write(tab[a]:4);
     end;

    j:=1;

    max(10);

    writeln;
    writeln('Najwieksza liczba to ',j);

    readln;

END.

Moim celem było "połączyć" te dwa programy tzn. wyeliminować zmienną j, tak aby funkcja którą definiuje się jako liczbę (w tym wypadku integer) przejęła końcowy wynik.

0

Nie wiem po co takie kombinacje i utrudnianie sobie, ale rob jak chcesz. Na pewno kod z Twojego pierwszego posta w funkcji max był nieprawidłowy, chocby dlatego, że porównywałeś funkcję bez podania dla niej parametru. A takiej funkcji jak Max nie trzeba by było robić rekurencynie, tylko przyjąć jako parametr wejściowy tabliće integerów, a w niej zrobić taką pętlę tylko od Low do High jak pokazałem w swoim kodzie przed podaniem wyniku zmiennej Max, tylko jeżeli używasz FPC bez odpowiednich dyrektyw kompilatora to wynik funkcji nastepuję po podaniu jej nazwy przez :=, a jeżeli używasz Delphi lub FPC z odpowiednią dyrektywą (na przykład {$MODE DELPHI}) podajesz słowo Result przed :=.

1

Kolega prawdopodobnie dostał zadanie, w którym musi nauczyć się operowania na rekurencji, w dodatku na zbyt banalnym zagadnieniu, jakim jest pobieranie maskimum... Owszem, można na pewno to zrobić na rekurencji, ale większego sensu to nie ma; dobrze @olesio napisał, że nie ma potrzeby utrudniać sobie życia, jeśli w grę wchodzi proste zagadnienie;

Co do samych funkcji to mnie osobiście strasznie denerwuje zwracanie wartości przez funkcję poprzez przypisanie konkretnej wartości do identyfikatora funkcji... Cieszę się niezmiernie, że twórcy języka wprowadzili zmienną Result pozostawiając przestarzałe nawyki z pascal'a; Bo ten algorytm:

var liczba: integer;
 
function fib(n:integer):integer;
begin
  if (n=1) or (n=0) then
    fib:=n
  else
    if n>1 then
      fib:=fib(n-1)+fib(n-2);
end;
 
begin
  writeln('Podaj n: ');
  readln(liczba);
  writeln('Wynik: ', fib(liczba));
end.

może okazać się mylący, gdyż ten:

  function Fib(N: Integer): Integer;
  begin
    if N >= 0 then
      case N of
        0 .. 1: Result := N;
      else
        Result := Fib(N - 1) + Fib(N - 2);
      end;
  end;

var
  Liczba: Integer;
begin
  WriteLn('Podaj n: ');
  ReadLn(Liczba);
  WriteLn('Wynik: ', Fib(Liczba));
  ReadLn;
end.

jest bardziej czytelny, bo widać dokładnie miejsca, w których podaje się rezultat, a gdzie jest wywoływana rekurencja;

0
Furious Programming napisał(a)

Cieszę się niezmiernie, że twórcy języka wprowadzili zmienną Result pozostawiając przestarzałe nawyki z pascal'a
Twórcy pascala nie wprowadzili Result bo w tym języku ono nie występuje. Nie odróżniasz "czystego" pascal'a od jego dialektów.

0

nie ma sensu robienia funkcji max rekurencyjnie ale jeśli się upierasz to powinno to wyglądać mniej/więcej tak (nie umiem pascala ani nie mam żadnego kompilatora pod ręką więc potraktuj to jako pseudokod)

PROGRAM prog;
uses crt;

   var a:integer;
       var tab:array[1..10] of integer;

function max(m, i: integer):integer;
begin
    if tab[i] > m then
        m := tab[i];

    if i >= 10 then
        max := m
    else
        max := max(m, i + 1);
end;

BEGIN
clrscr;
      randomize;
     for a:=1 to 10 do begin
        tab[a]:=random(30);
     end;

     for a:=1 to 10 do begin
        write(tab[a]:4);
     end;

    writeln;
    writeln;
    writeln('Najwieksza liczba to ',max(0, 1)); { 0 to minimalna wartość którą zwróci funkcja }

    readln;

END.

w skrócie - nie możesz odczytywać "max" tylko do niego zapisywać
odczytując wcale nie dostajesz tego co tam wcześniej zapisałeś (w poprzednim wywołaniu) tylko prawdopodobnie miejsce w pamięci do funkcji / parametrów na stosie lub czegoś w tym rodzaju (to by tłumaczyło malejącą wartość którą dostawałeś z każdym wywołaniem, ale nie wiem co to naprawdę bo nie znam tego języka) - w każdym razie po prostu tego nie rób

ale podejrzewam że po prostu nie wiesz co robisz a tak naprawdę chcesz zrobić zwykłą funkcję:

function max():integer;
var m: integer;
begin
    m := tab[1];
    for i := 2 to 10 do
        if tab[i] > m then m := tab[i];
    max := m;
end;

BEGIN
clrscr;
      randomize;
     for a:=1 to 10 do begin
        tab[a]:=random(30);
     end;

     for a:=1 to 10 do begin
        write(tab[a]:4);
     end;

    writeln;
    writeln;
    writeln('Najwieksza liczba to ',max());

    readln;

END.

przy czym przydałoby się przekazywać referencję do tablicy zamiast działać na zmiennych globalnych ale nie mam pojęcia jak to się robi w pascalu

2

Twórcy pascala nie wprowadzili Result bo w tym języku ono nie występuje.

http://pl.wikipedia.org/wiki/Petitio_principii

0
Azarien napisał(a)

Twórcy pascala nie wprowadzili Result bo w tym języku ono nie występuje.

http://pl.wikipedia.org/wiki/Petitio_principii

proszę czy taki odpis może wystarczyć do poparcia moich słów?

0

Już wszystko jasne, dziękuje wszystkim za pomoc. Po prostu nie rozumiałem, jak wywoływać odpowiednio funkcję w tym przypadku.

0

proszę czy taki odpis może wystarczyć do poparcia moich słów?

Czy ja podważam prawdziwość stwierdzenia, że w Pascalu (pierwotnym) nie ma Result? Ja wiem że nie ma.

Ale zdanie „Twórcy pascala nie wprowadzili Result bo w tym języku ono nie występuje.” jest bez sensu.
W Pascalu nie ma Result, bo jego twórca (Niklaus Wirth) albo w ogóle nie wpadł na taki pomysł, albo zdecydował by go nie wprowadzać.

0

Twórcy pascala nie wprowadzili Result bo w tym języku ono nie występuje. Nie odróżniasz "czystego" pascal'a od jego dialektów.

A masło jest maślane bo jest maślane.

To zależy co uznajesz za czystego pascala. Może TP 1.0? Albo jakiś archaiczny kompilator? No to wtedy pascal nie ma funkcji zapisu plików chociażby.
Prawda jest taka że współczesne kompilatory wspierają result, a mi się wydaje że 'czysty' pascal to dzisiaj jest to wszystko co ogarniają ważniejsze kompilatory, bo nie ma żadnego nowoczesnego dokumentu o pascalu.
Tak samo jest z C++, bo można powiedzieć że w 'czystym' C++ nie ma generyków, ale jednak jakimś dziwnym trafem wszystko w gcc opiera się na generykach.

Więc twoje tłumaczenie że to dialekty jest bez sensu, bo właściwie każdy kompilator ma swój dialekt, i nie sposób znaleźć kompilator który trzyma się (w większości niespisanych) zasad. Pascal to generalne określenie na tą rodzinę języków gdzie każdy z tych dialektów ma nieco inną specyfikację.

0

Prawda jest taka że współczesne kompilatory wspierają result, a mi się wydaje że 'czysty' pascal to dzisiaj jest to wszystko co ogarniają ważniejsze kompilatory, bo nie ma żadnego nowoczesnego dokumentu o pascalu..
przykładowo współczesny kompilator FPC wspiera result tylko po przestawieniu na odpowiedni tryb (ObjFPC lub Delphi mode). Gdyby result było integralne z językiem to byłoby one dostępne w każdym trybie działania kompilatora jak pozostałe zmienne wbudowane czy słowa kluczowe. Visual C++ też wspiera parę udziwnień ale czy to powód, żeby nazywać je zaraz częścią języka C++ (albo lepiej, bardziej do tej dyskusji pasowałoby - C).

Tak samo jest z C++, bo można powiedzieć że w 'czystym' C++ nie ma generyków, ale jednak jakimś dziwnym trafem wszystko w gcc opiera się na generykach.
o jakich piszesz generykach jakich nie wspiera C++?

Pascal to generalne określenie na tą rodzinę języków gdzie każdy z tych dialektów ma nieco inną specyfikację.

Dla mnie Pascal to język programowania, a nie rodzina języków - a te języki, które nazywasz "rodziną" to pochodne pascala. Nazywaj sobie to jak chcesz, tak jak kolega "Furious Programming", niejednokrotnie używa się zwyczajowego określenia języka - ale jeśli ktoś czyni taki skrót myślowy to niech przynajmniej zdaje sobie sprawę z tego jak to wygląda. Pascal i Object Pascal to dla ciebie to samo? To jak by powiedzieć, że C i C++ to te same języki :]

Nie wydaje mi się, żebym popełnił swoją pierwszą wypowiedzią wielkie przestępstwo. Jedyne co mam sobie do zarzucenia w związku z pierwszym postem to fakt, że z cytowanego fragmentu wypowiedzi "Furious Programming'a" nie wynika wcale, to co założyłem, że wynika ( ;) ). W zasadzie pośpieszyłem się z komentarzem nie wczytując się za bardzo z sens jego słów.

0

dla mnie Pascal to sposób na zapis, papcio wymyślił to na tyle fajnie, że nawet opłacało się z tego skorzystać. kiedyś był hisoft, później turbo, później...
kiedyś bym...
później formalizm zniechęcił mnie i polubiłem kurka wodna naturalne C
K&+R dobrze bawili się, szli na łatwiznę ale i były z nich kute na cztery łapy gapy

napiszmy może RIP

0

Jeśli ktoś dalej chce dyskutować na ten temat - proszę jeszcze raz przeczytać winne zdanie:

Cieszę się niezmiernie, że twórcy języka wprowadzili zmienną Result pozostawiając przestarzałe nawyki z pascal'a;

Jak widać w nim nie jest napisane, że twórcy pascal'a wprowadzili zmienną Result, więc Ci, którzy piszą o tym w poprzednich postach nie przeczytali mojego postu uważnie;

blee napisał(a)

Dla mnie Pascal to język programowania, a nie rodzina języków - a te języki, które nazywasz "rodziną" to pochodne pascala. Nazywaj sobie to jak chcesz, tak jak kolega "Furious Programming", niejednokrotnie używa się zwyczajowego określenia języka - ale jeśli ktoś czyni taki skrót myślowy to niech przynajmniej zdaje sobie sprawę z tego jak to wygląda. Pascal i Object Pascal to dla ciebie to samo? To jak by powiedzieć, że C i C++ to te same języki

Tu masz rację;


Skończmy już gawendę na ten temat, bo zrobił się offtopic;

1 użytkowników online, w tym zalogowanych: 0, gości: 1