Olá, caro(a) aluno(a)! Percorremos um longo caminho até aqui. Nas primeira aulas, descobrimos como um algoritmo deveria ser estruturado e como ele é interpretado pelo computador. Agora, já trabalhamos com conceitos complexos como vetores e matrizes.
Nesta lição, estudaremos sub-rotinas e escopo de variáveis, que são conceitos essenciais para todo programador. Sub-rotinas são muito importantes, pois permitem modularizar os códigos que desenvolvemos, desse modo, permitem que algumas partes da aplicação sejam reaproveitadas. Quando temos todo o código em um único bloco, a depender da complexidade do projeto, fica complicada a leitura, comprometendo, assim, a interpretação do código por outros programadores. Por outro lado, quando separamos as diferentes funcionalidades em módulos, fica fácil identificar o que cada parte do código realiza.
Iniciemos!
Sub-rotinas ou subprogramas são porções de código que realizam uma operação específica. Existem dois tipos de sub-rotinas: os procedimentos e as funções, conceitualmente, ambos realizam a mesma função, entretanto de modo diferente. Nessa lição, estudaremos os dois modos e como podemos aplicá-los para tornar os nossos códigos modulares.
Ao estudar sub-rotinas, surge a necessidade de entender como funciona o escopo das variáveis. Até agora, utilizamos variáveis que podem ser “vistas” por todo o algoritmo, isto é, em qualquer parte do algoritmo, podemos usar as variáveis que declaramos no início do programa. Entretanto, é possível declarar algumas variáveis que só são visíveis para uma porção específica do código (sub-rotina), não podendo ser utilizada em outra parte.
O escopo nada mais é que a visibilidade de uma variável. Existem dois tipos: as variáveis locais, que podem ser utilizadas apenas dentro das sub-rotinas, e as variáveis globais, que podem ser utilizadas por qualquer parte do algoritmo.
No seu dia a dia, como programador(a), você se deparará com problemas complexos. Para resolver esses tipos de problemas, é necessário decompô-los em problemas menores e, para isso, é necessário realizar uma análise para formular uma solução.
Para solução de subproblemas, utilizamos sub-rotinas que consistem em blocos de instrução que realizam uma tarefa específica. Imagine que estamos desenvolvendo um algoritmo de uma calculadora. Na calculadora, existem diversas operações, como: adição, subtração, multiplicação, divisão etc. Como sabemos, o primeiro passo é analisar o que queremos desenvolver, observar. Cada uma das operações que desejamos realizar pode ser decomposta em subproblemas, um subproblema do algoritmo de uma calculadora é a operação de adição, outro, o de subtração, e assim por diante.
Sabendo disso, podemos criar sub-rotinas para resolver cada um dos problemas. Então, ao invés de ter todas as operações programadas no bloco principal do programa, podemos definir os procedimentos e as funções que realizam cada uma das operações da calculadora e chamá-las quando necessário no programa principal. Desse modo, para a calculadora, teríamos quatro sub-rotinas:
Adição.
Subtração.
Divisão.
Multiplicação.
O case te deixou intrigado(a)? Assista ao vídeo a seguir para conhecer um pouco mais sobre essa história:
Uma sub-rotina consiste em um bloco de código que realiza uma função, que pode ser invocado a qualquer momento dentro do programa principal. Ela pode ter acesso às variáveis globais, como também às suas próprias variáveis “particulares”, conhecidas como variáveis locais (MANZANO; OLIVEIRA, 1997). Um programa pode conter uma ou diversas sub-rotinas, a quantidade delas será determinada pelo programador a partir da análise da complexidade do problema a ser resolvido.
Conforme definem Ascencio e Campos (2010), a utilização de sub-rotinas para a decomposição de problemas é determinante para a redução da complexidade de um algoritmo, permitindo que o programa seja modularizado. As principais vantagens da utilização de sub-rotinas são: facilidade de teste, evitar repetição de código e maior legibilidade do algoritmo.
Um procedimento é uma sub-rotina que não realiza retorno de dados. Consiste em um bloco de código com início e fim, identificado por uma assinatura que indica a forma com que deve ser invocado no programa principal. Quando um procedimento é chamado, ele é executado do início ao fim e retorna para a linha subsequente da chamada.
A sintaxe de uma procedimento é:
PROCEDIMENTO <nomeProcedimento> ()
VARIÁVEIS
<variáveis>
INÍCIO
<instruções>
FIM_PROCEDIMENTO
Em que:
<nomeProcedimento> indica o nome do procedimento que será utilizado para chamá-lo no programa principal.
<variáveis> é o local de declaração das variáveis locais do procedimento.
<instruções> é o bloco de código do procedimento.
Importante: as sub-rotinas devem ser declaradas antes do início do bloco principal de um algoritmo.
Veremos como declarar um procedimento na prática. Criaremos um programa que realiza a soma de dois números, para isso, criaremos um procedimento chamado soma, que será chamado dentro do programa principal.
PROCEDIMENTO Somar()
VARIÁVEIS
num1, num2, resultado : inteiro
INÍCIO
ESCREVA(“Digite o primeiro valor da soma”)
LEIA(num1)
ESCREVA(“Digite o segundo valor da soma”)
LEIA(num2)
resultado <- num1 + num2
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO
INÍCIO
Somar()
Escreva(“Sai do procedimento”)
FIM
Analisemos linha por linha.
Linha 1: declaração do procedimento Somar().
Linha 2: abertura do bloco de variáveis locais do procedimento, as variáveis declaradas nesse bloco só são visíveis para o procedimento.
Linha 3: declaração das variáveis num1, num2 e resultado. As variáveis num1, e num2, serão responsáveis por armazenar os valores que o usuário digitar, e a variável resultado, por armazenar o resultado da soma de num1 + num2.
Linha 4: início do bloco de código do procedimento.
Linha 5: comando ESCREVA solicitando ao usuário o primeiro valor da soma.
Linha 6: leitura do valor digitado pelo usuário e armazenado na variável num1.
Linha 7: comando ESCREVA solicitando ao usuário o segundo valor da soma.
Linha 8: leitura do valor digitado pelo usuário e armazenado na variável num2.
Linha 9: atribuição do resultado da soma num1 + num2 na variável resultado.
Linha 10: comando ESCREVA para exibir na tela o resultado da soma.
Linha 11: fim do bloco do procedimento.
Linha 13: abertura do bloco principal do programa.
Linha 14: chamada do procedimento Somar(). Nessa linha, o programa faz um desvio para o procedimento somar(), realiza as instruções que estão dentro do bloco do procedimento e, ao finalizar, volta para a próxima linha de onde ele foi chamado, no caso, a linha 15.
Linha 15: escreva para informar que o programa saiu do procedimento.
Linha 16: fim do algoritmo.
Procedimentos podem receber parâmetros, que são variáveis que são passadas na chamada do procedimento para enviar valores do programa principal ou outra sub-rotina que serão utilizados dentro do procedimento.
Por exemplo, no nosso procedimento Somar(), podemos utilizar parâmetros para enviar os dois números que serão somados, de forma que não será necessário solicitar os números ao usuário dentro do procedimento.
Os parâmetros de um procedimento deve ser indicado dentro dos parênteses da assinatura do procedimento, por exemplo, alteraremos a assinatura do procedimento Somar para ele receber dois valores como parâmetro:
PROCEDIMENTO Somar( A, B: INTEIRO)
VARIÁVEIS
INÍCIO
FIM_PROCEDIMENTO
Note, na linha 1, após o nome do procedimento, dentro dos parênteses, declaramos que, ao chamar esse método, é necessário informar dois valores do tipo inteiro que serão armazenados dentro das variáveis A e B, respectivamente. Esses valores poderão ser utilizados dentro do procedimento.
A chamada de um procedimento com parâmetros deve ser realizada indicando os valores que serão passados por parâmetro. Por exemplo, para chamar o procedimento Somar dentro do programa principal, precisamos informar os números que serão armazenados dentro de A e B:
INÍCIO
Somar( 5, 6)
Escreva(“Sai do procedimento”)
FIM
Observe que, na linha 2, realizamos a chamada do procedimento Somar e passamos os valores 5 e 6 que serão armazenado dentro das variáveis A e B.
Também, é possível passar como parâmetro valores que estão armazenados dentro de outras variáveis, por exemplo:
VARIÁVEIS
num1, num2 : inteiro
INÍCIO
num1 <- 5
num2 <- 6
Somar( num1, num2)
Escreva(“Sai do procedimento”)
FIM
Nesse caso, nas linhas 4 e 5, atribuímos valores dentro das variáveis num1 e num2. Na linha 6, chamamos o procedimento somar e passamos como parâmetros os valores armazenados dentro das variáveis, nesse caso, o algoritmo copia os valores armazenados em num1 e num2 para as variáveis locais do procedimento A e B.
Alteraremos o nosso algoritmo apresentado anteriormente para que ele receba os números da soma como parâmetro.
PROCEDIMENTO Somar(A, B: inteiro)
VARIÁVEIS
resultado : inteiro
INÍCIO
resultado <- A + B
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO
VARIÁVEIS
num1, num2: inteiro
INÍCIO
ESCREVA(“Digite o primeiro número")
LEIA(num1)
ESCREVA(“Digite o segundo número")
LEIA(num2)
Somar(num1, num2)
ESCREVA(“Sai do procedimento”)
FIM
Analisaremos linha por linha.
Linha 1: declaração do procedimento Somar(A, B: inteiro), o procedimento contém dois parâmetros, dessa forma, ao chamá-lo, devemos passar os valores de parâmetro.
Linha 2: abertura do bloco de variáveis locais do procedimento.
Linha 3: declaração da variável resultado que será responsável por armazenar o resultado da soma de A + B.
Linha 4: início do bloco de código do procedimento.
Linha 5: atribuição do resultado da soma A + B no resultado, em que A e B representam os números que foram passados por parâmetro na chamada do procedimento na linha 15.
Linha 6: comando ESCREVA para exibir na tela o resultado da soma.
Linha 7: fim do bloco do procedimento.
Linha 8: abertura do bloco de variáveis do programa principal.
Linha 9: declaração das variáveis num1 e num2 do tipo inteiro.
Linha 10: abertura do bloco principal do programa.
Linha 11: comando ESCREVA solicitando ao usuário o primeiro valor da soma.
Linha 12: leitura do valor digitado pelo usuário e armazenado na variável num1.
Linha 13: comando ESCREVA solicitando ao usuário o segundo valor da soma.
Linha 14: leitura do valor digitado pelo usuário e armazenado na variável num2.
Linha 15: chamada do procedimento Somar(A, B: inteiro ). Nessa linha, o programa faz um desvio para o procedimento somar(A, B: inteiro), passando como parâmetro os valores armazenados nas variáveis num1 e num2. Ao realizar as instruções que estão dentro do bloco do procedimento, volta para a próxima linha de onde ele foi chamado, no caso, a linha 16.
Linha 16: escreva para informar que o programa saiu do procedimento.
Linha 17: fim do algoritmo.
Note: esse algoritmo que acabamos de analisar faz exatamente a mesma coisa que o algoritmo apresentado anteriormente, entretanto, nesse caso, utilizamos a passagem de parâmetros para passar os valores que serão utilizados dentro do procedimento.
Uma função, assim como um procedimento, é uma sub-rotina que tem como objetivo desviar a execução do programa principal para realizar uma tarefa específica (MANZANO; OLIVEIRA, 1997). A diferença de um procedimento para uma função está no fato que uma função pode retornar um valor para o programa principal, isto é, após realizar os comandos que estão dentro do bloco, podemos indicar um valor que será retornado para o programa principal.
A sintaxe de uma função é dada por:
FUNÇÃO <nomeFuncao> (<parametros>) : <TipoRetorno>
VARIÁVEIS
<variaveis>
INÍCIO
<instruções>
RETORNE <valorDoRetorno>
FIM_FUNÇÃO
Em que:
<nomeFunção> indica o nome da função que será utilizado para chamá-la no programa principal.
<parametro> indica os parâmetros que serão utilizados; assim como procedimentos, funções podem ou não ter parâmetros.
<TipoRetorno> indica o tipo do valor que será retornado para o programa principal após a execução do programa.
<variáveis> é o local de declaração das variáveis locais da função.
<instruções> é o bloco de código da função.
<ValorDoRetorno> indica o valor que será retornado após a chamada.
Para exemplificar o uso de funções, criaremos um algoritmo que calcula o número fatorial de um número utilizando função. Para relembrar: o fatorial de um número qualquer “n” é representado por “n!” e é obtido a partir da multiplicação de todos os seus antecessores até o número um.
n! = n . (n – 1). (n – 2). (n – 3) …
Por exemplo, o fatorial de 5:
5! = 5 x 4 x 3 x 2 x 1 = 120
O algoritmo de fatorial pode ser escrito da seguinte forma:
FUNÇÃO Fatorial(num: inteiro) : inteiro
VARIÁVEIS
fat : inteiro
INÍCIO
fat <- 1
PARA inteiro i DE 1 ATÉ num PASSO 1 FAÇA
fat <- fat * i
FIM_PARA
RETORNE fat
FIM_FUNÇÃO
VARIÁVEIS
valor, resultado: inteiro
INÍCIO
ESCREVA(“Qual o número que você deseja descobrir o fatorial?”)
LEIA(valor)
resultado <- Fatorial(valor)
ESCREVA(“O fatorial é ”, resultado)
FIM
Analisaremos linha por linha.
Linha 1: declaração da função Fatorial(num: inteiro), a função contém um parâmetro, dessa forma, ao chamá-la, devemos passar o valor do parâmetro.
Linha 2: abertura do bloco de variáveis locais da função.
Linha 3: declaração da variável fat que será responsável por armazenar o cálculo do fatorial do número passado por parâmetro.
Linha 4: início do bloco de código da função.
Linha 5: inicialização da variável fat com o valor 1, pois o cálculo do fatorial começa em 1.
Linha 6: início do laço de Repetição para que seja responsável por passar por todos os números até o valor de num.
Linha 7: cálculo do fatorial, fat recebe o valor de fat multiplicado por i. A cada iteração do laço de repetição, i valerá um valor diferente até chegar no valor de num. Dessa forma, na primeira iteração, i = 1 e fat <- fat * 1. Na segunda iteração, i = 2 e fat <- fat * 2, e assim por diante, até chegar no valor que o usuário informou.
Linha 8: fim do laço de repetição
Linha 9: retorna da função. Aqui, informamos que a função deve enviar para o programa principal o valor armazenado na variável fat.
Linha 10: fim do bloco da função.
Linha 12: abertura do bloco de variáveis do programa principal.
Linha 13: declaração das variáveis valor e resultado do tipo inteiro.
Linha 14: abertura do bloco principal do programa.
Linha 15: comando ESCREVA solicitando ao usuário o valor para calcular o valor fatorial.
Linha 16: leitura do valor digitado pelo usuário e armazenado na variável valor.
Linha 17: a variável resultado recebe o valor de retorno da chamada da função fatorial, passando como parâmetro o valor que o usuário digitou. Nessa linha, o programa é desviado para o bloco da função e, então, é calculado o valor do fatorial do valor passado por parâmetro. Ao concluir a execução da função, o programa retorna o valor do cálculo e armazena na variável resultado.
Linha 18: escreva para imprimir na tela o resultado do fatorial calculado e retornado pela função
Linha 19: fim do algoritmo
Ficou interessado(a) sobre esse tema? Clique no play a seguir e assista ao vídeo:
Agora que você já sabe como utilizar procedimentos e funções, que tal colocar esse conhecimento em prática, escrevendo um algoritmo que foi apresentado no case? Escreveremos um algoritmo de uma calculadora que realiza as quatro operações básicas.
Objetivo: construir um algoritmo que realize as quatro operações básicas.
Entrada: ler os valores que o usuário deseja operar e ler qual operação deseja realizar.
Processamento: realizar a operação selecionada.
Saída: exibir o resultado da operação.
PROCEDIMENTO Somar(A, B: inteiro)
VARIÁVEIS
resultado : inteiro
INÍCIO
resultado <- A + B
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO.
PROCEDIMENTO Subtrair(A, B: inteiro)
VARIÁVEIS
resultado : inteiro
INÍCIO
resultado <- A - B
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO
PROCEDIMENTO Multiplicar(A, B: inteiro)
VARIÁVEIS
resultado : inteiro
INÍCIO
resultado <- A * B
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO
PROCEDIMENTO Dividir(A, B: real)
VARIÁVEIS
resultado : real
INÍCIO
resultado <- A / B
ESCREVA(“O resultado é ”, resultado)
FIM_PROCEDIMENTO
VARIÁVEIS
num1, num2, opcao : inteiro
INÍCIO
opcao <- 0
ESCREVA(“Qual operação aritmética deseja realizar?”)
ESCREVA(“1 - SOMAR”)
ESCREVA(“2 - SUBTRAIR”)
ESCREVA(“3 - MULTIPLICAR”)
ESCREVA(“4 - DIVIDIR”)
LEIA(opcao)
ESCREVA(“Qual o primeiro valor que deseja operar?”)
LEIA(num1)
ESCREVA(“Qual o segundo valor?”)
LEIA(num2)
SE (opcao == 1) ENTÃO
Somar(num1, num2)
SENÃO SE (opcao == 2) ENTÃO
Subtrair(num1, num2)
SENÃO SE (opcao == 3) ENTÃO
Multiplicar(num1, num2)
SENÃO SE (opcao == 4) ENTÃO
Dividir(num1, num2)
FIM SE
FIM_SE
FIM_SE
FIM_SE
FIM
No nosso dia a dia, como programadores, tendemos a repetir algumas porções de código, como instruções de escrita, comparações, entre outras. Desse modo, é importante identificar essas partes de repetição e, então, separar em funções, para, assim, poder reutilizar o código, eliminando as repetições.
ASCENCIO, A. F. G.; CAMPOS, E. A. P. V. de. Fundamentos da Programação de Computadores. São Paulo: Pearson Education 2010.
MANZANO, J.; OLIVEIRA, F. Estudos Dirigidos de Algoritmos. São Paulo: Érica, 1997.