MC102
Algoritmos e Programação de Computadores
Parte XVII



Norton Trevisan Roman




FUNÇÕES

Lembra como fazíamos para retirar um valor de um procedimento?

  PROGRAM P;
  VAR c,a,b:integer;

  PROCEDURE Soma(a,b : integer; VAR resp : integer);
  BEGIN
    resp := a+b
  END;

  BEGIN
    a := 2;
    b := 4;
    Soma(a,b,c);
    writeln(c)   {escreve 5}
  END.
	

Será que não há um modo mais direto? Vamos ver, como tiramos, em Pascal, a raiz de um número y?

  x := Sqrt(y);
	

E o módulo de y?

  x := Abs(y);
	

Não seria interessante fazer c := Soma(a,b)? Como posso vazer isso? Fazendo uma função, cuja forma geral é:

  FUNCTION nome(parâmetros) : tipo de retorno;
  VAR variáveis locais;
  BEGIN
    corpo da função, com cálculos etc;
    nome := resposta  {carrego a resposta a ser devolvida pela função}
  END;
	

Vamos fazer um paralelo entre função e procedimento (ambos fazem a mesma coisa):

  VAR x;

  PROCEDURE soma(a,b:integer; VAR r:integer);
  BEGIN
    r := a+b
  END;

  BEGIN
    soma(2,3,x);
    writeln(x) {escreve 5}
  END;
	
  FUNCTION soma(a,b:integer) : integer;
  BEGIN
    soma := a+b
  END;

  BEGIN
    x := soma(2,3);
    writeln(x) {escreve 5}
  END.
	

Vejamos as diferenças:

Vamos ver um exemplo de erro:
  {retorna a soma de 1 até "limite"}
  FUNCTION soma(lim:integer) : integer;
  VAR n : integer;
  BEGIN
    soma := 0;
    FOR n:=1 TO lim DO soma := soma + n {erro em alguns compiladores!}
  END;
	

Novamente: esse erro só existe em alguns compiladores. No free pascal, por exemplo, esse programa está correto e roda normalmente sem erro.

Ou seja: antes de usar isso, verifique se o teu compilador aceita! Se aceitar, use à vontade. Caso seu compilador não aceite, você pode substituir a função acima por essa:

  {retorna a soma de 1 até "limite"}
  FUNCTION soma(lim:integer) : integer;
  VAR n,t : integer;
  BEGIN
    t := 0;
    FOR n:=1 TO lim DO t := t + n;
    soma := t
  END;
	

Como foi mencionado antes, não podemos chamar uma função como procedimento. Ela devolve um valor que deve ser usado, pois a função representa esse valor. Assim, posso até passá-la como parâmetro:

  BEGIN
    writeln('2 + 3 = ', soma(2,3)) {escreve "2 + 3 = 5"}
  END.
	

ou:

  BEGIN
    a := soma(soma(2,3),6);
    writeln(a) {escreve "11"}
  END.
	

Com relação aos parâmetros, funções são como procedimentos. Sua grande utilidade é podermos usá-las em expressões:

  CONST PI = 3.1416;
  VAR raio, lado : real;
      vol_esfera : real;
      vol_cubo   : real;
  FUNCTION cubo(n:real):real;
  BEGIN
    cubo := n*n*n
  END;

  BEGIN
    raio := 3;
    lado := 2;

    vol_esfera := 4*PI*Cubo(raio)/3;
    vol_cubo := Cubo(lado)
  END.
	

Então, como funciona a FUNCTION?

Mas, e se quisermos devolver dois valores? Por exemplo, suponha que queremos uma função que calcule a média de alguém e me diga se este passou. Como faríamos?
  PROGRAM P;

  VAR media : real;

  {n1, n2 e n3 são as notas. A função retorna true se ele passou
   e false se não, carregando media com a média do sujeito}
  FUNCTION Passou(n1,n2,n3:real; VAR media:real):boolean;
  BEGIN
    media := (n1 + n2 + n3) /3;
    Passou := media >= 5 {true se media >=5, false se não}
  END;

  BEGIN
    IF Passou(5,3,7,media) THEN writeln('Passou com média ',media)
    ELSE writeln('Reprovou com média ',media)
  END.
	

Nesse programa, a média é calculada e armazenada em "media" e, se esta for ≥ 5, a função retorna true, senão retorna false.

Note que antes do retorno da função, que se dá somente no END do corpo desta, ou seja, quando ela termina, "media" já havia sido modificada.

Talvez, para entender melhor, devamos notar a similaridade entre uma função matemática e uma FUNCTION. Como dizemos que y é uma função de x? Fazendo:

  y = f(x)
	

Ou seja, a cada valor de x, corresponde um y dado por essa relação. Como, então, representamos essa mesma função em Pascal?

  y := f(x);
	

Parecidíssimo, não? Aqui, dado um valor de x, y é abastecido com o valor dado por f(x). Notou a semelhança do modo de pensar? Não é à toa, FUNCTION foi projetada para ter essa semelhança.

Mas será que o conceito de função nos é tão novo? Não, já usamos funções anteriormente, vejamos alguns exemplos:

  VAR ch : char;
      n  : integer;
      m  : real;

  BEGIN
    ch := readkey;
    n := ord(ch);
    m := Sqrt(n)
  END.
	

essas funções correspondem às seguinte definições:

  FUNCTION readkey : char;
  BEGIN
    ...
  END;

  FUNCTION ord(c : char) : integer;
  BEGIN
    ...
  END;

  FUNCTION sqrt(x:real) : real;
  BEGIN
    ...
  END;
	

e já vêm pré-definidas com o Pascal.

Em suma:
Use procedimentos quando tiver um pedaço de código que se repete (recebendo ou não parâmetros), e use funções quando esse pedaço de código precisar retornar um valor.

Obs: Com o que sabemos, FUNCTION só retorna valores simples, com nomes, como real, integer, boolean, char etc. Para saber como retornar valores mais complexos, verifique as próximas notas.





‹— Parte XVIPágina da disciplinaParte XVIII —›