Lógica de Programação - Subprogramas

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Objetivos da Aula

Após esta aula o aluno deverá ser capaz de:

  • Identificar padrões/blocos de código que se repetem na solução de determinados problemas;
  • Encapsular blocos de código na forma de subprogramas/subprocessos, representado-os com fluxogramas e pseudocódigo;
  • Identificar os dados de entrada de subprogramas, representado-os na forma de parâmetros do subprograma;
  • Identificar valores de retorno de subprogramas;
  • Aplicar subprogramas/subprocessos na solução algorítmica de problemas diversos.

Quebrando um problema em subproblemas: SUBPROGRAMAS

CASO DE ESTUDO 1: Elevando um número a uma potência inteira

Em várias algoritmos surge a necessidade de "elevar" um número a uma potência inteira. Muitos sistemas computacionais não conseguem implementar esta operação através uma operação simples da CPU. O que deve ser feito é multiplicar repetidas vezes o número de forma a se obter a operação de potenciação. Neste caso, um dado problemas simples, cuja solução requer o uso de potenciação em várias partes do algoritmo, deve replicar o código, abrindo espaço para possíveis erros, além de aumentar desnecessariamente o tamanho do algoritmo.

EXEMPLO: Implementar um algoritmo na forma de pseudocódigo de forma a resolver a seguinte equação: DADOS DE ENTRADA: valor de x e de y DADOS DE SAÍDA: valor computado de z

Solução 1 - inserindo código de repetição para resolver a potenciação

ALGORITMO  funcao_xyz()
VARIAVEIS
  x,y,z,prod1, prod2: real
  i: inteiro
INICIO
  LER x
  LER y
  prod1 = 1;
  i = 0
  ENQUANTO i < 7  FAÇA
      prod1 <- prod1 * x
      i <- i+1
  FIM_ENQUANTO
  prod2 = 1;
  i = 0
  ENQUANTO i < 3  FAÇA
      prod2 <- prod2 * y
      i <- i+1
  FIM_ENQUANTO  
  z = prod1 + prod2
  mostrar z
FIM

CASO DE ESTUDO 2: Controle de Acesso

Vamos retomar inicialmente o problema de controle de acesso:

PROBLEMA: Aprimorar o exemplo do controle de acesso para que, no caso de 3 tentativas de acesso seguidas, com senha errada, o sistema seja bloqueado. O administrador desbloqueia redefinindo a senha e zerando o contador de acesso.

  • DADOS DE ENTRADA: senha inserida pelo usuário na variável SENHA /* variável que armazena a senha entrada pelo usuário ou administrador */
  • DADOS DE SAÍDA: mensagem de abertura da porta / usuário bloqueado*/
  • VARIÁVEIS INTERMEDIÁRIAS: CONT_ACESSO /* valor inicial zero - incrementada a cada senha inválida */

FluxogramaControleAcessoComContador.jpg

Note que a variável CONT_ACESSO é iniciada com zero e incrementada a cada erro no fornecimento da senha. A atribuição CONT_ACESSO = CONT_+ACESSO + 1 deve ser interpretada da forma: acesse o valor de CONT_ACESSO e some 1 a este valor. Coloque o resultado novamente em CONT_ACESSO (o conteúdo anterior é sobrescrito!)

Esta solução não é perfeita e poderia ser aprimorada. Se o administrador erra, ele pode vir a bloquear o usuário.


Neste procedimento pode ser observado que:

  • começa a aparecer uma certa complexidade no fluxograma;
  • além disto, não ficou uma abordagem muito interessante, pois se for o administrador que erra a senha, ele pode bloquear o usuário. Mudando a ordem de teste pode-se contornar este problema.
  • não existe forma de desbloquear a senha (zerar o contador), a não ser mudando a senha.

Em síntese, existem subproblemas adicionais a serem resolvidos que adicionam complexidade ao sistema. Como podemos resolvê-los sem deixar um fluxograma complexo?

Usaremos a caixa de processos pré-definidos que usaremos para invocar funções que resolvem determinado subproblema.

Inicialmente, vamos construir três subprogramas:

  • Iniciar_Sistema(): inicia variáveis do sistema, colocando o sistema em um estado inicial conhecido;
  • Tratar_Admin(): é o código que trata a funcionalidade associada ao administrador;
  • Tratar_User(): é a funcionalidade que trata o usuário (procedimento de abrir porta, bloquear etc).

FluxogramaControleAcessoComSubprograma.jpg

OBS: Note que foi usada uma variável auxiliar AUX que permite ajustar o valor
de número de acessos a ser mostrado no display. Note também que na caixa DISPLAY foi usado
uma string a ser impressa e a variável AUX cujo conteúdo deve ser impresso. Ambos separados
por vírgula.
  • ANINHAMENTO DE DECISÔES

A função Tratar_User() se utiliza de aninhamento de decisões. Em um primeiro momento é testado se a senha confere com a senha do usuário. SE ela conferir ENTÂO é testado se o contador de bloqueios está dentro do aceitável.

PARÂMETROS E RETORNO DE VALORES EM SUBPROGRAMAS

Para tornar ainda mais interessante o uso de subprogramas, vamos ver o conceito de passagem de parâmetros e retorno de valores.

Quando chamamos (invocamos) um subprograma podemos passar valores (dados de entrada) para este subprograma.
Estes valores são passados através de variáveis especiais que chamamos de parâmetros.
Parâmetros podem ser passados por valor e por referência. Por valor é quando os dados a serem passados na invocação
do subprograma são copiados para uma variável do subprograma.
Os parâmetros são passados por referência quando o que é passado para o subprograma é simplesmente o endereço da variável
repassada na invocação do subprograma.

Não existe uma forma explícita de definir os parâmetros em um fluxograma. Deve-se realizar um comentário antes ou ao lado do mesmo especificando o tipo e como será tratado o parâmetro.

EXEMPLO: Seja elaborar um fluxograma correspondente a uma subprograma que deve calcular o fatorial de um número inteiro passado como parâmetro. O subprograma deve retornar o valor calculado.

A função fatorial é definida por:

FluxogramaFatorial.jpg

Neste fluxograma, o subprograma denominado CalcFatorial recebe um valor no parâmetro N (implicitamente inteiro) e retorna o valor calculado do fatorial.

O fluxograma principal invoca duas vezes o subrograma. O retorno é armazenado nas variáveis NUM1 e NUm3.

Quando um subprograma retorna um valor, ele é chamado de função. Para manter coerência com o C chamaremos
qualquer subrprograma de função (independente de retornar valor).

EXERCÍCIO: Implementar a solução acima usando pseudocódigo.

EXERCÍCIO: Implementar uma função (subpŕograma), usando fluxograma, que recebe dois números inteiros como parâmetro. A função retorna 1 se os números forem iguais, 0 se o primeiro número maior que o segundo e -1 se o segundo for maior que o primeiro.