eel170 computaÇÃo i del.ufrj.br/~ac/eel170.htm
DESCRIPTION
Antonio Cláudio Gómez de Sousa [email protected] 2a série de slides Versão 15/02/2014. EEL170 COMPUTAÇÃO I www.del.ufrj.br/~ac/eel170.htm. Programação Estruturada. Utiliza somente as estruturas de controle: Sequencial Iterativa Condicional. Pascal. Linguagem de programação: Estruturada - PowerPoint PPT PresentationTRANSCRIPT
EEL170 COMPUTAÇÃO I www.del.ufrj.br/~ac/eel170.htm
2a série de slidesVersão 30/08/2016
2
Pascal
Linguagem de programação: Estruturada De alto nível Fortemente tipificada Permite modularização Refinamento etapa por etapa Escopo de variáveis global e local Alocação estática e dinâmica de memória Orientação a objetos
3
Estrutura de um programa em Pascal
program <identificador>; uses <lista de identificadores de units>; // declarações de utilização de bibliotecas const //declarações para definição de constantes <identificador> = <valor>; // exemplo de declaração de constante type //declarações de tipos <identificador> = <declaração de tipo>; // exemplo de declaração de tipo var //declarações de variáveis <identificador> : <tipo>; // exemplo de declaração de variável procedure <identificador> (<parâmetros>); // declarações de procedimentos function <identificador> (<parâmetros>) :tipo; // declarações de funções begin <comandos>; // comandos do módulo principal end.
4
Principais comandos em Pascal: Atribuição // <identificador> <expressão algébrica>; if <condição> then
<comando>
[else <comando>]; case <seletor> of
<valor do seletor>>: <comando>; ... end repeat
<comandos>; until <condição>; while <condição> do
<comando>; for <identificador> := <valor> to | downto <valor> do
<comando>; comandos de entrada e saida
5
Regras para uma programação com qualidade
Colocar um comentário no início dos programas com seu objetivo, responsável e data
Colocar um comentário no início de cada módulo com sua finalidade e separar visualmente os módulos
Comentar Dentear/identar os comandos controlados por repita, para, enquanto,
caso, se-então-senão Utilizar identificador que lembre a semântica do conteúdo da variável ou
finalidade do procedimento – estética Java: identificador em minúsculas e maiúsculas só no início das palavras que o compõem, a partir da segunda palavra
Exemplos: dataDia, somaNotas, totalAlturasHomens Não alterar uma variável controlada por for dentro da iteração Usar for quando o escopo da variável de controle é conhecido Não usar variáveis booleanas desnecessárias
6
Modularização
Dividir para vencer Para resolver programas complexos
Separá-los em programas menores - módulos ou subprogramas
Algoritmos subalgoritmos ou módulos Subalgoritmo
Módulo projetado para executar uma tarefa específica
Partes de algoritmos que se repetem: Colocados em um módulo e chamados quantas vezes for
necessário de diferentes partes do mesmo programa
7
Algoritmo complexo - método de refinamento etapa por etapa
• Desenvolver o algoritmo em alto nível de abstração criando subalgoritmos para resolver problemas específicos
• Cada subalgoritmo pode ser separado em outros subalgoritmos em níveis de abstração mais baixos
• Parar quando chegar a subalgoritmos com baixa complexidade
• Subalgoritmos módulos• Cada módulo pode ser programado e testado
de forma independente
Algoritmo simples(* ordenar tres variáveis utilizando um módulo que ordena duas variáveis; data:.....; autor: ….*)
Var
a, b, c: real // variáveis globais
Inicio // módulo principal Exemplo
leia (a,b,c) 8 e 9 e 4
ordena (a,b) // passa a,b e os recebe ordenados – parâmetros atuais ou reais passa 8 e 9 retorna 8 e 9
ordena (b,c) // passa b,c e os recebe ordenados – parâmetros atuais ou reais passa 9 e 4 retorna 4 e 9
ordena (a,b) // passa a,b e os recebe ordenados – parâmetros atuais ou reais passa 8 e 4 retorna 4 e 8
escreva (a,b,c) 4 e 8 e 9
Fim // módulo principal
// --------------------------------------------------------------------------------------------
ordena(var x,y: real) // módulo ordena com dois parâmetros formais para os valores a ordenar e uma variável local
var // os dois parâmetros com passagem por referência
Aux: real
inicio
se x > y então
inicio
aux x
x y
y aux
fim
fim // módulo ordena
Diagrama de estrutura
Módulo principal
ordena
Passa dois valores Retornam dois valores
Módulos
• A modularização do programa pode ser feita através de procedimentos ou funções
• Os procedimentos ou funções são módulos, ou sub-programas, que programamos e podem ser “chamados” de vários pontos do algoritmo
• Procedimentos: podem receber e devolver vários parâmetros
• Funções: podem receber vários parâmetros mas devolvem um valor - como uma função matemática elas tem tipo
11
Procedimento
• Quando chamamos um procedimento podemos passar dados para o procedimento e receber dados do procedimento, através de parâmetros que são passados entre o módulo chamador e o módulo chamado
• Exemplo: vamos fazer um algoritmo que permite digitar dois valores e calcular sua média
• A média será calculada em um procedimento que definimos no algoritmo
• Um módulo do algoritmo deverá passar os dois valores para o procedimento e o parâmetro para o resultado, e o procedimento devolverá a média calculada no parâmetro do resultado.
12
algoritmo calcularMédia
(*algoritmo para calcular a média de dois pares de dados com um procedimento*)
Var
dado1, dado2, dado3, dado4, media: real // variáveis globais
// definição do procedimento
procedimento calcMed(x,y:real; var med:real)
// x,y passagem por valor – med passagem por referência
inicio
med (x + y)/2 // o retorno é pelo parâmetro passado por referência
fim
inicio // início do módulo principal exemplo
leia (dado1,dado2); // orientar e validar 4 e 6
calcMed(dado1, dado2, media) // chama procedimento passa 4 e 6 e 0 retorna 5
escreva(‘A média é ‘,media) A média é 5
Leia (dado3, dado4); // orientar e validar 2 e 4
calcMed(dado3,dado4,media) // chama procedimento passa 2 e 4 e 5 retorna 3
escreva(‘A média é ‘,media) A média é 3
fim
13
Estrutura modular
A estrutura modular do algoritmo apresenta o módulo principal, o procedimento e duas setas indicando que há parâmetros nos dois sentidos
calcularMedia
calcMed
x,y,med med
Med: Passagem por referênciax,y: Passagem por valor
14
Passagem de parâmetros
Nos procedimentos os parâmetros podem ser passados por valor ou por referência
No parâmetro passado por valor o módulo que chama passa o valor de seu parâmetro para o parâmetro do módulo chamado, o que resulta em uma passagem de dados apenas em um sentido
No parâmetro passado por referência o módulo que chama passa a referência de seu parâmetro para o parâmetro do módulo chamado; desta forma os dois parâmetros são referências para a mesma variável, o que permite passar dados nos dois sentidos
15
Função
• Quando chamamos uma função podemos passar dados para a função por meio dos parâmetros, e receber o resultado calculado pela função
• Exemplo: vamos fazer um algoritmo que permite digitar dois valores e calcular sua média
• A média será calculada em uma função que definimos no algoritmo
• Um módulo do algoritmo deverá passar os dois valores para a função, e a função devolverá a média calculada.
16
algoritmo calcularMédia
(*algoritmo para calcular a média de dois pares de dados com uma função*)
Var
dado1, dado2, dado3, dado4, media: real
// definição da função
função calcMed(x,y:real):real // a função tem tipo
inicio
calcMed (x + y)/2
fim
inicio // início do módulo principal Exemplo
leia (dado1,dado2); // orientar e validar 4 e 6
media calcMed(dado1,dado2) // chama função passa 4 e 6 retorna 5
escreva(‘A média é ‘,media) A média é 5
leia (dado3,dado4); // orientar e validar 2 e 4
escreva(‘A média é ‘, calcMed(dado3, dado4)) // A média é 3
fim
17
Estrutura modular
A estrutura modular do algoritmo apresenta o módulo principal, o procedimento e duas setas indicando que há parâmetros nos dois sentidos
calcularMedia
calcMed
x,y CalcMed
18
Estruturas de dados
19
Estrutura de dados homogênea
Problema: Após ler as notas dos alunos de uma turma (uma nota por aluno), calcular a média e quantos alunos ficaram com nota acima da média.
Este problema tem uma dificuldade: em uma primeira etapa digita-se as notas de todos os alunos; em uma segunda etapa calcula-se a média, e só então em uma terceira etapa pode-se comparar a média com a nota de cada aluno, para verificar quantos ficaram com a nota acima da média. Isso exige redigitar todas as notas da primeira etapa ou guardar todas as notas de maneira que se possa recuperá-las. A segunda possibilidade é a melhor.
20
Estrutura de dados homogênea
No ensino médio foi vista uma estrutura de dados que permite guardar vários valores de uma variável: a matriz.
Matriz: estrutura de dados homogênea - permite múltiplos valores de um mesmo tipo, por isso é dita homogênea.
Exemplo: uma matriz com números inteiros – em cada elemento da matriz podemos ter um número inteiro.
Dimensão: a matriz pode ter uma, duas três ou n dimensões.
Para acessar um elemento da matriz temos de saber quantas dimensões ela tem, e o índice para cada dimensão.
21
Elementos de uma matriz com uma dimensão com 5 elementos – um índice
Matriz a
[ a1 a2 a3 a4 a5 ]
22
Matriz em linguagens de computação
As linguagens de computação geralmente tem uma estrutura de matrizes, ou comandos que permitem manipular dados como matrizes.
Uma matriz de uma dimensão também é chamada de vetor
Como se define uma matriz em LEA: <identificador>: matriz [<dimensão1>,...,<dimensãon>]: <tipo>
<dimensão> := <valor inicial>,<valor final>
Exemplo: notas: matriz [1..45] de real; // uma dimensão com 45 elementos
Exemplo: temperaturas: matriz [1..31, 1..24] de real; Matriz com duas dimensões com 31 e 24 elementos respectivamente nas dimensões Nas matrizes com duas dimensões utiliza-se a indicação de linhas e colunas
23
Sintaxe das matrizes em Pascal
<identificador> : array [<dimensão1>,...,<dimensãon>]: <tipo>
<dimensão> := <valor inicial>,<valor final> Exemplo: notas: array [1..45] of real;
Matriz de uma dimensão com 45 elementos reais.
Exemplo: temperaturas: array [1..31, 1..24] of real; Matriz com duas dimensões com 31 e 24 elementos respectivamente nas
dimensões.
24
Voltando ao nosso problema
Problema: Após ler as notas dos alunos de uma turma (uma nota por aluno), calcular a média da turma e quantos alunos ficaram com nota acima da média.
Solução: Fazer um programa que permita informar as notas, guardando-as em uma matriz, calcular a média e depois comparar essa média com cada nota, contando as que estão acima da média.
Algoritmo: algoritmo mediaAcima; (* algoritmo para calcular a média das notas de alunos
e quantos estão acima da média; responsável:...; data:...*)
25
Var
turma: matriz [1..45] de real // matriz para as notas dos aluno
nota, somaNotas, mediaNotas: real
notasAcima, aluno: inteiro
inicio
somaNotas, notasAcima 0 // preparar um acumulador e um contador
para aluno variando de 1 a 45 faça // Exemplo
inicio Primeira iteração // Segunda iteração
escreva (‘Informe a nota do aluno ‘, aluno) // Informa a nota do aluno 1 // Informa a nota do aluno 2
leia (nota) (* testar *) // 8 // 7
turma [aluno] nota // matriz 8 0 0 0 0 0 0 … // matriz 8 7 0 0 0 0 0 ...
somaNotas somaNotas + nota // somaNotas = 8 // somaNotas = 15
fim
mediaNotas somaNotas / 45 // mediaNotas = 7,5
para aluno variando de 1 a 45 faça
inicio
se turma [aluno] > mediaNotas então // se 8 > 7,5
notasAcima notasAcima + 1 // notasAcima = 1
fim
escreva (‘A média dos alunos é ‘,mediaNotas, ‘ e há ‘, notasAcima, ‘alunos com nota acima da média’)
fim.
26
Programa em Pascal
program mediaAcima;
(* programa para calcular a média das notas de alunos e quantos estão acima da média; responsável:...; data:...*)
27
var
turma: array [1..45] of real;
somaNotas, nota, mediaNotas: real;
aluno, notasAcima: integer;
begin
somaNotas := 0; // iniciar o acumulador
notasAcima := 0; // iniciar o contador
for aluno := 1 to 45 do // para controlar a entrada de dados de 45 alunos
begin
writeln (‘Informe a nota do aluno ‘, aluno:2);
readln (nota);
turma [aluno] := nota;
somaNotas := somaNotas + nota;
end;
mediaNotas := somaNotas / 45;
for aluno := 1 to 45 do // para comparar a nota de cada aluno com a média geral
begin
if turma [aluno] > mediaNotas then
notasAcima := notasAcima + 1;
end;
writeln (‘A média dos alunos é ‘,mediaNotas:4:1, ‘ e há ‘, notasAcima:2, ‘alunos com nota acima da média’);
end.
28
Ordenar elementos em uma estrutura linear
Problema: Ordenar nomes em uma matriz.
Solução: Fazer um programa que permita digitar 10 nomes, ordená-los e apresentar os nomes desordenados e ordenados.
Algoritmo:
Algoritmo ordenaNomes
(* algoritmo para ordenar nomes em uma lista linear; responsável: ...; data: ...*)
29
Var
Inicial, Ordenado: matriz[1..10] de literal
Indice, contador: inteiro
Inicio
para indice variando de 1 a 10 faça
inicio
escreva(‘Informe o nome ‘,índice)
leia (Inicial[indice]) (* testar *)
fim
// copiar os dados para a estrutura que será ordenada
para índice variando de 1 a 10 faça
Ordenado[índice] Inicial[índice]
30
(* algoritmo do bubble sort *)
inicio
para contador variando de 1 a 9 faça
inicio
para indice variando de 1 a 9 faça
inicio
se ordenado[indice] > ordenado[indice+1] então
início
auxiliar ordenado[índice]
ordenado[índice] ordenado[índice+1]
ordenado[índice+1] auxiliar
fim
fim
fim
31
{ apresentar os dados não ordenados e ordenados}
escreva (‘Nomes antes da ordenação:’)
para índice variando de 1 a 10 faça
inicio
escreva (inicial[índice]) // na mesma linha
fim
escreva (‘Nomes após a ordenação:’)
para índice variando de 1 a 10 faça
inicio
escreva(ordenado[índice]) // na mesma linha
fim
fim
32
(* algoritmo do bubble sort - com pequena otimização *)
inicio
para contador variando de 9 a 1 faça
inicio
para indice variando de 1 a contador faça
inicio
se ordenado[indice] > ordenado[indice+1] então
início auxiliar ordenado[índice] ordenado[índice] ordenado[índice+1] ordenado[índice+1] auxilir
fim
fim fim
fim
33
Calcular o determinante de uma matriz 3x3
Problema: calcular o determinante de uma matriz 3x3.
Solução: fazer um programa que: Permita digitar os dados de uma matriz 3x3; Calcule seu determinante; usar uma matriz 5x3
para repetir as linhas 1 e 2 em 4 e 5 para facilitar o cálculo do determinante;
Apresente a matriz em sua forma matricial; Apresente o valor de seu determinante.
Algoritmo:
34
algoritmo determinante3x3
(* algoritmo para o cálculo do determinante de uma matriz 3x3; responsável:...; data:...*)
var
dados: matriz[1..5,1..3] de real
linha, coluna, indice: inteiro
determinante: real
inicio
para linha variando de 1 a 3 faça // entrada de dados inicio
para coluna variando de 1 a 3 faça // entrada dados inicio
escreva (‘Informe o valor do elemento ‘,linha,’, ‘,coluna)
leia (dados[linha,coluna])
fim
fim
35
// cálculo do determinante
// copiar as linhas 1 e 2 para as linhas 4 e 5
para linha variando de 1 a 2 faça
inicio para coluna variando de 1 a 3 faça
inicio dados[linha+3,coluna] dados [linha,coluna]
fim
fim
//cálculo do determinante
determinante 0
para indice variando de 1 a 3 faça
inicio
determinante determinante +
dados[indice+0,1]*dados[indice+1,2]*dados[indice+2,3]
fim
para indice variando de 1 a 3 faça
inicio
determinante determinante -
dados[indice+0,3]*dados[indice+1,2]*dados[indice+2,1]
fim
37
// apresentar a matriz em forma matricial
escreva(‘a matriz é:’)
para linha variando de 1 a 3 faça
inicio
para coluna variando de 1 a 3 faça
inicio
escreva( dados[linha,coluna])
fim
pule uma linha
fim
escreva(‘O determinante da matriz vale ’, determinante)
fim
38
Estrutura de dados heterogênea
Problema: manter os dados de uma DVDteca domiciliar. Para cada CD manter: Título Intérprete Autor Duração em minutos
Estes dados são heterogêneos Necessitamos de novo tipo de estrutura de
dados
39
Registro: variável heterogênea
O registro permite definir dados heterogêneos em uma variável estruturada, através da composição da variável
Exemplo de variável heterogênea: Var dvd: registro título: literal // início da definição .......................intérprete: literal .......................autor: literal .......................duração:real .......................fim // término da definição
40
Como acessar cada elemento de uma variável heterogênea
Cada elemento de uma variável heterogênea é acessado pelo identificador da variável seguido de ponto (.) e do identificador do elemento
Exemplo: leia (dvd.titulo) escreva (dvd.titulo)
41
Guardar os dados em uma variável estruturada
algoritmo dvdTeca1
(* algoritmo para ler e guardar os dados de um dvd; responsável:... ; data:... *)
Var
dvd: registro título: literal // início da definição
.......................intérprete: literal
.......................autor: literal
.......................duração:real
.......................fim // término da definição do registro
Inicio
leia (dvd.titulo, dvd.interprete, dvd.autor, dvd.duração) // orientar testar
escreva (dvd.titulo, dvd.interprete, dvd.autor, dvd.duração)
fim
42
Retornando ao problema da DVDTeca
A solução não resolve o problema: permite armazenar os dados apenas de um DVD
Para armazenar os dados de vários DVDs a solução será utilizar uma matriz unidimensional de registros
Em cada posição da matriz haverá um registro com seus elementos constitutivos
Vamos introduzir a definição de tipo de variável
43
Definição de tipo de variável
Nas linguagens há tipos primitivos e derivados.
Tipos primitivos: definidos na linguagemEx.: real, inteiro, booleano, ….
Derivados: definidos a partir dos tipos primitivosEx.:
tipo
tDMes = (1..31)
tMAno = (1..12)
var
diaMes1, diaMes2, diaMes3: tDMes
mesAno, mesAno1: tmAno
44
Algoritmo dvdTeca2
(* algoritmo para manter os dados de dez DVDs; responsável: ... ; data: ... *)
tipo // declaração de tipos de variáveis
tRegDvd = registro título: literal
............................ ....intérprete: literal
............................ ....autor: literal
............................ ....duração:real
............................. ...fim
var // declaração das variáveis
dvd: matriz[1..10] de tRegDvd
indice: inteiro
45
Inicio
para índice variando de 1 a 10 faça
Início
escreva(‘Informe o título, intérprete, autor e duração do DVD ‘,índice)
leia(dvd[índice].título, dvd[índice].intérprete)
leia(dvd[índice].autor, dvd[índice].duração) (* testar *)
fim
// apresentação dos dados
para índice variando de 1 a 10 façaescreva(dvd[índice].título, dvd[índice].intérprete, dvd[índice].autor,
dvd[índice].duração)
fim
46
Menu
O algoritmo anterior não dá flexibilidade ao usuário. Muitas vezes é necessário oferecer opções, e o usuário escolher a cada momento a opção mais adequada.
47
DVDteca com menu
Problema: para o problema anterior, oferecer ao usuário as opções: Incluir um DVD Listar todos os DVDs Consultar um DVD pelo título
Solução: fazer um programa que permita ao usuário, de forma interativa, escolher uma das opções até que o usuário escolha sair do programa.
48
Algoritmo dvdTeca3
(* algoritmo para incluir, listar e consultar os dados de dvd; responsável:... ; data:... *)
tipo // declaração de tipos de variáveis
tRegDvd = registro título: literal
.................................intérprete: literal
.................................autor: literal
.................................duração:real
.................................fim
var // declaração das variáveis
dvd: matriz[1..10] de tRegDvdindice,
opcao, primPosLivre: inteiro
titu: literal
49
Inicio
// preparar para iniciar a partir da primeira posição
primeiraPosLivre 1
repita // apresentação do menu
escreva(‘digite 1 para incluir os dados de um DVD’)
escreva(‘digite 2 para listar os dados de todos os DVDs’)
escreva(‘digite 3 para consultar os dados de um DVD por seu título’)
escreva(‘digite 4 para sair do programa’)
leia opção // validar
50
Caso opção seja
1: inicio // incluir um DVDescreva(‘Informe o título, intérprete, autor e duração do DVD ‘)
leia(dvd[primeiraPosLivre].título, dvd[primeiraPosLivre].intérprete, dvd[primeiraPosLivre].autor, dvd[primeiraPosLivre].duração) (*testar*)
primeiraPosLivre primeiraPosLivre + 1 // atualizar posição livre
fim
2: inicio // listar todos os DVDs para índice variando de 1 a primeiraPosLivre - 1 faça
inicio escreva(dvd[índice].título, dvd[índice].intérprete, dvd[indice].autor, dvd[indice].duração)
fim
fim
51
3: inicio // para consultar um DVD escreva(‘Informe o título do DVD que procura’)
leia(titu)
indice 1
enquanto (titu <> dvd[índice].titulo) e (indice < primeiraPosLivre) faça
ÍnicioÍndice Índice + 1
fim
se índice < primeiraPosLivre entãoescreva(‘Os dados do DVD são: ‘, dvd[índice].título,
dvd[índice].intérprete, dvd[índice].autor, dvd[índice].duração) senão
escreva(‘Não há DVD com esse título’) fim
Fim // fim do caso do menu
até que opção = 4
fim
Modularização
53
Refinamento etapa por etapa
O algoritmo recém visto é pequeno, mas ocupa 4 slides, o que não deixa clara sua lógica. Com algoritmos maiores isto se agrava. A solução é o refinamento etapa por etapa: começar pelo módulo principal do algoritmo e, para processamentos importantes dentro do módulo principal, criar módulos que realizem esses processamentos para o módulo principal.
Se algum dos processamentos novos for muito grande, pode ser quebrado em outros módulos, e assim por diante.
Vamos rever então o último algoritmo.
54
Algoritmo dvdTeca4
(* algoritmo para incluir, listar e consultar os dados de dvd com modularização; responsável:... ; data:... *)
tipo // declaração de tipos de variáveis
tRegDvd = registro título: literal
.................................intérprete: literal
.................................autor: literal
.................................duração:real
.................................fim
tMatDvd = matriz[1..10] de tRegDvd
var // declaração das variáveis
dvd: tMatDvd
indice, opcao, primeiraPosLivre: inteiro
55
Inicio // Módulo principal
primPosLivre 1 // preparar a primeira posição
repita
opção ← funMenu
caso opção seja:
1: procIncluirDvd (dvd; primPosLivre)
2: procListarDvd (dvd; primPosLivre)
3: procConsultarDvd(dvd; primPosLivre)
fim
até que opcao = 4
fim.
56
funMenu()
// Função para o usuário escolher uma opção
repita // apresentação do menu
escreva(‘digite 1 para incluir os dados de um DVD’)
escreva(‘digite 2 para listar os dados de todos os DVDs’)
escreva(‘digite 3 para consultar os dados de um DVD por seu título’)
escreva(‘digite 4 para sair do programa’)
leia opção
até que opção válida // (1 a 4)
57
procedimento procIncluirDvd(var dvd:tMatDvd; var ppl: inteiro)
// procedimento para incluir um DVD
inicio
escreva(‘Informe o título, o intérprete, o autor e a duração do DVD ‘)
leia(dvd[ppl].título, dvd[ppl].intérprete, dvd[ppl].autor, dvd[ppl].duração //validar
ppl ppl + 1 // atualizar posição livre
fim
procedimento procListarDvd(dvd:tMatDvd; ppl: inteiro) //listarDVD
// procedimento para listar todos os DVDs
inicio para índice variando de 1 a ppl - 1 faça
Inicio
escreva(dvd[índice].título, dvd[índice].intérprete, dvd[indice].autor,dvd[indice].duração)
Fim
fim
58
procedimento procConsultarDVD(dvd:tMatDvd; ppl: inteiro
// procedimento para consultar um Dvd
Var indice: inteiro
titu: literalinicio
escreva(‘Informe o título do DVD que procura’)
leia(titu) // título procurado
iIndice 1
enquanto (indice < ppl) e (titu <> dvd[índice].titulo) faça // para navegar na estrutura
inicio
indice indice + 1
Fim
se indice < ppl então // escolher se encontrou ou não o titulo procurado
escreva(‘Os dados do DVD são: ‘, dvd[indice].título, dvd[índice].intérprete, dvd[índice].autor, dvd[índice].duração)
senão
escreva(‘Não há DVD com esse título’)
fim
59
dvdteca4
procIncluirDVD procListarDVD procConsultarDvdfunMenu
Diagrama modular do algoritmo
60
Estrutura de algoritmo com menu
algoritmo ...
// comentário com objetivo, autor e data
// declarações de constantes, tipos e variáveis
Início
// preparar
Repita
apresentar opções do menu
usuário escolhe uma opção
caso opcao seja
(<escalar>: <bloco de comandos>)*
fim // fim do caso
Ate que opcao tenha sido encerrar o menu
// parte final do algoritmo
fim
61
Problema: Realizar operações com matrizes e apresentar os resultados na forma matricial
Solução: Fazer um programa que permita realizar operações com matrizes quadradas de 2X2 até 10X10, e ofereça interativamente as opções: 1 - Digitar os dados da primeira matriz 2 – Digitar os dados da segunda matriz 3 - Somar as matrizes 4 - Subtrair a segunda da primeira 5 - Multiplicar as matrizes 6 - Achar a transposta da primeira 7 – Sair do programa
62
algoritmo operaMatriz(* algoritmo para realizar operações sobre matrizes quadradas;
responsável:...; data:... *)
tipo // declaração de tipos
tipmat = matriz[1..10,1..10] de realvar
mat1, mat2, matResult: tipmatQtd, opção, linha, coluna: inteiro
inicio
repita // escolha da quantidade de elementos
escreva (‘Informe a quantidade de elementos nas linhas e colunas – deve variar de 2 a 10’)
leia (qtd)se (qtd < 2) ou qtd > 10 então
escreva (‘Valor fora do escopo – repita’)até que (qtd >= 2) e (qtd <= 10)
63
Repita // início do menuescreva (‘Digite 1 para informar os dados da
primeira matriz’)escreva (‘Digite 2 para informar os dados da
segunda matriz’)escreva (‘Digite 3 para somar as matrizes’)escreva (‘Digite 4 para subtrair a segunda da
primeira’)escreva (‘Digite 5 para multiplicar as
matrizes’)escreva (‘Digite 6 para achar a transposta da
primeira’)escreva (‘Digite 7 para sair do programa’)leia (opcao)
64
caso opcao seja // para testar as várias opções
1: início // para incluir os dados na 1a matriz
para linha variando de 1 a qtd faça
para coluna variando de 1 a qtd faça
inicio
(* orientar o usuário*)
leia (mat1[linha,coluna])
fim
(* apresentar a mat1 em forma matricial *)
fim // fim do caso 1
2: início // para incluir os dados na 2a matriz
para linha variando de 1 a qtd faça
para coluna variando de 1 a qtd faça
inicio
(* orientar o usuário*)
leia (mat2[linha,coluna])
fim
(* apresentar a mat2 em forma matricial *)
fim // fim do caso 2
65
3:inicio // para somar as duas matrizes
para linha variando de 1 a qtd façapara coluna variando de 1 a qtd faça
matResult[linha,coluna] mat1[linha,coluna] + mat2[linha,coluna]
(* apresentar matriz result *)fim // fim do caso 3
4:inicio // para subtrair a segunda da primeira
para linha variando de 1 a qtd façapara coluna variando de 1 a qtd faça
matResult[linha,coluna] mat1[linha,coluna] - mat2[linha,coluna]
(* apresentar matriz result *)fim // fim do caso 4
66
5:início // para multiplicar as duas raízes
..................
..................
(* apresentar a matResult *)
fim // fim do caso 5
6:início // para calcular a transposta da primeira
para linha variando de 1 a qtd façapara coluna variando de 1 a qtd faça
matResult[linha,coluna] mat1[coluna,linha](* apresentar a matResult *)
fim // fim do caso 6
Fim // fim do caso
até que opcao = 7
fim // fim do algoritmo
67
Observações sobre o algoritmo
• As entradas de dados para a 1a e 2a matrizes são iguais, muda somente a matriz destino das informações: fazer um só procedimento para os dois casos
• Após cada caso deve-se apresentar a matriz resultante, que pode ser mat1, mat2 ou matresult, mas são procedimentos idênticos: fazer um só procedimento para todos os casos
• O algoritmo ficou muito longo, o que dificulta perceber sua lógica: quebrar o algoritmo em partes menores
68
Modularização do problema de operações com matrizes
• Um módulo principal que apresente a lógica geral do programa: esse módulo deve permitir que o usuário escolha a quantidade de elementos de cada dimensão, e a seguir deve permitir que o usuário escolha uma opção até que o usuário escolha sair do programa. Para cada escolha, o módulo principal chama um outro módulo que implementa a opção selecionada.– Refinamento etapa por etapa
• Um módulo para a entrada de dados para as duas matrizes
• Um módulo para apresentar os dados das matrizes no formato matricial
69
Algoritmo operaMatriz
(* algoritmo modularizado para realizar operações sobre matrizes quadradas; responsável:...; data:... *)
tipo // declaração de tipos
tipMat = matriz[1..10,1..10] de real
var
qtd, linha, coluna, opcao: inteiro
mat1, mat2, matResult: tipMat
70
inicio
proQtd (qtd) (* escolher quantidade elementos *)
Repita
Opção funMenu (* função menu e escolha da opção *)Caso opcao seja
1: proDigDados (mat1, qtd) 2: proDigDados (mat2, qtd) 3: proSoSub (mat1, mat2, matResult, qtd, 1) 4: proSoSub (mat1, mat2, matResult, qtd, -1) 5: proMultiplicar (mat1, mat2, matResult, qtd) 6: proTransposta (mat1,matResult, qtd)
fimaté que opcao = 7
fim.
71
procedimento proQtd (var qt: inteiro)
(* procedimento para escolher a quantidade de elementos em cada dimensão da matriz *)
inicio
repita
escreva (‘Informe a quantidade de elementos nas linhas e colunas – deve variar de 2 a 10’)
leia (qt)
se (qt < 2) ou qt > 10 então
escreva (‘Valor fora do escopo – repita’)até que (qt >= 2) e (qt <= 10)
fim
72
função funMenu (): inteiro(* função para apresentar o menu e optar*)var op: inteiroInicio
repita escreva (‘Digite 1 para informar os dados da primeira matriz’) escreva (‘Digite 2 para informar os dados da segunda matriz’) escreva (‘Digite 3 para somar as matrizes’) escreva (‘Digite 4 para subtrair a segunda da primeira’) escreva (‘Digite 5 para multiplicar as matrizes’) escreva (‘Digite 6 para achar a transposta da primeira’) escreva (‘Digite 7 para sair do programa’) leia (op) Se (op < 1) ou (op > 7) então escreva(‘Opção inválida. Refaça’)
até que (op >= 1) e (op <= 7)funMenu ← op
fim
73
procedimento proDigDados (var matDig: tipMat; qtDig: inteiro)
(* procedimento para digitar os dados *)var
lin, col: inteiroinicio
para lin variando de 1 a qtDig faça para col variando de 1 a qtDig faça
(* orientar *)leia (matDig[lin,col])
proListarMat (matDig, qtDig)fim
74
procedimento proSoSub (mat1SS, mat2SS: tipMat; var matRSS:tipMat; qtdSS, sinal: inteiro)
(*procedimento para somar e subtrair matrizes *)
var
liSS, coSS: inteiro
inicio
para liSS variando de 1 a qtdSS faça para coSS variando de 1 a qtdSS faça
matRSS[liSS,coSS] mat1SS[liSS,coSS] +
(sinal * mat2SS[liSS,coSS])
proListarMat (matRSS, qtdSS)
fim
75
procedimento proMultiplicar (mat1M, mat2M: tipMat; var matRM:tipMat; qtdM: inteiro)
(*procedimento para multiplicar matrizes *)
var
liM, coM, indice: inteiroinicio
para liM variando de 1 a qtdM faça
inicio para coM variando de 1 a qtdM faça
inicio MatRM[liM,coM] 0 Para indice variando de 1 a qtdM faça matRM[liM,coM] matRM[liM,coM] + mat1M[liM,indice] * mat2M[indice,coM])Fim fim
proListarMat (matRM, qtdM)
fim
76
procedimento proTransposta (matT: tipMat; var matR:tipMat; qtdT: inteiro)
(*procedimento para achar a transposta da 1a *)
var
liT, coT: inteiro
inicio
para liT variando de 1 a qtdT faça para coT variando de 1 a qtdT faça
matR[liT,coT] matT[coT,liT]
proListarMat (matRSS, qtdSS)
fim
77
procedimento proListar (matLis: tipMat; qtdLis: inteiro)
(*procedimento para listar a matriz em forma matricial *)
var
liLis, coLis: inteiro
inicio
para liLis variando de 1 a qtdLis faça
inicio
para coLis variando de 1 a qtdLis façaEscreva (matLis[liLis,coLis] (* Pule uma linha *)
fim
fim
78
opcao
operaMatriz
proQTD
proListarMat
proDigDados proSoSub proMultiplicar proTransposta
79
Tratamento de erro
As linguagens verificam a ocorrência de erros em tempo de execução, e executam suas rotinas de tratamento de erro.
Algumas linguagens permitem que o usuário desabilite a rotina padrão de tratamento de erro e faça sua própria rotina de tratamento de erro.
Ao terminar de executar um comando de entrada ou saída de dados, sempre é gerado um código de erro, que será zero se não houve erro, e diferente de zero se houve erro, e esse valor será o código de erro
80
Tratamento de erro padrão em E/S
Exemplo para comando de leitura de teclado: leia (variável) // pode ser mais de uma variável Rotina da linguagem verifica o que foi solicitado e habilita o teclado Usuário digita no teclado um valor e conclui a entrada de dados Rotina da linguagem verifica se o comando foi executado com êxito e se o
valor digitado é compatível com o tipo da variável, e atualiza um parâmetro interno com o resultado dessa verificação de erro:
Se não houve erro ativa esse parâmetro interno para zero e coloca o valor digitado na variável definida no comando;
Se houve erro ativa esse parâmetro interno para um valor maior que zero, que indicará o tipo de erro que ocorreu, e poderá colocar qualquer lixo na variável definida no comando ou não colocar nada.
Se houve erro, a rotina da linguagem chama uma rotina padrão de tratamento de erro, que poderá terminar a execução do programa abruptamente.
Por programação poderá ser evitado que no caso de erro seja chamada a rotina padrão de tratamento de erro, e ser criada uma outra rotina pelo programador.
81
Tratamento de erro programado
Se no programa há uma leitura para uma variável numérica e o usuário digita uma tecla não numérica, este erro poderá parar a execução do programa, fazendo o usuário perder todo seu trabalho até o momento.
Solução: o programador desabilita a rotina da linguagem de tratamento padrão de erro e faz uma rotina especial de tratamento de erro que avisa ao usuário de seu erro, e permite que ele refaça a digitação, sem interromper o programa.
82
Exemplo em Pascal
program ...var numero: integer;...begin...
repeat // repetir os comandos abaixowriteln(‘Informe um valor numérico’);{$I-} // para desativar a rotina padrão de tratamento de erroreadln(numero);{$I+} // para ativar a rotina padrão de tratamento de erro
until ioresult = 0 { até que o comando tenha sido executado sem erro }
83
Rotinas padronizadas (proposta)
Toda vez em que há entrada de dados é necessário: Orientar o usuário do que deve ser feito Testar se houve erro de execução e neste caso
executar rotina apropriada de tratamento de erro Testar se os valores digitados estão dentro do
escopo dos valores permitidos Informar adequadamente no caso de erros Repetir a entrada de dados até que os dados
estejam corretos
84
Rotina para orientar, digitar e verificar variáveis inteiras
Este procedimento tem três parâmetros passados por valor: MensInt: a mensagem para orientar o usuário MaxInt: o valor máximo permitido MinInt: o valor mínimo permitido
E um parâmetro passado por referência: ValInt para retornar o valor digitado
85
procedure digInt(mensInt: string; maxInt, minInt: integer; var valInt:integer);
(* procedimento para orientar o usuário, permitir que ele digite um valor inteiro, testar se houve erro e testar se o valor está dentro do escopo de valores aceitos para a variável; responsável: ...; data:...*)
var
erro: integer; // variável para o código de erro
86
Begin
repeat
writeln (mensInt);
{$I-} // para desativar rotina padrão de tratamento de erro
readln (valInt);
{$I+} // para reativar a rotina padrão de tratamento de erro
erro := 1; // para fazer todos os testes
if ioresult <> 0 then
writeln ('O valor digitado não é um inteiro. Digite novamente')
else if (valInt > maxInt) then
writeln(‘O valor digitado é maior que o valor máximo permitido. Digite novamente’)
Else if (valInt < minInt) then
writeln((‘O valor digitado é menor que o valor mínimo permitido. Digite novamente’)
Else erro := 0; // para aceitar o valor digitado após passar os testesuntil erro = 0;
end;
87
Rotina para orientar, digitar e verificar variáveis reais
Este procedimento tem tres parâmetros passados por valor: MensReal: a mensagem para orientar o usuário MaxReal: o valor máximo permitido MinReal: o valor mínimo permitido
E um parâmetro passado por referência: ValReal para retornar o valor digitado
88
procedure digReal(mensReal: string; maxReal, minReal: real; var valReal:real);
(* procedimento para orientar o usuário, permitir que ele digite um valor real, testar se houve erro e testar se o valor está dentro do escopo de valores aceitos para a variável; responsável: ...; data:...*)
var
erro: integer; // variável para o código de erro
89
begin
repeat
writeln (mensReal);
{$I-} // para desativar rotina padrão de tratamento de erro
readln (valReal);
{$I+} // para reativar a rotina padrão de tratamento de erro
erro := 1; // para fazer todos os testes
if ioresilt <> 0 then
writeln ('O valor digitado não é um real. Digite novamente')
else if (valReal > maxReal) then
writeln(‘O valor digitado é maior que o maior valor permitido. Digite novamente’)
else if (valReal < MinReal) then
writeln(‘O valor digitado é menor que o menor valor permitido. Digite novamente’)
Else erro := 0; // para aceitar o valor digitado após passar os testesuntil erro = 0;
end.
90
Rotina para orientar, digitar e verificar variáveis string
Este procedimento tem tres parâmetros passados por valor: MensStr: a mensagem para orientar o usuário MaxStr: o comprimento máximo permitido MinStr: o comprimento mínimo permitido
E um parâmetro passado por referência: ValStr para retornar o valor digitado
91
procedure digStr(mensStr: string; maxStr, minStr: integer; var valStr:string);
(* procedimento para orientar o usuário, permitir que ele digite um valor string e testar se o valor está dentro do escopo de valores aceitos para a variável; responsável: ...; data:...*)
var
tamanho: integer; // para conter o comprimento da variável digitada
begin
repeat
writeln (mensStr);
readln (valStr);
tamanho := length (valStr);
if (tamanho > maxStr) then
writeln ('Valor com comprimento maior que o maior comprimento permitido. Digite novamente');
else if (tamanho < minStr)
writeln ('Valor com comprimento menor que o menor comprimento permitido. Digite novamente');
until (tamanho <= maxStr) and (tamanho >= minStr);
end.
92
Reutilização de código
Reutilização de código é utilizar um código já desenvolvido, evitando-se “reinventar a roda”. Procedimentos e funções muito usados podem ser
guardados em uma biblioteca, já compilados. Para reutilizá-los basta em um programa informar, através de uma cláusula, a biblioteca que será utilizada, e todos os procedimentos e funções desta biblioteca estarão disponíveis para reutilização no programa.
Deve-se colocar em bibliotecas módulos que possam ser utilizados em muitos outros programas sem a necessidade de qualquer alteração no código.
93
Unit Em Pascal as bibliotecas são definidas como units. A unit é um código Pascal que define procedimentos e
funções, ou mesmo declarações de constantes, tipos ou variáveis, que podem ser reutilizados.
A unit segue a sintaxe do Pascal. O compilador traduz a unit para um código binário não
executável. A unit é dividida em duas partes:
Interface: onde estão declarados os procedimentos e funções, assim como outras declarações, que podem ser acessados pelos programas que utilizam a unit;
Implementation: onde é colocado o código Pascal que implementa os procedimentos e funções declarados na interface; pode ter outras declarações internas à unit.
94
unit <identificador da unit>; (* prólogo com objetivo, responsável, data ... *) Interface
Declarações de incluir, const, type, var Declarações de procedimentos e funções:
Procedure <id do procedimento1> (<lista de parâmetros1>); Function <id da função2> (<lista parâmetros2): <tipo função>;
Implementation Declarações de incluir, const, type, var Código completo dos procedimentos e funções:
Procedure <id do procedimento1> (<lista de parâmetros1>); (* prólogo com objetivo, data, responsável, ...*) Declarações de , const, type, var, outros procedimentos ou funções Begin // início dos comandos
Comandos do procedimento End; ...
[ begin Código de execução inicial ]
end.
95
Exemplo de unit
Unit com os procedimentos padronizados vistos antes para a digitação de três tipos de dados
O nome da unit será digDados
96
Unit digDados;
(* biblioteca com rotinas para orientar e validar a digitação de três tipos de dados; responsável: fulano; data: 17/10/2008 *)
interface
procedure digInt(mensInt: string; maxInt, minInt: integer; var valInt:integer);
procedure digReal(mensReal: string; maxReal, minReal: real; var valReal:real);
procedure digStr(mensStr: string; maxStr, minStr: integer; var valStr:string);
97
implementation
procedure digInt(mensInt: string; maxInt, minInt: integer; var valInt:integer);
(* procedimento para orientar e validar inteiro; responsável: ...; data:...*)
Var
erro: integer; // variável para o código de erro
begin
repeat
writeln (mensInt);
{$I-} // para desativar rotina padrão de tratamento de erro
readln (valInt);
{$I+} // para reativar a rotina padrão de tratamento de erro
erro := 1; // para fazer todos os testes
if ioresult <> 0 then
writeln ('O valor digitado não é um inteiro. Digite novamente')
else if (valInt > maxInt) then
writeln(‘O valor digitado é maior que o valor máximo permitido. Digite novamente’)
else if (valInt < minInt) then
writeln((‘O valor digitado é menor que o valor mínimo permitido. Digite novamente’)
else erro := 0; // para aceitar o valor digitado após passar os testesuntil erro = 0;
end;
98
procedure digReal(mensReal: string; maxReal, minReal: real; var valReal:real);
(* procedimento para orientar, validar, ...; responsável: ...; data:...*)
var
erro: integer; // variável para o código de erro
begin
Repeat
writeln (mensReal);
{$I-} // para desativar rotina padrão de tratamento de erro
readln (valReal);
{$I+} // para reativar a rotina padrão de tratamento de erro
erro := 1; // para fazer todos os testes
if ioresult <> 0 then
writeln ('O valor digitado não é um real. Digite novamente')
else if (valReal > maxReal) then
writeln(‘O valor digitado é maior que o maior valor permitido. Digite novamente’)
else if (valReal < MinReal) then
writeln(‘O valor digitado é menor que o menor valor permitido. Digite novamente’)
else erro := 0; // para aceitar o valor digitado após passar os testesuntil erro = 0;
end;
99
procedure digStr(mensStr: string; maxStr, minStr: integer; var valStr:string);
(* procedimento para orientar... ; responsável: ...; data:...*)
var
tamanho: integer; // para conter o comprimento da variável digitada
begin
repeat
writeln (mensStr);
readln (valStr);
tamanho := length (valStr);
if (tamanho > maxStr) then
writeln ('Valor com comprimento maior que o maior comprimento permitido. Digite novamente');
else if (tamanho < minStr) then
writeln ('Valor com comprimento menor que o menor comprimento permitido. Digite novamente');
until (tamanho <= maxStr) and (tamanho >= minStr);
end;
end.
100
Função Confirmar
Em muitos programas temos de confirmar uma opção com S ou N. Vamos fazer então uma função que retorna a escolha realizada pelo usuário.
// esta função exige o uso da unit crt
Function funConfirmar(mens: string): char;
(* Função para confirmar ou não uma opção do usuário; data: ...; Responsável: ... *)
Var
Carac: char;
Begin
repeat Writeln(mens,’ Confirme ou não sua opção com S ou N);
Carac := upcase(readkey);
If (carac <> ‘S’) and (carac <> ‘N’)
Then Writeln(‘Opção inválida. Tente novamente’);
Until (carac = ‘S’) or (carac = ‘N’);
funConfirmar := carac;
End;