Funções e Procedimentos - Parte 1

Tipos de dados em algoritmos

Rotinas

 

Pessoal, estamos chegando ao fim da série de artigos sobre ALGORITMOS. Ufa! Falamos sobre muitas coisas né? Agora, nesta reta final, vou falar sobre Rotinas, Bibliotecas e Arquivos. A intenção da minha série sobre Algoritmos foi introduzir os recursos e técnicas de programação que são comuns a todas as linguagens de programação. Infelizmente, muitos tópicos só poderiam abordar se estivesse falando especificamente a respeito de uma Linguagem de Programação.

 

Cada linguagem tem suas peculiaridades, apesar de implementarem o básico. Quem sabe mais para a frente eu não retorno falando sobre Java? (Minha linguagem de programação favorita no momento!). O artigo de hoje é sobre ROTINAS, conhecida como FUNÇÃO ou PROCEDIMENTO em Pascal, MÉTODO em Java e FUNÇÃO em C/C++, e por aí vai. Pra que o artigo não fique imenso, vou dividi-lo em duas partes, hoje introduzo o assunto e mostro um tipo de rotina e, no próximo artigo, mostro os outros tipos, tudo bem? Vamos começar então.

 

 

Objetivo

 

Uma Rotina tem como objetivo realizar uma tarefa específica, realmente muito específica. Por exemplo, somar dois números, solicitar dados para um usuário, etc. Vamos desenvolver uma calculadora em Pascal que demonstrará a construção de um programa completo usando ROTINAS e, assim, poderei mostrar a vocês os diferentes tipos de rotinas que podemos implementar.

 

 

Escopo

 

Vamos ver como são divididos os programas que fazemos em pascal? Essa divisão ajudará a entender o ESCOPO, isto é, o contexto de execução de cada parte do programa e a comunicação de cada um deles com outras partes do programa. Observe a Figura 1.

 

Primeiro, vamos definir o significado das palavras Global e Local no contexto do nosso texto:

  • Global:  recursos que podem ser usados em TODO o seu arquivo de código fonte. Eles são utilizados conforme a sua necessidade e existem durante todo o tempo de execução do seu programa;
  • Local: recursos que só podem ser usados em uma parte ESPECÍFICA do seu arquivo de código fonte. Eles são utilizados apenas no bloco em que foram declarados e existem apenas durante o tempo de execução daquele bloco em particular.

 

Agora que isso ficou claro, vamos ver as partes do programa que estão definidas na Figura 1 e entender melhor como elas conversam entre si:

 

Escopo
Figura 1: Escopo

 

Nome do Programa

 

Essa área está identificada na Figura 1 com a cor amarela. ESCOPO GLOBAL. O nome do programa identifica o arquivo e o tipo de arquivo. Se fosse um arquivo de biblioteca, então colocaríamos UNIT ao invés de PROGRAM. Assim, o seu arquivo é identificado com uma UNIT ou um PROGRAM com o uso dessa palavra chave. Claramente isso é usado pelo compilador.

 

Bibliotecas

 

Essa área está identificada na Figura 1 com a cor azul. ESCOPO GLOBAL. As bibliotecas que você declara aqui são aquelas definidas pelo Pascal, ou por você, para serem utilizadas em seu programa, como um todo, portanto elas são de uso GLOBAL. Bibliotecas são arquivos que normalmente contêm constantes, funções e procedimentos, permitindo permitindo que você as use em seu arquivo de programa. Exemplo: quando usamos writeln() e readln(), na verdade estamos chamando as funções referentes à leitura e escrita que foram definidas (codificadas) na biblioteca específica CRT.

 

Assim, o seu arquivo de programa CHAMA uma Function/Procedure que está em outro arquivo, um arquivo de biblioteca, e a utiliza quantas vezes forem necessárias. Entretanto, se você esquecer de declarar a biblioteca (UNIT) na área de declaração de bibliotecas, usando a palavra-chave USES, então não será possível usar os recursos que foram codificados na biblioteca. É pela declaração da biblioteca que o arquivo de programa e o arquivo de biblioteca podem “conversar”. Para ilustrar, observe a Figura 2:

 

Organização de uma Unit
Figura 2: Unit

 

Ela apresenta uma UNIT com duas funções, e ambas são usadas no arquivo de código fonte, declarando a biblioteca em USES MINMAX, e depois chamando as funções dentro do programa principal.

 

Variáveis

 

Essa área está identificada na Figura 1 com a cor verde. ESCOPO GLOBAL. Aqui declaramos as variáveis GLOBAIS, isto é, as variáveis declaradas nesse ESCOPO são usadas em TODO o programa e, por isso, você deve tomar cuidado ao utilizá-las nas funções/procedimentos, pois pode receber ou passar valores que não deseja para outras partes do programa, trabalhando assim com valores errados. Assim, é sempre bom passar parâmetros para as funções/procedimentos, garantindo o uso dos valores corretos entre as partes diferentes do programa.

 

Funções e Procedimentos

 

Essa área está identificada na Figura 1 com a cor laranja. ESCOPO GLOBAL. Funções e Procedimentos podem ter, ou não ter, parâmetros em sua assinatura, assim como declaração de novas variáveis dentro da assinatura e também dentro do corpo da função/procedimento.

 

As variáveis declaradas dentro das funções/procedimentos, ou na assinatura, são variáveis LOCAIS, portanto têm ESCOPO LOCAL. Elas receberão os valores que você estiver passando para elas na chamada, garantindo assim a integridade dos valores e, após o término da execução da função/procedimento, elas são destruídas. Quem pode chamar uma Função/Procedimento? Outra Função/Procedimento ou o programa.

 

As Funções sempre retornam algum valor para quem chamou, diferente dos Procedimentos, que não retornam valor algum. Podemos pensar que um Procedimento é uma função do tipo VOID. Não se preocupem, mostrarei detalhes sobre como isso funciona. Portanto, em um arquivo de programa, funções/procedimentos conversam com o programa principal, e vice-versa.

 

Programa Principal

 

Depois que você estiver familiarizado com UNITS, Funções/Procedimentos, vai perceber que o programa principal só servirá para chamar as partes do programa que você precisa. O programa principal tem acesso às variáveis globais e também às funções e procedimentos, então, tudo o que for global, está disponível para o programa principal. O que é LOCAL, não tem acesso permitido pelo programa principal.

 

 

Rotina sem passagem de parâmetros e sem retorno

 

Você pode criar rotinas sem parâmetros e sem retorno, isso significa que elas não receberão parâmetros de quem a está chamando, assim como não retornará um valor de um tipo especifico para quem está chamando. Vejamos a Listagem 1.

 

Listagem 1:

 

Nesse programa de exemplo, o programa principal chama o procedimento MENU() e é só isso que o programa principal faz. Todo o restante está nos procedimentos. Temos um procedimento para fazer a leitura do teclado (solicita dados ao usuário), outros para cada um dos cálculos matemáticos, outro para chamar o MENU() e mostrar as opções para o usuário selecionar a que ele deseja. Observem como o programa fica bem organizado dessa forma.

 

Como são procedures as chamadas nas opções dentro do switch/case também são simples, não há passagem de parâmetros, nem tratamento de variáveis ou retornos das chamadas, todo o trabalho foi distribuído nas procedures. Se vocês observarem bem, a verificação de n2=0, para evitar o erro de divisão de por zero, também pode ser transformado em uma procedure/function, diminuindo assim a quantidade de código REPETIDO no arquivo de programa.

 

Vejam, pensar uma rotina é uma tarefa importante. É preciso identificar o que se repete com frequência no seu código, perceber que aquilo ali pode se transformar numa rotina e, assim, ao invés de ficar codificando a mesma coisa sempre, você abstrai isso, otimizando o seu código. Melhor ainda se você transformar isso em uma UNIT, permitindo que suas rotinas possam ser usadas em vários arquivos de programas diferentes. Isso é reutilização de código, uma postura muito bem-vinda, e aceita, por desenvolvedores e projetistas de software. Treine isto!

 

Vamos ver uma algumas figuras que ilustram essa sequência de chamadas e de retornos dos procedimentos envolvidos em uma soma.

 

Chamada de Menu
Figura 3: Chamada de Menu

 

 

Chamada de Soma
Figura 4: Chamada de Soma
Chamada ao procedimento leitura
Figura 5: Chamada ao procedimento leitura
Pilha de Execução
Figura 6: Pilha de Execução

 

As Figuras 3, 4 e 5 ilustram as chamadas das procedures, de uma para outra até chegar a última necessária, formando uma espécie de cascata. A Figura 6 apresenta a Pilha de Execução, que é uma forma de representar a sequência de chamadas das rotinas e seus retornos. Entretanto, a verdade é que os sistemas computacionais utilizam uma estrutura de PILHA DINÂMICA para controlar as chamadas e retorno, armazenando seus valores atuais em memória e desalocando esses espaços quando não são mais necessários.

 

Cada chamada é empilhada com seus valores atuais, e cada retorno é desempilhado, retornando os valores resultantes para quem chamou, conforme mostram as setas na Figura. Uma pilha é uma estrutura de dados e nós a estudaremos na série sobre Estruturas de Dados.

 

 

Conclusão

 

Talvez isto ainda não esteja muito claro pra você agora, mas peço paciência. No próximo artigo mostrarei as outras formas de uso de Rotinas, ilustrando com imagens e códigos fontes. Com o tempo, praticando, você compreenderá tudo isso. Até a próxima.

Outros artigos da série

<< Comando de Controle Do-WhileFunções e Procedimentos - Parte 2 >>

Deixe um comentário

Seja o Primeiro a Comentar!

Notificar
avatar
 
wpDiscuz