Sei sulla pagina 1di 63

Algoritmos e Programação Computacional

Aula 01 - 02/mar/2020

Wilson H. Hirota

Universidade Federal de São Paulo

wilson.hirota@unifesp.br
Apresentação do Curso
• Objetivos Gerais
◦ Capacitar o aluno na elaboração de algoritmos computacionais e
técnicas elementares de programação computacional

• Objetivos especı́ficos
◦ Apresentar os principais conceitos de algoritmos computacionais e
linguagens de programação
◦ Capacitar os alunos a utilizarem as ferramentas disponı́veis para as
demais unidades curriculares do curso

• Metodologia
◦ Aulas teóricas e práticas com resolução e discussão de exercı́cios

2 / 63
Datas

março maio
abril
D S T Q Q S S D S T Q Q S S
D S T Q Q S S 1 2
1 2 3 4 5 6 7
1 2 3 4 3 4 5 6 7 8 9
8 9 10 11 12 13 14
5 6 7 8 9 10 11 10 11 12 13 14 15 16
15 16 17 18 19 20 21
12 13 14 15 16 17 18 17 18 19 20 21 22 23
22 23 24 25 26 27 28
19 20 21 22 23 24 25 24 25 26 27 28 29 30
29 30 31
26 27 28 29 30 31

junho julho

D S T Q Q S S D S T Q Q S S
1 2 3 4 5 6 1 2 3 4 Aulas Práticas
7 8 9 10 11 12 13 5 6 7 8 9 10 11
14 15 16 17 18 19 20 12 13 14 15 16 17 18 04/mai - Laboratório 01
19 20 21 22 23 24 25 01/jun - Laboratório 02
21 22 23 24 25 26 27
26 27 28 29 30 31 22/jun - Laboratório 03
28 29 30

Laboratório: salas de informática - Unidade Eldorado

3 / 63
Datas
maio
março
abril D S T Q Q S S
D S T Q Q S S 1 2
D S T Q Q S S
1 2 3 4 5 6 7 3 4 5 6 7 8 9
1 2 3 4
8 9 10 11 12 13 14 10 11 12 13 14 15 16
5 6 7 8 9 10 11
15 16 17 18 19 20 21 17 18 19 20 21 22 23
12 13 14 15 16 17 18
22 23 24 25 26 27 28 24 25 26 27 28 29 30
19 20 21 22 23 24 25
29 30 31 31
26 27 28 29 30

junho julho

D S T Q Q S S D S T Q Q S S
Provas
1 2 3 4 5 6 1 2 3 4
7 8 9 10 11 12 13 5 6 7 8 9 10 11
11/mai - Prova 01
14 15 16 17 18 19 20 12 13 14 15 16 17 18
29/jun - Prova 02
21 22 23 24 25 26 27 19 20 21 22 23 24 25 06/jul - Substitutiva
28 29 30 26 27 28 29 30 31 13/jul - Exame

1. Prova de conteúdo acumulativo 2. Prova substitutiva fechada

4 / 63
Critérios de avaliação e aprovação

M.Ex.: Média aritmética


dos Exercı́cios (Aula
Início M.F.: Média Final
Prática)
NEx.: Nota do Exame
M.T.: Média dos Trabalhos
T1 + T2 + 2 × T3 Calcular
M.T. = Frequência M.Ex.: Média dos Exercícios
4 M.P.: Média das Provas
NÃO
P1 + 2 × P2 Freq. ≥75%
M.P. =
3 SIM
Calcular
média
Média = 0,2 x M.T. + 0,1 x M.Ex + 0,7 x M.P.

Contato NÃO NÃO


Média ≥6 Média ≥3
Laboratório de Engenha- SIM SIM
ria de Controle Ambiental M. F. = (Média +
(LENCA) M. F. = Média EXAME
NEx)/2

Unidade José de Alencar, SIM NÃO


3o andar APROVADO M.F.≥6 REPROVADO

wilson.hirota@unifesp.br
FIM

5 / 63
Cuidados / Dicas
• O grande problema apresentado pelos estudantes não são as
linguagens de programação ou a descrição de algoritmos, mas sim a
dificuldade em abstrair e descrever as soluções do problema
contando apenas com poucas e simples estruturas

• O que deve ser percebido é que um novo problema de programação


pode ser gerado a partir de um já existente, alterando-se apenas
poucos elementos de seu enunciado

Cuidado
Dessa forma, é um erro decorar as soluções, pois podem não
servir para outros problemas, que com certeza serão diferentes

6 / 63
Cuidados / Dicas
• O que deve ser procurado é o entendimento de como foi obtida uma
solução, armazená-la na memória e, então, utilizar essa experiência
adaptando-a a outras situações, por analogia, generalização ou
especialização

• A grande dica é que um problema pode ser diferente de outro, mas


consegue-se aproveitar grande parte da experiência obtida em
problemas passados em novos desafios

• Em programação, não existe uma “fórmula mágica” para resolver


problemas. De qualquer forma, apresenta-se a seguir um conjunto de
dicas que podem ser utilizadas durante o processo de raciocı́nio
empregado na resolução de problemas

7 / 63
Cuidados / Dicas
• Ao se deparar com um problema novo, tente entendê-lo. Para
auxiliar, pense no seguinte:

◦ O que se deve descobrir ou calcular? Qual o objetivo?

◦ Quais são os dados disponı́veis? São suficientes?

◦ Quais as condições necessárias e suficientes para resolver o problema?

◦ Faça um esboço informal de como ligar os dados com as condições

◦ Se possı́vel, modele o problema de forma matemática

8 / 63
Cuidados / Dicas
• Crie um plano com a solução

◦ Consulte sua memória e verifique se você já resolveu algum problema


similar. A sua solução pode ser aproveitada: i) por analogia, quando o
enunciado for diferente, mas a estrutura em si guarda similaridades; ii)
por generalização quando se tem uma solução particular e deseja uma
solução geral; iii) por especialização, quando se conhece alguma
solução geral que serve como base para uma particular

◦ Verifique se é necessário introduzir algum elemento novo no problema,


como um problema auxiliar

◦ Se o problema for muito complicado, tente quebrá-lo em partes menores


e solucionar essas partes

9 / 63
Cuidados / Dicas
• Formalize a solução

◦ Crie um algoritmo informal com passos que resolvam o problema

◦ Verifique se cada passo desse algoritmo está correto

◦ Escreva um algoritmo formalizado por meio de um fluxograma ou


pseudocódigo

10 / 63
Cuidados / Dicas
• Examine os resultados

◦ Teste o algoritmo com diversos dados de entrada e verifique os


resultados (simulação)

◦ Se o algoritmo não gerou resultado algum, o problema está na sua


sintaxe e nos comandos utilizados. Volte e tente encontrar o erro

◦ Se o algoritmo gerou resultados, estes estão corretos? Analise sua


consistência

◦ Se não estão corretos, alguma condição, operação ou ordem das


operações está incorreta. Volte e tente encontrar o erro

11 / 63
Introdução
• Um programa de computador é um conjunto de instruções e
dados criado por um ser humano que, ao ser executado por alguma
máquina, cumpre um determinado objetivo
• Os dados são organizados em um computador de acordo com sua
representação binária, isto é, sequências de 0s e 1s. Portanto, a
principal tarefa do computador é extrair as informações resultantes
das execuções das intruções de um programa 1
• Parte dos dados processados durante a execução de um software é
fornecida pelo ser humano (ou outra máquina) e denominada dados
de entrada. Por outro lado, os dados de saı́da são aqueles
fornecidos ao ser humano (ou outra máquina) após o processamento
dos dados de entrada
• O software deve ser encarado como um produto de um processo
bem-definido e controlado de engenharia
1 Dado é um valor qualquer armazenado em um computador enquanto a informação representa a
interpretação desse dado, ou seja, qual o seu significado

12 / 63
Algoritmos e Lógica de Programação
• O estudo de algoritmos e de lógica de programação é essencial no
contexto do processo de criação de um software, pois permite
verificar, em um nı́vel maior de abstração, se o software está correto
ou não; permite, inclusive, averigar se o software atenderá às
especificações originalmente propostas. Assim, evita-se partir
diretamente para a etapa de implementação, o que poderá ocasionar
mais erros no produto final
• Muitas definições podem ser dadas à palavra algoritmo. Atualmente,
tem-se associado algoritmo à computação, mas este não é um termo
restrito à computação ou que tenha nascido com ela
• Na realidade, a palavra algoritmo vem do nome do matemático
iraniano Abu Abdullah Mohammad Ibn Musa al-Khawarizmi, nascido
em Khawarizm, ao sul do mar Aral, que viveu no século XVII.
Também é considerado o fundador da álgebra, cujo nome derivou de
seu livro Al-Jabr wa-al-Muqabilah

13 / 63
Algoritmos e Lógica de Programação
• O termo algoritmo também é utilizado em outras áreas, como
engenharia, administração, entre outras. Vejamos algumas definições
de algoritmo

Definição 1
1. Mat. Processo de cálculo ou de resolução de um grupo de problemas
semelhantes, em que se estipulam, com generalidade e sem restrições, re-
gras formais para a obtenção do resultado ou da solução do problema. 2.
Inform. Conjunto de regras e operações bem definidas e ordenadas, desti-
nadas à solução de um problema ou de uma classe de problemas, em um
número finito de etapas.

14 / 63
Algoritmos e Lógica de Programação
• O termo algoritmo também é utilizado em outras áreas, como
engenharia, administração, entre outras. Vejamos algumas definições
de algoritmo

Definição 2
Sequência não ambı́gua e ordenada de instruções destinada à solução de
um problema, ou uma classe de problemas, em um número finito de passos.

• Em outras palavras, um algoritmo não representa necessariamente um


programa de computador, mas o caminho de solução para um
problema
• Dessa forma, uma receita de bolo é um exemplo de um algoritmo, pois
descreve as regras necessárias para a conclusão de um objetivo: a
preparação de um bolo. Se essas instruções tiverem sua ordem
trocada ou a quantidade dos ingredientes alterada, o resultado vai
divergir do original
15 / 63
Algoritmos e Lógica de Programação
• Das definições expostas anteriormente, pode-se extrair as seguintes
caracterı́sticas evidentes
◦ Um algoritmo representa uma sequência de regras.
◦ Essas regras devem ser executadas em uma ordem preestabelecida.
◦ Cada algoritmo possui um conjunto finito de regras.
◦ Essas regras devem possuir um significado e ser formalizadas segundo
alguma convenção.
• Todo algoritmo possui as seguintes propriedades
◦ Valores de entrada: todo algoritmo deve possuir zero, uma ou mais
entradas de dados. A receita de bolo representa um algoritmo que
possui zero entradas, pois seu algoritmo opera com quantidades fixas de
ingredientes.
◦ Valores de saı́da: todo algoritmo possui uma ou mais saı́das, que
simboliza(m) seu(s) resultado(s). Por exemplo, a saı́da da receita de
bolo é o próprio bolo.

16 / 63
Algoritmos e Lógica de Programação
• Todo algoritmo possui as seguintes propriedades
◦ Finitude: todo algoritmo possui um inı́cio, meio e fim. Portanto, todo
algoritmo deve ser finito, isto é, deve possuir um inı́cio e um conjunto de
passos que, ao serem executados, levarão sempre ao seu término,
executando a tarefa a que se propõe. Deve-se dedicar uma atenção
especial a essa propriedade. Muitas vezes, por erros de lógica, pode-se
criar um algoritmo que nunca chegará a um resultado (loop infinito).
◦ Passos elementares: um algoritmo computacional deve ser explicitado
por meio de operações elementares (operações matemáticas e
comparações)
◦ Correção: um algoritmo deve ser correto, isto é, deve permitir que,
com sua execução, se chegue à(s) saı́da(s) com resultados coerentes com
a(s) entrada(s). Para saber se um algoritmo está correto ou não, deve-se
realizar testes com diversos valores de entrada (Simulação), cujos
valores já se conhece a priori e, então, comparar esses resultados com os
valores produzidos pelo algoritmo em questão

17 / 63
Algoritmos e Lógica de Programação
• O processo de criação de um algoritmo é uma tarefa
essencialmente intelectual e envolve os seguintes passos:
◦ Análise e sı́ntese do problema: na fase de análise, o problema é
entendido de forma que se descubra o que deve ser solucionado, quais
são os dados necessários e as condições para resolvê-lo. Nessa fase, faz-se
uso direto de processos de abstração, o que significa elaborar modelos
mentais do problema em questão e do encaminhamento de sua solução.
Portanto, como resultado dessa fase, tem-se a elaboração de um plano
de ação. Na fase de sı́ntese, executa-se o plano definido na etapa de
análise, representando o passo-a-passo por meio de um algoritmo. É
importante que a solução seja verificada e comprovada, por meio da
execução do algoritmo. Essa execução é feita percorrendo-se o algoritmo
do seu inı́cio até o seu fim, e verificando, a cada passo, se o resultado
esperado foi obtido. Caso tenha sido encontrada alguma discrepância,
deve-se procurar saber qual foi sua causa e eventualmente analisar
novamente o problema, repetindo-se assim esse ciclo até que a solução
tenha sido obtida
18 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Modelagem: nas ciências exatas, o uso da linguagem matemática é
fundamental, principalmente pela eliminação de duplos sentidos que
acontecessem nessa prática. O mesmo ocorre na computação, com o
emprego de linguagens de descrição de algoritmos (como fluxogramas) e
de linguagens de programação (como linguagem C/C++). Como um
exemplo de modelagem, considere o seguinte problema:

Compraram-se 30 canetas iguais, que foram pagas com uma nota de R$


100,00, obtendo-se R$ 67,00 como troco. Quanto custou cada caneta?

19 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Modelagem
Compraram-se 30 canetas iguais, que foram pagas com uma nota de R$
100,00, obtendo-se R$ 67,00 como troco. Quanto custou cada caneta?

• Este problema é bem simples; porém como pode ser mostrada a solução?
Uma possı́vel resposta:

Se eu tinha R$ 100,00 e recebi como troco R$ 67,00, o custo total das


canetas é a diferença entre os R$ 100,00 que eu tinha e os R$ 67,00
do troco. Ora, isto vale R$ 33,00; portanto, esse valor foi o total pago
pelas canetas. Para saber quanto custou cada caneta, basta dividir os
R$ 33,00 por 30. Assim, cada caneta custou o equivalente a R$ 1,10.

20 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Modelagem
• Esse raciocı́nio é matematicamente demonstrado por: seja x o custo de
cada caneta, então quanto gastei = 30x. Como quanto gastei + troco = R$
100,00, tem-se:
30x + 67 = 100
30x = 100 − 67
30x = 33
x = 33/30
x = 1.1
• De uma forma mais curta e universalmente entendida, pode-se também
dizer que o caminho pode ser obtido pelo seguinte algoritmo:
INICIO
Pegar os valores 30, 100 e 67
Subtrair 67 de 100 e dividir o resultado por 30
Mostrar o resultado final
FIM

21 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Modelagem
• Deve-se observar que o algoritmo acima resolve apenas uma instância
particular do problema. Para solucionar um caso geral, tem-se o
seguinte:
Compraram-se N canetas iguais, que foram pagas com uma nota de Z
reais, obtendo-se Y reais como troco. Quanto custou cada caneta?
• Nesse caso, basta que sejam fornecidos os valores das variáveis N , Z e Y
que a solução do problema é a mesma que a anterior e seu algoritmo pode
ser escrito da seguinte forma:

INICIO
Ler os valores de N, Y e Z
Subtrair Y de Z e dividir o resultado por N
Mostrar o resultado final
FIM

22 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Modelagem
INICIO
Ler os valores de N, Y e Z
Subtrair Y de Z e dividir o resultado por N
Mostrar o resultado final
FIM

◦ No entanto, o algoritmo acima tem uma série de restrições:


• O que acontece se alguém pensar em comprar zero canetas, ou -3 canetas?
Faz algum sentido?

• Suponha que alguém execute o algoritmo com os seguintes dados N = 10,


Z = 10 e Y = 15. O valor de cada caneta será de -R$ 0.50. Isso faz sentido?

23 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Então, para que a solução geral seja realmente consistente, devemos
levar em consideração as seguintes condições:

• Que o valor pago pelas canetas seja sempre maior que o troco recebido
(Z > Y )

• Que o valor pago e a quantidade de canetas seja sempre maiores que zero
(Z > 0 e N > 0)

• Que o troco seja maior ou igual a zero (Y ≥ 0)

24 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Se essas condições não forem todas verdadeiras, então, o algoritmo deve
terminar sinalizando, de alguma forma, a razão de seu fracasso.

INICIO
Ler os valores de N, Y e Z
Se Z > Y e N > 0 e Y ≥ 0 e Z > 0 Ent~
ao
Subtrair Y de Z e dividir o resultado por N
Mostrar o resultado final
Sen~
ao
Exibir a mensagem: "Erro: os valores s~ ao inconsistentes"
Fim Se
FIM

25 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Lógica em Programação
• Lógica é uma área da Matemática cujo objetivo é investigar a veracidade
de suas proposições

• Considere, por exemplo, o caso em que temos as seguintes proposições

1. Se estiver chovendo, eu pegarei meu guarda-chuva


2. Está chovendo

• O que se conclui dessas duas proposições? Parece que a conclusão óbvia é:
”eu pegarei o meu guarda-chuva”

• Essa conclusão seguiu o fato de que existe uma implicação lógica na


primeira proposição, a qual afirma que ”se estiver chovendo”implica ”eu
pegarei o meu guarda-chuva”. Essa implicação age como uma
”regra”, que conduz à dedução do fato

26 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Lógica em Programação
• ...e se as proposições fossem:

1. Se estiver chovendo, eu pegarei o meu guarda-chuva


2. Eu peguei o meu guarda-chuva

• O que se conclui? A conclusão poderia ser: ”Não se pode afirmar com


precisão que está chovendo só porque você pegou seu guarda-chuva, mas é
plausı́vel que esteja chovendo”

• Esses dois exemplos fornecem uma ideia, embora simplificada, do que a


lógica se preocupa em estudar

• Toda lógica proposta também deve ser formalizada em elementos


sintáticos (especificam como escrever suas proposições) e elementos
semânticos (avaliam o significado das proposições)

27 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Lógica em Programação
• No caso da lógica clássica, o resultado da avaliação de suas proposições
pode ser somente um entre dois valores: VERDADEIRO ou FALSO

O papel da lógica em programação


O papel da lógica em programação está relacionado com a correta sequência de ins-
truções que devem ser definidas para que o programa atinja seu objetivo. Serve como
instrumento para a verificação do programa escrito, provando se este está correto ou
não.

• Em um algoritmo em execução, o valor das suas variáveis a cada instante


representa o seu estado. Com a execução dessas instruções, esse estado vai
sendo alterado
• Um algoritmo correto é aquele que, a partir de um estado inicial de
suas variáveis, consegue, com a execução de suas instruções, chegar a um
estado final, no qual os valores das variáveis estão de acordo com a
solução esperada
28 / 63
Algoritmos e Lógica de Programação
• Processo de criação de um algoritmo
◦ Lógica em Programação
• Voltando ao algoritmo geral para a solução do problema das canetas,
podemos conferir sua solução analisando a lógica empregada em cada passo:

Ler os valores de N, Y e Z → Nesse ponto temos três valores quaisquer de N, Y e Z


Se Z > Y e N > 0 e Y ≥ 0 e Z > 0 Ent~ ao → Nesse ponto, garante-se que Z > Y, N
> 0, Y ≥ 0 e Z > 0
Subtrair Y de Z e dividir o resultado por N → Como Z > Y, Y ≥ 0 e Z > 0
então Z - Y > 0 e sendo N > 0, o resultado existe e é maior que zero
Mostrar o resultado final → É exibido o resultado, que existe e é maior que zero
Sen~ ao
Exibir a mensagem: "Erro: os valores s~ ao inconsistentes" → Esse comando
é executado quando, pelo menos, uma das condições do problema não foi atendida.
Fim Se

29 / 63
Algoritmos e Lógica de Programação
• Estruturação de algoritmos
◦ Graças ao surgimento das linguagens de programação de alto nı́vel2 , as
linguagens de programação se afastaram da linguagem de máquina e se
aproximaram da ”lógica humana”.

Cuidado
Diferentemente da linguagem natural, a linguagem de programação é dirigida a
orientar uma máquina e não pessoas. Máquinas não podem tomar decisões com
base em premissas. Máquinas não podem escolher alternativas, mesmo que estas
pareçam óbvias a um ser humano. Máquinas não podem corrigir comandos mal
redigidos. Máquinas não podem descobrir a intenção do programador, mesmo
que ela seja (ou pelo menos pareça) clara no contexto.

2 As linguagens de alto nı́vel são independentes do processador em que serão executadas. Suas
caracterı́sticas principais são que seu código é mais elaborado, contemplando operações mais complexas e
mais próximas da ”lógica humana”. Para que possam ser processadas por um computador, os comandos da
linguagem precisarão ser traduzidos para a linguagem de máquina. Essa tradução é feita por meio de um
compilador ou de um interpretador.

30 / 63
Algoritmos e Lógica de Programação
• Estruturação de algoritmos
◦ Por isso, a linguagem de programação precisa ter algumas caracterı́sticas
que a linguagem natural não tem. Veja-as a seguir:
• Rigidez sintática: O compilador é um tradutor relativamente limitado,
que só consegue fazer as traduções sobre um idioma bastante limitado, com
construções muito bem definidas. Apesar de encontrarmos palavras
pertencentes à linguagem natural, elas não serão usadas com a mesma
liberdade

• Rigidez semântica: o computador definitivamente não pode lidar com


ambiguidades. Por isso não adianta o programador ter uma intenção se não
conseguir exprimi-la de forma exata. Podemos dizer que o computador é
um ótimo cumpridor de ordens, porém não tem idéia de quais ordens está
cumprindo, nem o contexto em que essas ações estão inseridas.
Diferentemente da linguagem de programação, a linguagem natural
apresenta ambiguidades. Por exemplo, considere a seguinte afirmação:

A criança ouviu o barulho da janela

31 / 63
Algoritmos e Lógica de Programação
• Estruturação de algoritmos

A criança ouviu o barulho da janela


◦ Essa afirmação curta pode ser interpretada de pelo menos três maneiras:
• A criança ouviu o barulho produzido pela janela
• A criança estava junto à janela e ouviu o barulho
• A criança ouviu o barulho que veio através da janela
◦ Uma máquina seria incapaz de interpretar o que realmente está
acontecendo, mesmo que o contexto pudesse ajudar. Por isso, a rigidez
semântica é tão crucial e consequentemente a linguagem natural não
pode ser utilizada como ferramenta para a construção de algoritmos
computacionais
◦ A segunda alternativa seria escrever o algoritmo diretamente na
linguagem de programação. Porém a rigidez sintática e semântica
tornam a escrita de algoritmos uma tarefa bastante difı́cil, pois as
pessoas não estão acostumadas a essas exigências para expressar ordens.
Muitas vezes, mesmo em linguagem natural, esta não é uma tarefa
trivial.
32 / 63
Algoritmos e Lógica de Programação
• Estruturação de algoritmos

Dilema
Chegamos a um dilema: a linguagem natural não é adequada porque não
tem rigidez sintática e semântica e a linguagem de programação não é ade-
quada justamente por ter essas caracterı́sticas. Parece claro que devemos
encontrar uma terceira alternativa para estruturar algoritmos computaci-
onais.

◦ Na realidade, já existem algumas alternativas. Duas delas serão


abordadas mais adiante: o fluxograma e o pseudocódigo

◦ Independentemente da estrutura, é importante formalizar a descrição


do algoritmo segundo alguma convenção, para que todos possam
entendê-lo da mesma forma

33 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Em primeiro lugar, é necessário definir um conjunto de regras que
regulem a escrita do algoritmo, isto é, regras de sintaxe

◦ Em segundo, é preciso estabelecer as regras que permitam interpretar


um algoritmo, que são as regras semânticas

◦ A sintaxe de um algoritmo resume-se nas regras para escrevê-lo


corretamente

◦ Em computação, as regras indicam quais são os tipos de comandos


que podem ser utilizados e também como neles escrever expressões

◦ As expressões de um comando em um algoritmo realizam algum tipo de


operação com os dados envolvidos, isto é, operam com valores e
resultam em outros valores que são usados pelo algoritmo

34 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Os tipos de comandos de um algoritmo são também denominados
estruturas de programação.

◦ Existem apenas três tipos de estruturas que podem ser utilizadas para
escrever qualquer programa:

• Estruturas sequenciais

• Estruturas de decisão

• Estruturas de repetição (laços ou loops)

35 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial
A Torre de Hanói é um quebra-cabeça que consiste em uma base com 3 a
5 pinos, em um dos quais são dispostos alguns discos empilhados de baixo para
cima por tamanho decrescente. O desafio consiste em transferir todos os discos
de um pino para outro qualquer, sob as restrições de que apenas um disco é
movido de cada vez, e em momento algum um disco maior pode ser colocado
sobre um disco menor. Um terceiro pino está disponı́vel para apoiar os discos
temporariamente.

36 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial

◦ Vamos supor que você tenha o seguinte problema:

Inicialmente têm-se 3 pinos, A, B e C, e no pino A repousam três discos


de diâmetros diferentes, em ordem decrescente por diâmetro. Deseja-se
transferir os 3 discos do pino A para o pino C, usando o pino B como pino
auxiliar. Queremos desenvolver um algoritmo que gere a sequência exata
de transferências de pino, disco a disco

37 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial
As únicas informações para resolver esse problema são os estados inicial e
final dos discos e as regras de movimento. Uma solução poderia ser a seguinte
sequencia de movimentos

Um possı́vel algoritmo para resolver o problema das Torres de Hanoi com 3 discos
INICIO
1. Mover disco 1 do pino A para o pino C
2. Mover disco 2 do pino A para o pino B
3. Mover disco 1 do pino C para o pino B
4. Mover disco 3 do pino A para o pino C
5. Mover disco 1 do pino B para o pino A
6. Mover disco 2 do pino B para o pino C
7. Mover disco 1 do pino A para o pino C
FIM

38 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial
Um possı́vel algoritmo para resolver o problema das Torres de Hanoi com 3 discos
INICIO
1. Mover disco 1 do pino A para o pino C
2. Mover disco 2 do pino A para o pino B
3. Mover disco 1 do pino C para o pino B
4. Mover disco 3 do pino A para o pino C
5. Mover disco 1 do pino B para o pino A
6. Mover disco 2 do pino B para o pino C
7. Mover disco 1 do pino A para o pino C
FIM

O algoritmo acima é um bom exemplo de estrutura sequencial, pois sua


execução é direta, imperativa, não havendo nenhum tipo de condição a ser
verificada e nenhum desvio em seu caminho

39 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial
Agora, considere o seguinte problema:

Inicialmente têm-se 3 pinos, A, B


e C, e no pino A repousam QUA-
TRO discos de diâmetros diferentes,
em ordem decrescente por diâmetro.
Deseja-se transferir os 4 discos do
pino A para o pino C, usando o pino
B como pino auxiliar. Queremos de-
senvolver um algoritmo que gere a
sequência exata de transferências de
pino, disco a disco

40 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial
Um possı́vel algoritmo para resolver o problema das Torres de Hanoi com 4 discos
INICIO
1. Mover disco 1 do pino A para o pino B
2. Mover disco 2 do pino A para o pino C
3. Mover disco 1 do pino B para o pino C
4. Mover disco 3 do pino A para o pino B
5. Mover disco 1 do pino C para o pino A
6. Mover disco 2 do pino C para o pino B
7. Mover disco 1 do pino A para o pino B
8. Mover disco 4 do pino A para o pino C
9. Mover disco 1 do pino B para o pino C
10. Mover disco 2 do pino B para o pino A
11. Mover disco 1 do pino C para o pino A
12. Mover disco 3 do pino B para o pino C
13. Mover disco 1 do pino A para o pino B
14. Mover disco 2 do pino A para o pino C
15. Mover disco 1 do pino B para o pino C
FIM

41 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial

Como essas soluções foram obtidas?

• Primeiro, é importante entender o enunciado do problema e as regras que


foram impostas. Dessa forma, não é possı́vel especificar os movimentos nos
quais uma peça que esteja abaixo de outra seja movida e nem mover mais
de uma peça por vez

• Segundo, é importante verificar a cada passo definido se a solução está se


aproximando do objetivo final

• Terceiro, o número de movimentos dobra cada vez que se acrescenta uma


nova peça. Portanto, a generalização desse algoritmo, na forma em que está
sendo descrito, é impraticável para grandes valores de n (número de
discos)
42 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Estrutura Sequencial

Por exemplo: Se n for igual a 64 discos, o número de movimentos


que deverão ser descritos será igual a, aproximadamente, 2, 0 × 1019 ,
ou seja, é humanamente impossı́vel listar todos os movimentos para
resolver o problema

• É possı́vel mostrar por Progressão Geométrica (e também pelo Princı́pio da


Indução) que existe uma relação matemática entre o número de discos do
problema (n) com o número mı́nimo de movimentos executados (m). Esta
relação é dada pela seguinte fórmula:

m(n) = 2n − 1
• Então, surge a seguinte pergunta: ... e se for considerado o mesmo
problema, porém, com n discos postados inicialmente na haste A, como
desenvolver um algoritmo que gere a sequência exata de transferências de
pino, disco a disco?
43 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Modularização / Recursão
• Se tivéssemos que resolver esse problema com a ajuda de métodos
convencionais, ficarı́amos preso na administração dos discos rapidamente.
Em vez disso, se atacarmos o problema com a recursão em mente, o
problema imediatamente se tornará mais resolúvel.

• Mover n discos pode ser visto em termos de mover apenas n − 1 (e daı́ a


recursão) discos da seguinte forma:

Mova n − 1 discos do pino A para o pino B, usando o pino C como área de manutenção
temporária

Mova o último disco (o maior) do pino A para o pino C

Mova os n−1 discos do pino B para o pino C, usando o pino A como área de manutenção
temporária

44 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo
◦ Exemplo 1: Torre de Hanói - Modularização / Recursão
1. Mova n−1 discos do pino A para o pino B, usando o pino C como área de manutenção
temporária
2. Mova o último disco (o maior) do pino A para o pino C
3. Mova os n − 1 discos do pino B para o pino C, usando o pino A como área de
manutenção temporária

• Essa solução funciona para qualquer valor de n tal que n ≥ 1. Apesar de ser
um algoritmo geral que resolve todos os casos para o problema das Torres
de Hanói, ainda existem algumas dificuldades nas sua forma de descrição:

i) Existe um tratamento informal dos comandos: por exemplo, o


computador não entende o significado da palavra mova

ii) As operações descritas são úteis para uma pessoa interpretar, mas não
para um máquina. É necessário modelar melhor o problema de forma que seja
facilmente traduzido para uma máquina

45 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Fluxogramas
Definição
Fluxograma: Inform. (fluxo+grama). 1. Diagrama para representação de um algo-
ritmo. 2. Representação gráfica, por sı́mbolos especiais, da definição, análise ou método
de solução de um problema

◦ Os fluxogramas apresentam os algoritmos de forma gráfica. São


formados por sı́mbolos gráficos que contêm as instruções a serem
executadas. Tais sı́mbolos gráficos são ligados por setas que indicam o
fluxo das ações

◦ Todo fluxograma deve possuir uma sintaxe e uma semântica


bem-definidas. A sintaxe de um fluxograma é definida pela forma
correta de empregar seus elementos, os quais são:
• sı́mbolos gráficos especı́ficos;
• expressões admissı́veis a serem escritas no interior dos sı́mbolos;
• sub-rotinas predefinidas que podem ser utilizadas nas expressões

46 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Fluxogramas

Sı́mbolo Uso
Terminador Representa a saı́da para ou a entrada do ambiente externo,
por exemplo, inı́cio ou fim do programa
Processo Representa a execução de uma operação que resulta na mu-
dança de valor, forma ou localização de uma informação ou
valor
Entrada/Saı́da Representa os dados, tanto de entrada como de saı́da, qual-
quer que seja o meio utilizado
Representa uma decisão ou um desvio tendo uma entrada;
Decis~
ao porém pode ter uma série de saı́das alternativas, uma única
das quais deverá ser ativada como consequência da avaliação
das condições internas do sı́mbolo. O resultado apropriado de
cada saı́da deverá ser escrito adjacente à linha, representando
o caminho respectivo.

47 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Fluxogramas
◦ Os fluxogramas possuem um grande apelo visual e aplicação no
entendimento de processos industriais, os quais são muito importantes
na formação e na vida prática do engenheiro

◦ De fato, a representação de algoritmos por meio de fluxogramas tem


uma série de vantagens como, por exemplo, a facilidade proporcionada
para a compreensão do funcionamento do algoritmo, mesmo para leigos

◦ Entretanto, a representação gráfica não é prática por uma série de


razões, dentre as quais podemos destacar duas:
• A correção de uma linha de pensamento pode implicar a reconstrução de
muitas instruções

• A construção de algoritmos mais complexos e longos pode se tornar


extremamente trabalhosa, ocupando várias páginas

48 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Fluxogramas
inicio

ler num1, num2


Essas caracterı́sticas acabam tornando
a utilização do fluxograma
desaconselhável como ferramenta sim num1 > num2 não
principal para o desenvolvimento de
algoritmos. Todavia, a utilização de
fluxograma continua sendo útil para maior ← num1 maior ← num2
apresentação de algoritmos em um
nı́vel de abstração alto, sem entrar nos
detalhes de sua implementação escrever maior

fim

49 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Pseudocódigo
◦ Algoritmos podem ser representados em código diretamente em
linguagem de programação.

◦ É fato que temos algumas vantagens como o código pronto para a


execução e, o mais importante, a rigidez sintática e a rigidez
semântica, que são imprescindı́veis para que o algoritmo possa ser lido
e executado pelo computador

◦ Contudo, a implementação de algoritmos diretamente em uma


linguagem de programação apresenta uma série de desvantagens.

◦ O pseudocódigo visa a trazer o máximo possı́vel desses benefı́cios,


tentando diminuir o ônus da utilização da linguagem de programação.
Abre-se mão do código compilável para se ter um código menos rı́gido,
menos dependente das peculiaridades que todo compilador tem

50 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Pseudocódigo
◦ Ao contrário da linguagem de programação, o pseudocódigo tem um
grau de rigidez sintática intermediária entre as linguagens natural e de
programação. Além disso, podemos utilizar o idioma nativo. Em geral,
linguagens de programação são construı́das utilizando palavras
reservadas em inglês, uma espécie de padrão de mercado

◦ Porém, o pseudocódigo deve manter, tanto quanto possı́vel, a rigidez


semântica. A ideia é que o pseudocódigo seja um passo intermediário
entre a linguagem natural e a linguagem de programação de alto nı́vel

◦ Após a construção do algoritmo em pseudocódigo, é necessário que mais


um passo seja executado: a transformação do pseudocódigo em código
de alguma linguagem de programação

◦ O pseudocódigo é independente do compilador e pode ser


traduzido de uma forma quase direta para uma gama de
linguagens de programação
51 / 63
Algoritmos e Lógica de Programação
• Formalização de um algoritmo: Pseudocódigo
◦ Pseudocódigo referente ao fluxograma mostrado no slide 49
inicio
Algoritmo 1: Maior número
Entrada: num1, num2
ler num1, num2 Saı́da: maior número
1 inı́cio
2 declare num1, num2, maior:
sim num1 > num2 não inteiro;
3 ler(num1,num2);
4 se num1 > num2 então
maior ← num1 maior ← num2 5 maior ← num1;
6 senão
7 maior ← num2;
8 fim
escrever maior
9 escrever(”Maior numero = ”,
maior);
10 fim
fim

52 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ Em um computador, manipulamos informações que, durante a execução
de um programa, ficam armazenadas temporariamente na memória

◦ Para que tais valores possam ser manipulados na linguagem de


programação, é preciso que haja algum identificador informando em que
local da memória (endereço) esse elemento se encontra

◦ Uma analogia útil seria entender esta porção de memória onde o


elemento está amrazenado como uma garagem que tenha uma placa de
identificação na frente. Assim, supondo que tivéssemos vários carros
para escolher, encontrarı́amos o que procuramos pela placa de
identificação

◦ Variáveis e constantes são repositórios de elementos pertencentes aos


tipos. A diferença é que o elemento armazenado em uma constante é
definido no inı́cio do programa e não é mais modificado, enquanto o da
variável pode ser alterado durante a execução do programa
53 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ Tanto variáveis como constantes têm algumas caracterı́sticas em comum:
ambas são identificadas por um nome

◦ Podemos compreender variáveis e constantes como as garagens por


analogia. Os nomes devem identificar o objeto que ali está guardado,
porém não há garantia de que o objeto armazenado seja o esperado

◦ Digamos que se tentarmos colocar um Fusca na garagem em que se


encontra a placa da Ferrari, conseguiremos. No entanto, quando
quisermos dar uma volta de Ferrari, acessaremos a garagem da Ferrari e
teremos uma surpresa ao nos depararmos com o Fusca.

◦ Portanto, convém ao programador dar nomes significativos às


variáveis e constantes de acordo com os elementos (ou valores)
que armazenarão. Normalmente, utilizamos mnemônicos, ou
seja, nomes ou abreviaturas que lembram o uso da variável no
algoritmo
54 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ As variáveis em um algoritmo devem ser escritas de modo claro,
inteligı́vel. Nesse sentido, convencionam-se algumas regras para nomear
variáveis:
• O nome de uma variável pode ser constituı́do por letras do alfabeto
(minúsculas e maiúsculas), dı́gito (0,. . . 9) e ainda pelo caracter
underscore( ).

Cuidado 1
Evite identificadores que comecem por sublinhado ( ) simples ou duplo, porque aqueles
gerados pelo compilador e os da biblioteca-padrão podem usar nomes semelhantes

Cuidado 2
O primeiro caracter não pode ser um dı́gito. O primeiro caracter deve ser uma letra

• Maiúsculas e minúsculas representam variáveis distintas

55 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ As variáveis em um algoritmo devem ser escritas de modo claro,
inteligı́vel. Nesse sentido, convencionam-se algumas regras para nomear
variáveis:

Boa prática de programação


É tradição usar minúsculas para nomes de variáveis e maiúsculas para nomes de cons-
tantes. Isso facilita na hora da leitura do código

• Letras fora do alfabeto ocidental, como as letras gregas, não são aceitas

Boa prática de programação


A escolha de nomes significativos de variáveis favorecerá a elaboração de um programa
”autodocumentado”, isto é, que necessitará de menos comentários

56 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ Antes de utilizarmos uma variável dentro de uma algoritmo, é
necessário definir o tipo de valor que essa variável pode
armazernar e identificá-la com o nome pelo qual será acessada

◦ Uma variável de um determinado tipo só pode receber valores que


pertençam àquele tipo. Na analogia das garagens, podemos dizer que
uma garagem de carro só pode armazenar Fuscas, Ferraris e outros
carros, porém não podem armazernar aviões

◦ A declaração de uma variável em um algoritmo, segundo a nossa


notação, é feita da seguinte forma:

declare <variáveis> : tipo

57 / 63
Algoritmos e Lógica de Programação
• Convenções para tipos de dados: Constantes e variáveis
◦ Os principais tipos de dados são:

• inteiro: qualquer número inteiro, negativo, nulo, ou positivo. Exemplo:


-15; 0; 104

• real: qualquer número real, negativo, nulo ou positivo. Exemplo: -1.0;


-0.5; 0.0; 5.0; 9.3

• caracter: qualquer conjunto de caracteres alfanuméricos. Exemplo: ”AB”;


”123”; ”A123”; ”prova”

• lógico: falso ou verdadeiro (operador booleano)

Valores lógicos
Os valores lógicos ou ainda booleanos (em homenagem a George Boole, que elabo-
rou a lógica booleana) são aqueles que representam apenas dois estados: um estado
verdadeiro ou um estado falso.

58 / 63
Algoritmos e Lógica de Programação
• Convenções para as expressões: Atribuição
◦ Já descrevemos onde os dados ficam armazenados, porém para que
possamos manipulá-los é necessário primeiramente colocar um valor
dentro da variável

◦ A atribuição é a operação que permite armazenar um valor em uma


variável e é representada pelo sı́mbolo ← (seta para a esquerda)

◦ A atribuição é feita das seguintes formas:

<variável> ← <valor>

ou

<variável> ← <resultado de uma expressão>

59 / 63
Algoritmos e Lógica de Programação
• Convenções para as expressões: Atribuição
◦ Exemplos:

1. altura ← 1.80 (armazenar o valor 1.80 na variável altura, ou ainda altura


recebe 1.80)

2. A ← 6 (armazenar o valor 6 na variável A, ou ainda A recebe 6)

3. A ← A + 1 (A recebe o valor de A + 1)

Observação
Apenas valores pertencentes ao tipo da variável podem lhe ser atribuı́dos (p. ex. uma
variável do tipo inteiro só pode receber valores do tipo inteiro

60 / 63
Algoritmos e Lógica de Programação
• Convenções para as expressões: Operações aritméticas
◦ Em programação, todas as quatro operações aritméticas básicas
(adição, subtração, multiplicação e divisão) são suportadas

◦ Essas operações matemáticas são consideradas operações binárias,


pois envolvem sempre dois operandos

◦ Já a operação troca de sinal é unária, pois altera o sinal de um


único operando. O operador unário pode ser pensado como uma
operação que multiplica seu operador por -1
• Exemplos:
1. x ← −x

2. y ← −b

61 / 63
Algoritmos e Lógica de Programação
• Convenções para as expressões: Operações aritméticas
◦ Dependendo dos operadores e do tipo de resultado, a divisão pode ser
feita de forma diferente: a divisão real (operador /), a divisão inteira
(operador div) e o resto da divisão inteira (operador mod)

◦ Exemplos:
1. resp ← 14 div 3 (divisão inteira: resp recebe 4)

2. resp ← 14 mod 3 (resto da divisão inteira: resp recebe 2)

3. resp ← 14.0/3.0 (divisão real: resp recebe 4.67)

◦ Um resumo das operações aritméticas é apresentado na tabela a seguir.

62 / 63
Algoritmos e Lógica de Programação
• Convenções para as expressões: Operações aritméticas
Operaçao 1o operando 2o operando Tipo resultante Simbologia
inteiro inteiro inteiro
real real real
Adição z ←x+y
real inteiro real
inteiro real real
inteiro inteiro inteiro
real real real
Subtração z ←x−y
real inteiro real
inteiro real real
inteiro inteiro inteiro
real real real
Multiplicação z ←x∗y
real inteiro real
inteiro real real
inteiro inteiro real
real real real
Divisão real z ← x/y
real inteiro real
inteiro real real
Divisão inteira inteiro inteiro inteiro z ← x div y
Resto inteiro inteiro inteiro z ← x mod y
inteiro Não aplicável inteiro
Troca de sinal z ← −x
real Não aplicável real

63 / 63

Potrebbero piacerti anche