Jump to content
thoga31

Erro em passagem por valor (function)

Recommended Posts

thoga31

Olá pessoal.

Normalmente ando aqui a tirar dúvidas neste quadro. Mas, desta vez, surgiu-me uma situação à qual não consigo dar a volta.

Decidi passar um array por valor para uma função. Contudo, o programa foi-me abaixo.

// a função:
function maior(lista : array of integer) : integer;

// chamar a função:
maior([1..n]);

Decidi então testar a função mais a fundo, e descobri que o erro ocorre ainda na passagem, no programa principal, e não na função. O erro é o famoso Access Violation.

O que se pode estar a passar? Já experimentei substituir o n (um Integer) por uma constante, como 10 ou 50, e o erro mantém-se.

Cumprimentos,

thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
nunopicado

Oi Thoga...

Experimenta o seguinte:

Na rotina onde chamas a função, declara um array, mete-lhe os valores, e só por fim é que chamas a função, passando o array por parametro à função.

Exemplo:

function Maior(lista:array of integer):integer;
var
   i:integer;
begin
     Result:=-65535;   // Para o valor inicial do resultado ser o mínimo possível, neste caso do integer tradicional
     for i := 1 to 5 do
         if lista[i]>Result then Result:=lista[i];
end;

procedure MostraMaior;
var
   ListaNumeros:array[1..5] of integer;
   i:integer;
begin
   for i:=1 to 5 do                 // Treta de código para
      ListaNumeros[i]:=i*i-(-i);   // preencher o array com qualquer coisa heheheheh
   Writeln('O maior numero da lista é ',maior(ListaNumeros),'.');   // Chamada da função
end;

begin
   ClrScr;
   MostraMaior;
   Readln;
end.

Dá para o que queres?


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
thoga31

Pois. Dessa forma funciona. Mas eu queria mesmo era evitar a pré-criação de um array. Ou seja, o utilizador dizia a dimensão N e passava por parâmetro.

Isto é, explicando bem:

Em vez de ter um primeiro array do tipo lista[1..100], por exemplo, queria que o array fosse como que criado na altura em que era necessário, tendo a dimensão [1..N]. Digamos que era uma maneira de poupar recursos de memória. O array era criado para o fim, e depois "desaparecia".

Não sei se me fiz entender. No teu caso, criaste um array[1..5], e eu quero que seja o utilizador a decidir a dimensão.

Ok, podia criar um array[1..100] e pedir um limite de inserção de valores de 1 a 100, mas isto implicaria sempre várias coisas, entre elas ter de reiniciar o array todo para nova utilização, ter 100 elementos "preparados" em memória durante o programa todo, etc. E se o utilizador precisa mais do que 100? Meto 1000. Mas e se só precisa de 10? Tenho 90 elementos "a encher sacos de batatas".

Por isso é que eu experimentei passar directamente daquela forma.

Obrigado pela dica. ;)

Cumprimentos.


Knowledge is free!

Share this post


Link to post
Share on other sites
nunopicado

Compreendo, eu também prefiro os arrays dinamicos.

Mas sei que há compiladores que não os conseguem fazer. Estás a usar qual?


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
thoga31

Compreendo, eu também prefiro os arrays dinamicos.

Mas sei que há compiladores que não os conseguem fazer. Estás a usar qual?

Utilizo o Dev-Pascal 1.9.2 recorrendo ao compilador Free Pascal.

Vou experimentar com recurso ao GNU Pascal.


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

O freepascal suporta arrays dinâmicos.

Quanto ao código que escreveste, eu nem sabia que podias passar algo como 1..n a uma função. Isso não é uma array (pelo menos em freepascal e no Delphi 7, que eu usava), mas sim uma definição de um intervalo.

De qualquer modo, numa situação real nunca passarias isso como parâmetro a função nenhuma, mas sim uma array pré-criada, fosse ela fixa ou dinâmica.

program arraytest;

function maior(list : array of integer): integer;
var
  i: integer;
begin
  maior := list[0];
  for i := 0 to length(list) - 1 do
    if list[i] > maior then
      maior := list[i];
end;

var
  a: array of integer;
  n, i: integer;
begin
  write('Quantos elementos? ');
  readln(n);
  setlength(a, n);
  for i := 1 to n do
  begin
    write('#', i, ': ');
    readln(a[i - 1]);
  end;
  writeln('Maior elemento: ', maior(a));
end.

$ ./arraytest
Quantos elementos? 3
#1: -7
#2: 2
#3: 42
Maior elemento: 42

Nota: se estiveres a usar algo diferente de freepascal, substitui todas as ocorrências de maior no código da função maior por result.

Share this post


Link to post
Share on other sites
thoga31

Não fazia ideia dos arrays dinâmicos. Muito obrigado, pedro-kun. O meu problema está-se a resolver, por fim. :thumbsup:


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

Arrays dinâmicos, apontadores (pointers/pointeiros, whatever), e Classes/objectos são aquelas coisas que pouca gente fala mas que são muito úteis em pascal.

Estou a ver se escrevo qualquer coisita sobre um desses 3 temas :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.