Funções e Procedimentos

Padrão

Estou ficando preocupado. Praticamente todos os meus posts começam com “Olá pessoal!“. Preciso urgentemente de uma nova maneira de começar meus posts e saudar meus leitores. Mas, enfim, até o próximo post eu penso em alguma coisa. Quem sabe alguma gíria, algum termo informático… ah, sei lá. Aguardemos os próximos capítulos.

Bom, hoje vamos tratar de um assunto de extrema importância na programação estruturada: as Funções e Procedimentos. Sem eles, a programação seria praticamente impossível de ser realizada à medida que os programas crescessem em tamanho. Além disso, seria praticamente impossível trabalhar em equipe (entenderemos isso já já), e a reutilização de código também seria inimaginável, ou seja, toda vez que escrevêssemos nossos programas, teríamos que fazer tudo a partir do zero. A própria linguagem não teria suas funções e procedimentos, e teríamos que fazer toda a manipulação de teclado, vídeo, E/S, tudo a partir do zero. Entenderam a importância? Veremos aqui como constitui-se uma função/procedimento, as diferenças de um para o outro, o que é um argumento e um parâmetro, diferenças entre um e outro, o que é um retorno… ufa! Como deu para perceber, o post tá bem recheado! Então vamos que vamos!

Para começarmos a falar sobre procedimentos e funções, vamos dar uma olhada no conceito da máquina de von Neumann, onde os sistemas computacionais são constituídos de:

ENTRADA -> PROCESSAMENTO -> SAÍDA

Através desse conceito, podemos generalizar que todo programa recebe uma entrada de Dados, realiza seus cálculos no processamento e, como saída, temos a Informação que é o dado processado. Da mesma forma, os procedimentos e funções recebem dados de entrada, processam-os e retornam algo para quem os chamou. Podemos começar diferenciando um procedimento de uma função pela maneira como é feito o retorno. Na Função, o valor de retorno é Explícito, enquanto que no Procedimento, o retorno é realizado de maneira Implícita. Veremos isso na prática mais adiante. Da mesma forma que temos a saída na forma do retorno, também temos a saída na forma dos parâmetros ou argumentos de nossa função ou procedimento. Mas qual a diferença entre um Parâmetro e um Argumento? De maneira simplificada, podemos dizer que uma função (vou utilizar apenas o termo função para designar função e procedimento, apenas para poupar digitação) recebe de quem a chamou, em seus Parâmetros, os dados a serem processados. Já quando chamamos uma função, passamos Argumentos para que ela execute o seu processamento. Dessa forma, os Parâmetros são os dados aguardados pela função, enquanto que os Argumentos são os dados que passamos à função. Pode parecer um pouco confuso agora, mas pretendo espairecer melhor essas ideias quando discutirmos a parte prática da coisa. Então, para fechar essa parte mais “conceitual”, podemos dizer que as funções são pequenos programas. Ou seja, a partir de agora, podemos “quebrar” o nosso programa em partes menores. Dessa forma, podemos, dentre outras coisas, reutilizar funções já escritas em programas novos, dividir trabalho entre uma equipe, onde cada um escreve um trecho do código, ou seja, cada um escreve suas funções e depois junta-se em um único programa. Legal, hein!

Antes de começarmos a ver as Funções e Procedimentos na prática, precisamos ter uma noção sobre Variáveis Globais e Variáveis Locais.

O conceito de Variáveis, já foi explorado em um post anterior (variável é um célula de memória que armazena um valor, toda variável precisa de um tipo, etc). Uma Variável Global é uma variável que pode ser acessada, alterada, enfim, ela pode ser vista por todo o programa. Como assim? As variáveis são todas globais então? Bom, nos programas que fizemos até agora, sim. A partir de agora, veremos que os procedimentos e funções também possuem suas próprias variáveis, que só são conhecidas dentro de seu escopo (dentro do procedimento ou função). Ou seja, uma Variável Local é uma variável que só é conhecida por um trecho do programa, não podendo ser acessada fora dele. Por exemplo, eu declarei uma variável chamada X dentro de uma função. Se eu mencioná-la fora da função onde foi declarada, o compilador em questão irá acusar um erro, dizendo que a variável não foi declarada. Com isso, você pode perceber que podemos ter variáveis de mesmo nome em nosso programa, porém cada uma dentro de seu escopo, sem nenhuma ligação uma com a outra.

Bom, já falamos bastante da parte “teórica” de funções e procedimentos. Então vamos ver alguns exemplos de como fazê-los, tanto nos algoritmos quanto na linguagem Pascal.

Primeiramente, vamos criar um programa que lê dois números e os somam. Para isso iremos criar uma função chamada somar, que receberá dois números inteiros como parâmetros e devolverá também um inteiro contendo o resultado da soma.

Algoritmo Somar_com_Funcoes

[Declaração de Variáveis]
   valor1, valor2, resultado : inteiro

Função somar(n1, n2 : inteiro) : inteiro
[Início]

[Declaração de Variáveis Locais]
   resultado : inteiro

[Processamento]
   resultado ← n1 + n2
   retorne(resultado)

[Fim]

[Processamento Principal - Início]
   escreva("Digite o primeiro membro da soma: ")
   leia(valor1)
   escreva("Digite o segundo valor da soma: ")
   leia(valor2)
   resultado ← somar(valor1, valor2)
   escreva("O resultado é ", resultado)
[Fim]

 

program Somar_com_Funcoes;

uses
   crt;

var
   valor1, valor2, resultado : integer;

function somar(n1, n2 : integer) : integer;
var
   resultado : integer;
// Logo a seguir vou explicar algumas particularidades da linguagem Pascal

begin
   resultado := n1 + n2;
   somar := resultado;
end;

begin
   write('Digite o primeiro membro da soma: ');
   readln(valor1);
   write('Digite o segundo membro da soma: ');
   readln(valor2);
   resultado := somar(valor1, valor2);
   writeln('O resultado é ', resultado);
   readkey;
end.

Vimos acima um exemplo bastante simples, onde declaramos uma função chamada somar que recebe dois valores inteiros (n1 e n2) e retorna um valor inteiro, contendo a soma dos dois valores passados como argumento. Você pode pensar: “que coisa inútil… é muito mais fácil usar o operador + e pronto”. Calma, calma… esse foi só um exemplo. Obviamente não iremos criar funções que já existem. As funções servem pra que possamos modularizar o código, dividindo tarefas e deixando o código mais legível. Por exemplo, podemos criar uma função que calcule o imposto de renda, que calcule as raízes de uma equação de 2º grau, dentre outros. Com isso, se tivermos outro programa que também necessite de tais cálculos, podemos reutilizar o código!

Podemos perceber em nosso código que declaramos algumas variáveis globais e locais. Nesse caso, declaramos as variáveis globais: valor1, valor2 e resultado, enquanto que declaramos as variáveis locais: n1, n2 e resultado. Epa! Surgiram duas dúvidas agora! Primeiro: n1 e n2 são parâmetros e não variáveis locais, certo? Errado. Os parâmetros que declaramos em nossas funções e procedimentos também são variáveis locais, apesar de não terem sido declarados na área de variáveis locais. A segunda dúvida é: você declarou duas variáveis de nome ‘resultado’! Por que o compilador não acusou erro? Na verdade eu só percebi isso agora, mas serviu pra explicar um detalhe da linguagem Pascal: quando temos duas variáveis de mesmo nome, sendo uma global e uma local, o programa sempre vai levar em conta a variável local. Ele acusaria erro se declarássemos suas variáveis de mesmo nome dentro de um mesmo escopo.

Bom, eu comentei o código ali em cima, dizendo que iria explicar algumas particularidades da linguagem Pascal. No algoritmo, quando vamos retornar o valor que a função calculou, utilizamos simplesmente retorne(<valor>). Já na linguagem Pascal, fazemos isso de uma modo diferente. Atribuímos o valor a uma variável com o mesmo nome da função. Essa variável não precisa ser declarada, pois é criada automaticamente para representar a função. No nosso exemplo, atribuímos o que queremos retornar à variável somar.

Pra encerrar, vou mostrar um exemplo do uso de Procedimentos, também para somar dois valor. Vocês perceberão que eles funcionam exatamente da mesma maneira, porém, sem o valor de retorno:

Algoritmo Somar_com_Procedimentos

[Declaração de Variáveis]
   valor1, valor2, resultado : inteiro

Procedimento somar(n1, n2 : inteiro)
[Início]

[Declaração de Variáveis Locais]
   resultado : inteiro

[Processamento]
   resultado ← n1 + n2
   escreva("O resultado é ", resultado)

[Fim]

[Processamento Principal - Início]
   escreva("Digite o primeiro membro da soma: ")
   leia(valor1)
   escreva("Digite o segundo valor da soma: ")
   leia(valor2)
   somar(valor1, valor2)
[Fim]

 

program Somar_com_Procedimentos;

uses
   crt;

var
   valor1, valor2, resultado : integer;

procedure somar(n1, n2 : integer);
var
   resultado : integer

begin
   resultado := n1 + n2;
   writeln('O resultado é ', resultado);
end;

begin
   write('Digite o primeiro membro da soma: ');
   readln(valor1);
   write('Digite o segundo membro da soma: ');
   readln(valor2);
   somar(valor1, valor2);
   readkey;
end.

Perceberam como é simples? E acaba auxiliando e muito no desenvolvimento de aplicações. Quem sabe eu ainda reescrevo o nosso jogo da velha em Pascal, recodificando-o de forma modularizada? Vou pensar nisso…

Ah, e antes de encerrar, vale lembrar que uma função ou procedimento pode, também, não ter nenhum parâmetro. Para isso, é só deixar os parênteses vazios ou até omiti-los.

Post grande, de certa forma cansativo, mas de um tema bastante interessante! No próximo post vamos começar a nos aventurar por um outro mundo: A Linguagem C! Ela vai servir pra nos mostrar que, tendo um algoritmo bem feito, podemos implementá-lo facilmente, independente da linguagem.

Abraço, pessoal e bons estudos!

Deixe uma resposta