Baixe o app para aproveitar ainda mais
Prévia do material em texto
ALGORITMOS E PROGRAMAÇÃO APLICADOS À ENGENHARIA PROF. ME LUCAS PUALI SIMÕES SUMÁRIO AULA 01 AULA 02 AULA 03 AULA 04 AULA 05 AULA 06 AULA 07 AULA 08 AULA 09 AULA 10 AULA 11 AULA 12 AULA 13 AULA 14 AULA 15 AULA 16 ANÁLISE E DESCRIÇÃO NARRATIVA 4 FLUXOGRAMA 12 CONCEITOS BÁSICOS DE PROGRAMAÇÃO 18 PROCEDIMENTOS E FUNÇÕES 25 ESTRUTURAS DE FLUXO (CONDICIONAIS) 31 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO ENQUANTO) 37 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO REPITA) 43 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO PARA) 48 APLICAÇÕES DE ALGORITMOS 1 54 ENTENDENDO O CÓDIGO 59 TESTANDO O CÓDIGO (TESTE DE MESA) 67 ESTRUTURAS DE DADOS (VETORES ESTÁTICOS) 72 ESTRUTURAS DE DADOS (MATRIZES ESTÁTICAS) 80 ESTRUTURAS DE DADOS (REGISTROS) 96 ESTRUTURAS DE DADOS (VETORES E MATRIZES DINÂMICOS) 91 APLICAÇÕES DE ALGORITMOS 2 97 CONCLUSÃO 104 REFERÊNCIAS 105 INTRODUÇÃO Na disciplina algoritmos estudaremos o processo e o raciocínio por trás da utilização dessa ferramenta. E ao final da disciplina, ter as noções básicas para criação de algoritmos simples e complexos. No contexto atual, os algoritmos são muito utilizados para criação de softwares para dispositivos móveis, computadores, eletrônicos e até itens menos óbvios como automó- veis e eletrodomésticos. Quando pensamos na idéia de casa inteligente, todo aparelho que tem um tipo de programação, tem por trás um algoritmo. Apesar de associarmos algoritmos a uma questão mais tecnológica e moderna, a ori- gem da palavra é atribuída a um matemático persa chamado Al-Khwarizmi. Isso ocorre pelo fato dele ter desenvolvido algoritmos que trabalhavam no sistema de numeração decimal.[UFPB, 2019] Porém, a idéia principal foi formalizada por Alan Turing e Alonzo Church em 1936, sendo essa a fundação da ciência da computação atual.[UFPB, 2019] Mas afinal, o quê seria um algoritmo? De acordo com Turing e Church, podemos descrever um algoritmo como: um conjunto não ambíguo e ordenado de passos executáveis que definem um processo finito. Isso quer dizer que podemos definir um algoritmo em uma sequencia lógica de passos com etapas únicas que, em ordem seqüencial, resolvem determinado problema. Essa descrição deve ter um numero finito de etapas, ou seja, a descrição das etapas deve ter um fim. Nessa disciplina veremos como representar algoritmos em três formas, a forma des- critiva, o fluxograma e código fonte. Na forma descritiva, os algoritmos são escritos em uma forma muito próxima à forma que escrevemos normalmente, mas com alguns detalhes adicionais. Nessa etapa vamos entender melhor a análise de problemas e como “traduzir” os problemas para criarmos algoritmos. Já o fluxograma, são utilizadas formas geométricas para descrever os passos e ações do algoritmo. Essa forma de descrição facilita ter uma visão geral do problema, facilitando identificar potenciais problemas. Por último, o código fonte é o que mais utilizaremos ao longo da disciplina. Nele será possível “ensinar” o computador a resolver problemas. Esse formato que possibilitará termos uma boa experiência prática na disciplina. Referências UFPB, 5.1. Algoritmos http://producao.virtual.ufpb.br/books/camyle/introducao-a-computacao-livro/livro/livro.chunked/ ch05s01.html http://producao.virtual.ufpb.br/books/camyle/introducao-a-computacao-livro/livro/livro.chunked/ch05s01.html http://producao.virtual.ufpb.br/books/camyle/introducao-a-computacao-livro/livro/livro.chunked/ch05s01.html ANÁLISE E DESCRIÇÃO NARRATIVA AULA 01 5 Nessa primeira aula, precisaremos dividir o conteúdo em análise, onde vamos estudar quais são os elementos necessários para traduzir um problema para um algoritmo. E em seguida, vamos detalhar como é feita a descrição desse algoritmo na forma narrativa. ANÁLISE Anote isso A etapa de analise conta com três pontos chave: os dados de entrada, o processamento e os dados de saída. Os dados de entrada são os elementos necessários para a solução do proble- ma; o processamento são os passos necessários para chegar a solução; e os dados de saída indica o resultado após o processamento. DADOS DE ENTRADA Uma maneira fácil de entender os dados de entrada, é pensar em qual per- gunta é feita quando queremos resolver um problema. Na forma narrativa e no fluxograma, é possível representar a maioria dos problemas do dia-a-dia. Porém, ao iniciarmos a descrição por código fonte, fica- remos restritos à problemas mais voltados à resolução de questões relacionadas a cálculos matemáticos. Exemplo(1): Problema: Faça a tabuada de um número. Pergunta: de qual número a tabuada deve ser feita? Explicação: No problema da tabuada só existe um dado de entrada, que é o nú- mero que devemos fazer a tabuada. 6 Exemplo(2): Problema: Multiplique dois números. Pergunta: quais números devo multiplicar? Explicação: No problema da multiplicação existem dois dados de entrada, que são os números que devemos fazer multiplicar. Exemplo(3): Problema: Resolva a equação f1(x,y,z). Pergunta: quais os valores de x, y e z? Explicação: Apesar de parecer um problema mais complexo, os dados de entrada são os mesmos números que são solicitados para resolver o problema, que no exemplo(3) temos como dados de entrada x, y e z. Considerando os exemplos acima, quando estamos analisando os dados de entrada, seria o mesmo que entender “o que eu preciso saber para resolver este problema?”. Seria o equivalente aos ingredientes de uma receita culinária, caso um falte, não é possível concluir os passos de uma forma que eu tenha como resultado exatamente o que é proposto pela receita. Você deve ter percebido o destaque na palavra “exatamente” no parágrafo anterior. Isso foi intencional, pois você pode ter pensado: “eu posso trocar um ingrediente ou não colocar e ainda assim fazer a receita”. Isso é verdade, mas o resultado final não será o que foi proposto nos passos da receita. Será uma mo- dificação ou adaptação do original. Logo, você não pode dizer que fez a receita original, apenas fez ela modificada ou parcial. Portanto o resultado não será o mesmo. Anote isso Esse ponto é importante pois, quando ensinamos um novo algoritmo ao computador, o computador não saberá se explicamos certo ou errado, ele apenas executará os passos que solicitarmos. Ao definir o processamento, ficará mais clara a importância dos dados de en- trada. 7 Um ultimo detalhe, quando dizemos que utilizaremos “um número” para sim- plificar, podemos chamá-lo apenas de “n”, ou “num”, ou “n1”. No caso de dois números, “n1” e “n2”, ou “a” e “b”. Esse conceito é o conceito de variáveis, que será aprofundado no futuro. No momento, basta saber que podemos simplificar a descrição de um dado de entrada através do seu nome. PROCESSAMENTO O processamento trata dos passos da resolução do problema proposto. Para ilustrar melhor o processamento, utilizaremos a descrição narrativa. Nessa des- crição, utilizaremos frases para descrever as ações que devem acontecer em cada etapa. Ao descrevermos as etapas do processamento é importante deixar cada ins- trução numerada, pois na forma narrativa, ela é a única forma de referenciarmos uma instrução passada ou futura. Exemplo(1): Problema: Multiplique dois números. Dados de Entrada: n1 e n2 Processamento: 01. multiplique o valor de n1 pelo valor de n2. Explicação: No problema da multiplicação o processamento é simplesmente o resultado da multiplicação entre dois números (n1 e n2). Exemplo(2): Problema: Faça a tabuada de um número. Dados de entrada: n Processamento: 01. para elemento começando em 1 até 10 de 1 em 1 faça 02. o valor de n multiplique pelo elemento 03. se elemento ainda for menor que 10, volte para o passo 01 Explicação: No problema da tabuada o processamento se refere à multiplicação um a um de todos elementos de 1 até 10 pelo número (n) que queremos obter a tabuada. 8 Neste exemplo, temos dois novos conceitos no processamento que serão abor- dados em mais detalhesem aula futura, são eles a condição e a repetição. Mas foram utilizados para ilustrar que posso pedir para repetir uma ação voltando a um passo anterior, assim como verificar se uma condição foi atingida. A palavra elemento representa uma variável, que começa com o valor 1 e deve ir até o valor 10 somando 1 a cada passo. E em cada passo, multiplica o valor atual por n e verifica se chegou até 10, se não chegou calcula o próximo. Ilustrando a execução do passo a passo, teríamos algo como: Supondo que queremos a tabuada do 2, logo n = 2 1. elemento = 1 2. n x elemento => 2 x 1 => 2 3. elemento < 10 ? => 1 < 10? Sim 1. elemento = 2 2. n x elemento => 2 x 2 => 4 3. elemento < 10 ? => 2 < 10? Sim 1. elemento = 3 ... repetindo até o elemento ser igual a 10 2. ... 3. elemento <10 ? => 10 < 10? Não E neste ponto, nosso algoritmo chegaria ao fim concluindo toda a tabuada do 2. No caso do exemplo 2, é uma execução que termina concluindo o que é pedido, já o exemplo 1 gera um resultado que não é utilizável. Por esse motivo temos os dados de saída. DADOS DE SAÍDA Esse é o elemento final da análise, é o que indica o resultado dos passos rea- lizados no processamento. Mas atenção, nem todo algoritmo possui dados de saída. Caso você esteja pensando “como assim?”, vou explicar melhor. Por mais que a execução dos passos gere alguma ação ou modificação, nem 9 sempre isso precisa ser um dado de saída ou um “resultado”. Quando realizamos o processamento da tabuada no exemplo 2, ao terminar os passos; caso eu perguntasse para você qual é o resultado, pense um pouco, o quê me diria? Caso a resposta tenha sido algo parecido com “a tabuada pronta”, “a tabuada concluída” ou “a conta das multiplicações da tabuada resolvida”. Todas respostas estariam certas, mas isso não é um resultado. Isso é apenas a conclusão dos passos do processamento. Esse é um caso onde o algoritmo não possui dados de saída. Já no exercício 1 onde multiplicamos 2 números, se eu perguntasse qual o re- sultado, você diria algo como “o resultado da multiplicação” ou “o resultado obtido no passo 1”. Veja como nesse caso o resultado é fácil de identificar e responder. Nesse caso, o dado de saída seria exatamente o valor obtido após o proces- samento da linha 01. Portanto, dividimos os algoritmos em 2 classes, os que possuem dados de saída e os que não possuem. Anote isso Essas classificações são representadas por uma nomenclatura especial. Os algoritmos que não possuem dados de saída são chamados procedimen- tos, já os que possuem dados de saída são chamados funções. Os dados de saída podem ser considerados a parte mais complicada da análise, pois são eles que definem se o problema deve ser abordado por um procedi- mento ou por uma função. Basicamente o que determina se um problema tem dados de saída é se ele é uma pergunta ou uma ordem. Se o problema é uma ordem então se trata de um procedimento que não tem dados de saída, caso seja uma pergunta então é uma função que tem dados de saída. 10 EXERCITANDO Sem se preocupar em pesquisar ou perguntar para alguém, tente resolver o problema a seguir da forma que você resolveria se precisasse. Antes de prosseguir, pegue um pedaço de papel, ou um editor de textos no computador e, com base nas explicações dessa aula, tente identificar os dados de entrada, o processamento e os dados de saída para o seguinte problema: • Trocar o pneu de um carro. Continue a leitura somente após tentar resolver. Esse problema, você pode ou não ter enfrentado alguma vez na vida, mas mesmo que não tenha, tem uma idéia de como resolveria. O principal objetivo desse exercício é exemplificar que um único problema pode ter mais de uma solução possível, apesar do mesmo resultado. Descontando pequenas variações, você respondeu em uma das duas formas a seguir. A mais complexa (dependendo do detalhamento pode passar de 60 passos): Dados de Entrada: macaco, estepe, triângulo de sinalização, chave de roda Processamento: 2. Encostar o carro, desligar o motor e ligar o pisca alerta. 3. Abrir o porta-malas e pegar o macaco, o estepe e o triângulo. 4. Identificar qual lado e qual o pneu está furado 5. Afrouxar os parafusos no lado com o pneu furado identificado no passo 03 utilizando a chave de roda 6. Erguer o lado identificado no passo 03 com o macaco 7. ... Dados de saída: nenhum A mais simples: Dados de Entrada: telefone celular, cartão da seguradora Processamento: 1. Ver o número da seguradora no cartão 2. 02. Ligar para o número do passo 01 com o telefone celular. Dados de Saída: nenhum 11 Tanto a abordagem mais simples quanto a mais complexa estão corretas. Você deve estar pensando “Então, qual é a diferença?”. Tudo depende de qual finali- dade você está elaborando o algoritmo. Se for para colocar no manual do carro, você deve seguir o caminho mais complexo. Agora, se for para deixar no cartão da seguradora, a mais simples é suficiente. Tudo depende da necessidade; Os dois resolvem o problema corretamente deixando o carro com o pneu trocado. Esse exemplo mostra que, desde que você consiga obter a resposta correta, o algoritmo pode variar. Mas preste atenção, nem todos problemas possuem uma variação tão grande. Se lembrarmos do caso do exemplo de multiplicar dois números, o resultado DEVE SER o resultado da multiplicação, então não existem muitas formas diferentes de se obter esse valor. E com essas definições concluímos esta aula. Nela vimos que os dados de entrada são os elementos necessários para resolver o problema em questão, o processamento consiste nos passos a serem executados e os dados de saída são os resultados que podem existir ao término do processamento. 12 FLUXOGRAMA AULA 02 13 Com as noções básicas de algoritmos definidas, vamos estudar a segunda forma de representação de algoritmos. Os fluxogramas são representações gráficas de algoritmos, onde utilizamos símbolos para ilustrar o que deve acontecer naquele momento. Existe um padrão internacional a ISO 5807:1985, nela estão definidos os sím- bolos e funções dos fluxogramas. Existem muitos símbolos que podem ser utili- zados na criação de um fluxograma, mas para as necessidades desta disciplina, utilizaremos apenas alguns. Isto está na rede Porém, na internet é possível encontrar vários explicativos e informações sobre o tema. Fonte: http://www.abenge.org.br/cobenge/arquivos/20/st/q/q162.pdf FORMAS BÁSICAS Todo fluxograma deve apresentar um início e um fim e, para esta represen- tação, são utilizadas as seguintes formas. Entre as duas formas é onde serão inseridas as outras formas, e essas formas devem ser ligadas entre si através de setas que indicam qual a próxima opera- ção a ser executada. Para demonstrar de forma adequada qualquer problema, como vimos ante- riormente é necessário utilizar dados de entrada e em alguns casos também utilizamos dados de saída. http://www.abenge.org.br/cobenge/arquivos/20/st/q/q162.pdf 14 No caso do processamento não ter um resultado, estamos trabalhando com um procedimento. Este por sua vez, não terá a forma de saída em sua estrutura. Já no caso do processamento possuir um resultado, temos uma função. E este sim terá em sua estrutura a forma de saída. Com esses elementos temos a base para inserir o processamento, que é o último elemento que falta para podermos descrever um problema por completo. No processamento, encontramos atribuições, cálculos e desvios. As atribuições e cálculos são representados pela mesma forma, mudando apenas a funcionalidade do conteúdo. Ao utilizar a atribuição, podemos apenas armazenar um valor ou armaze- nar o resultado de algum cálculo. Para informar que é uma operação de atri- buição, podem ser utilizados os símbolos ← ou := sendo que os dois possuem exatamente o mesmo significado. Porém, vale ressaltar que após escolher um dos dois símbolos ele deve ser utilizado em todo o fluxograma. Na atribuição para armazenamento de valor teremosalgo semelhante à figura abaixo, nela estão representados os dois símbolos ← e := para ilustrar sua utilização: 15 Na atribuição para armazenamento de resultado de cálculo teremos algo semelhante à figura abaixo, nela estão representados os dois símbolos ← e := para ilustrar sua utilização: Quando utilizamos cálculos, estamos executando uma operação aritmética ou lógica e armazenando este valor para uso futuro. Em nenhuma forma do fluxograma deve ser utilizado apenas cálculo. E por fim temos a forma utilizada para desvios, os desvios são utilizados quando temos uma comparação que trará um resultado do tipo verdadeiro ou falso, podendo também ser utilizado como resposta sim ou não para diminuir o tamanho do fluxograma. Como podemos observar, os desvios recebem o fluxo e dão origem a dois caminhos alternativos. Nos desvios temos sempre uma flecha chegando e duas saindo. Anote isso Os desvios sempre contém uma operação de comparação, sendo as prin- cipais operações a de maior (>), menor (<), maior ou igual (>=), menor ou igual (<=), igual (=) ou diferente (<>). Por exemplo, se compararmos dois números (n1 e n2) para sabermos se são diferentes ou iguais teremos. 16 Dependendo da resposta obtida à pergunta, o fluxograma segue pelo cami- nho da resposta, se a resposta for sim ele segue pela seta do sim, caso contrário segue pela seta do não. EXEMPLOS Exemplo(1): Problema: Faça a tabuada de um número. Explicação: Obrigatoriamente devemos ter um início e um fim, seguindo o fluxo temos os dados de entrada (n), depois uma atribuição de valor (i := 1) seguida de duas atribuições de cálculo (atual := i * n / i := i + 1), para então en- contrar o desvio (i <= 10) que obriga o fluxo voltar (resposta do desvio é sim) enquanto não calcular os 10 valores da tabuada. Ao terminar (resposta do des- vio é não) os cálculos, chegamos ao fim do fluxograma. Exemplo(2): Problema: Multiplique dois números. Pergunta: n1 é diferente de n2? Pergunta: n1 é igual a n2? 17 Explicação: Neste exemplo, são solicitados os dados de entrada (n1 e n2), em seguida ocorre uma atribuição de cálculo (Result ← n1 * n2) e por se tratar de uma função a forma para dados de saída (Result) é utilizada. Como no pro- cessamento não existe nenhum desvio esta estrutura não deve aparecer no fluxograma. Exemplo(3): Problema: Resolva a equação f1(x,y,z). “function f1(x,y,z:Integer):Integer;” Explicação: A equação f1 foi apresentada simplesmente para ilustrar uma ou- tra maneira de demonstrar o resultado. Nela estamos dizendo que o resultado é o valor atribuído a w, e que este valor está atribuído a result porém também seria correto apresentar diretamente w como dado de saída. Portanto, não é necessário utilizar sempre result para indicar o resultado, basta informar aonde está o dado de saída. Os principais problemas que podemos encontrar em um fluxograma são: • Ter mais de um caminho a seguir sem ter um desvio • Ter um valor indefinido que impede prosseguir. Lembre-se que SEMPRE devemos conseguir partir do início e chegar ao fim por um caminho seqüencial. E com isso, chegamos ao fim de mais uma aula. Os fluxogramas são uma fer- ramenta muito útil para detecção de erros nos algoritmos, a visualização gráfica facilita a compreensão do problema e ajuda a identificar os possíveis problemas que temos no desenvolvimento. 18 CONCEITOS BÁSICOS DE PROGRAMAÇÃO AULA 03 19 Deste ponto em diante, estaremos trabalhando diretamente com programa- ção. Para isso, é necessário optar por uma linguagem de programação para trei- narmos os conceitos que serão estudados. Optar por uma linguagem de programação não gera impacto futuro. Todas as linguagens de programação compartilham da mesma base de raciocínio. O que quero dizer é que não importa se no futuro você venha a utilizar uma linguagem diferente da estudada, você somente terá que aprender “como escrever” nela, o raciocínio lógico será o mesmo. Em qualquer de programação que comporte programação imperativa, poderá utilizar condicionais, repetições, funções, variáveis, vetores, matrizes e registros, ou seja, qualquer conceito aprendido nesta disciplina. Algumas linguagens de programação mais difundidas que utilizam estes con- ceitos são: Ada; ALGOL; Basic; C; C++; PHP; Java; Cobol; Fortran; Pascal; Python e Lua. Nós utilizaremos Pascal para nossos estudos. Caso você já tenha pesquisado algo sobre o tema, pode estar pensando “Porque Pascal entre tantas outras?”. A resposta é simples, Pascal é a linguagem mais didática dentre as demais. A maioria das linguagens utiliza muitos símbolos para delimitar e indicar infor- mações. Pascal é uma linguagem mais escrita, por ser mais natural essa forma, facilita a memorização e a compreensão. Além disso, o modo como o código fica estruturado, por ter “localizações específicas” para cada elemento, ajuda na or- ganização do raciocínio. Isso é crucial para um iniciante no desenvolvimento de programação e algoritmos Mas caso você não seja iniciante, terá no mínimo, uma perspectiva diferente da atual. Tendo em vista que nosso foco está no raciocínio e não na linguagem em si. Para facilitar nossos estudos, está disponibilizado um link com um Programa De Testes “PDT”, que foi desenvolvido por mim para reduzir as dificuldades que a maioria enfrenta com um compilador e todos demais requisitos. Porém, esse aplicativo está disponível apenas na versão desktop. Antes de se preocupar por não ter acesso freqüente à um computador, esse programa é apenas uma ferramenta opcional. Todos exercícios e estudos podem ser realizados com um simples lápis e papel. Programa de testes https://drive.google.com/drive/folders/1cW6vrHlhn7d7M1zmgCxF4i8zdNA_NH5x?usp=sharing https://drive.google.com/drive/folders/1cW6vrHlhn7d7M1zmgCxF4i8zdNA_NH5x?usp=sharing 20 Não é necessário instalar, basta baixar e executar. Uma parte comum para o desenvolvimento em qualquer linguagem de pro- gramação são os tipos de dados, e a escolha do tipo de dado que define quais operações podem ser feitas com eles. Nesta primeira parte devemos nos preocu- par com os tipos mais comuns de dados: os Inteiros (Integer), Reais (Real), Textos (String) e Lógicos (Boolean). Os inteiros e reais seguem a mesma definição da matemática básica, os textos são conjuntos de caracteres e os lógicos são utilizados para comparações e veri- ficações onde armazenamos os valores verdadeiro ou falso. IDENTIFICADORES Os identificadores são nomes que identificam valores dentro de um proce- dimento ou função. Se observarmos o exemplo da multiplicação de dois números, os valores dos números que devemos multiplicar não são informados, apenas sabemos quais são seus identificadores (n1 e n2) que são respectivamente o pri- meiro número que deve ser multiplicado pelo segundo número. No exemplo da tabuada, também não é informado qual o número que deve- mos calcular a tabuada, apenas dizemos que é a tabuada do número n. Tais identificadores devem ser utilizados para informar o que deve ser utilizado sem se preocupar com os valores que o identificador pode assumir. Identifica- dores são utilizados em variáveis, constantes e em nomes de procedimentos e funções. Um identificador deve ser único, não podendo haver uma constante com o mesmo identificador de uma variável, ou uma variável com o mesmo identificador que uma constante, como também não pode haver uma variável/constante com o mesmo nome que o procedimento ou função no qual ela é utilizada. 21 Alguns exemplos: Outro detalhe importante sobre identificadores é que eles não podem con- ter espaços nem acentos e nunca devem ser iniciados por números. Alguns exemplos de uso incorreto de identificadores são: ‘vezes dois’, ‘multiplicação’, ‘1numero’, etc. CONSTANTES As constantes são utilizadas quando temos valores fixos ou que variam rara- mente. Alguns exemplos de constantes são: número de dedos nas mãos, o valor de π, um multiplicador de uma função matemática, etc.Para representar uma constante, o símbolo de atribuição (:= ou ←) nunca é uti- lizado. Como ela é constante informamos que o identificador é igual (=) a um valor. Exemplos de constantes: DedosDaMao = 5; Pi = 3.14; x = 9; Utilização de constantes: para i := 1 até DedosDaMao faça r := i * Pi; Errado Errado Errado Procedure a(n:integer); Function b(m:integer;):integer; Procedure c(o:integer); const var const a = 1; b : integer; d = 1; ... ... var d : real; ... Erro: Constante e procedimento com o mesmo identificador. Erro: Variável e função com o mesmo identificador. Erro: Constante e variável com o mesmo identificador. 22 VARIÁVEIS As variáveis são utilizadas para armazenar valores que serão alterados posteriormente e para armazenar resultados de cálculos matemáticos ou lógicos. Como as variáveis armazenam valores, é necessário informar qual tipo de valor ela pode armazenar e isso é feito através da utilização do símbolo : que significa “do tipo”. A utilização das variáveis deve ser feita através da utilização dos símbolos de atribuição (:= ou ←) podendo ser seguida de um valor ou cálculo. Podemos comparar variáveis com caixas, assim como temos caixas de sapatos, de jóias, ou de qualquer coisa, podemos definir o que está guardado nela. Ilustrando esse conceito, vamos considerar o seguinte algoritmo: X := 4; X := X + 3; Nele temos duas linhas de processamento, na primeira, a variável X guarda o valor 4, e na segunda quanto? Antes de responder, vamos entender como as variáveis funcionam em cada lado da atribuição. Vamos imaginar que temos uma variável identificada por X, logo, seria o equi- valente a termos uma caixa com X marcado na frente dela. VariáVEl à dirEita da atribuição Explicação Quando a variável está nes- ta posição, devemos ver o conteúdo que foi guardado anteriormente nela para uti- lizarmos em uma conta ou simplesmente guardar este valor em outra variável 23 VariáVEl à EsquErda da atribuição Explicação No caso da esquerda, qualquer valor que estava na variável é descartado e o valor que estava na direita passa a ser o novo valor da variável. Voltando ao problema que foi descrito anteriormente. X := 4; X := X + 3; Na primeira linha, X está à esquerda da atribuição, logo o que deve acontecer é: Qualquer coisa que estivesse guardada em X seria descartada e o novo valor de X passa a ser 4 deste ponto em diante Na linha 2 temos X à direita E à esquerda da atribuição. Nesse caso, primeiro resolvemos a parte da direita e depois de concluirmos, guardamos o valor final na esquerda. Como 4 é o novo valor de X, o X à direita tem esse valor arma- zenado Com esse valor, conseguimos realizar a conta e armazenar o novo valor de X, que será o valor da de X a partir da linha 2. Respondendo então a pergunta de qual seria o valor de X após computar a linha 2. O valor de X é 7. 24 Exemplos de declaração variáveis (Informar o tipo de informação): Multiplicacao: Integer; Numero1: Real; Nome: String; TesteDeDesvio: Boolean; As variáveis exemplificadas significam: Multiplicacao é “do tipo” inteiro, ou seja, só podemos armazenar inteiros nela. Numero1 é “do tipo” real, ou seja, só podemos armazenar valores reais nela. Nome é “do tipo“ texto, ou seja, só podemos armazenar textos nela. TesteDeDesvio é “do tipo” lógico, ou seja, só podemos armazenar valores lógicos nela. Utilização de variáveis: Multiplicacao:= n1 * n2; Numero1:= 4.5; Nome:= “Meu nome é”; TesteDeDesvio:= n1 > n2; Anote isso Um detalhe importante das variáveis do tipo texto. Quando vamos utilizar textos, para o computador diferenciar que é um texto e não um identifica- dor, devemos utilizar “o texto dentro das aspas“. Outra questão está nos valores reais, o separador de casa decimal é o ponto e não a vírgula. Com essa base, podemos iniciar os estudos com parte prática. Para podermos testar os programas desenvolvidos no PDT, precisamos entender os conceitos de função e procedimento, tema da próxima aula. 25 PROCEDIMENTOS E FUNÇÕES AULA 04 26 Inicialmente, vamos testar a sua memória, você lembra o que é um dado de saída? Lembra também se todo algoritmo sempre deve possuir ao menos um? Espero que tenha recordado, mas vamos relembrar mesmo assim. Os dados de saída representam o resultado de um algoritmo e não são obrigatórios. Em alguns casos temos e em outros não. Na multiplicação de dois números, encontramos o resultado da multiplicação como dado de saída. Já na tabuada, não existia nenhum resultado apenas a ta- buada concluída. Como visto anteriormente os procedimentos e funções são utilizados para execução de uma tarefa, sendo que a única diferença entre eles é a presença ou ausência de um resultado. As funções e procedimentos são estruturas que representam ou “explicam” um algoritmo para o computador, também são uma forma de guardar o que já ensinamos ao computador, podendo reutilizá-las quantas vezes forem necessárias sem ter que explicar novamente. Essas estruturas têm um conjunto de componentes e, no pascal, uma ordem correta. Em outras linguagens, esses componentes também estão presentes, mas não necessariamente na mesma ordem. O primeiro elemento é o escopo, nele contamos uma história inicial sobre o que essa estrutura irá realizar e o que ela exige para funcionar. 1º Escopo: I. Indicativo se é um procedimento ou função (ou seja, se tem resultado ou não); II. Identificador (nome para poder realizarmos “chamadas”); III. Parâmetros (dados de entrada com os respectivos tipos caso existam), caso seja necessário, separamos um dado de entrada do outro utilizan- do ponto e vírgula ( ; ); IV. [somente em funções] o tipo do resultado. 27 A figura acima ilustra cada item do escopo, sendo que em I a palavra function indica que temos uma função e, por sua vez, ela tem um dado de saída. No caso do exemplo, o resultado seria no formato texto como indicado no item IV. Se você reparar no procedimento (ou procedure), esse campo não existe pois procedi- mentos não possuem dados de saída. Agora repare nos itens II e III, o item II indica o nome da função e o nome do procedimento, eles devem ser únicos no programa sendo desenvolvido. Já o item III indica quais são os dados de entrada que a função ou procedimento precisam para funcionar. Os dados de entrada podem ter o mesmo nome pois fazem parte de elementos diferentes. Os dados de entrada da função nome1 serão utilizados exclusivamente por essa função, logo não entrarão em conflito com os dados de entrada do proce- dimento nome2. Como vimos anteriormente em variáveis, o uso do : serve para indicar o tipo de informação trabalhada. No exemplo, n1 será um valor inteiro e a função será texto. Na forma narrativa temos algo como, uma função chamada nome1 com dado de entrada n1 do tipo inteiro e dado de saída do tipo texto; e um procedimento chamado nome2 com dado de entrada n1 do tipo inteiro. Isso faz com que o computador já prepare a execução e pontos de memória para que isso seja possível. Ao dizer que é ou não uma função ele já sabe se terá um resultado para armazenar, o nome faz com que ele saiba o que execitar quan- do solicitado e o dado de entrada faz com que ele somente inicie os passos caso todos dados de entrada sejam fornecidos. 2º Constantes: Caso existam devem aparecer logo depois do escopo. 3º Variáveis: Se existirem constantes devem aparecer logo abaixo. Caso não existam constantes devem aparecer logo depois do escopo. 4º Processamento: Deve vir após as variáveis ou constantes caso elas existam. Caso não tenha constantes ou variáveis deve aparecer logo abaixo do escopo. 28 Para montar estas estruturas, podemos utilizar algumas perguntas: pErgunta rEspostas O problema tem resultado? Se tem utilizar função Senão utilizar procedimento Qual problema estou resolvendo? Identificador da função/procedimento O que preciso para resolver? Os dados de entrada Tem algum valor constante? Constantes Precisoguardar valores para utilizar depois? Variáveis Como resolvo o problema? Processamento Se tenho resultado, aonde ele está armazenado? Dado de saída Exemplo(1): Problema: Faça a tabuada de um número. “procedure tabuada(n:Integer):Integer;” pErgunta MontagEM EM pascal O problema tem resultado? não Procedure Qual problema estou resolvendo? tabuada procedure tabuada O que preciso para resolver? um número (n) procedure tabuada(n:Integer); Tem algum valor constante? não procedure tabuada(n:Integer); Preciso guardar valores para utilizar depois? sim procedure tabuada(n:Integer); var índice, atual : integer; Como resolvo o problema? procedure tabuada(n:Integer); var indice, atual : integer; begin for indice := 1 to 10 do begin atual := indice * n; end; end; Se tenho resultado, aonde ele está armazenado? não tem resultado 29 Exemplo(2): Problema: Multiplique dois números. “function multiplica2(n1,n2:Integer):Integer;” Não se preocupe caso pareça complicado, tem elementos no exemplo que ainda não foram estudados. O importante é conseguir identificar o que aconteceu em cada pergunta e em cada etapa. Para testarmos os exemplos acima e já iniciarmos nossas práticas no PDT, vamos entender o funcionamento dessa ferramenta. O programa de testes (PDT) é um programa bem simples que tem como prin- cipal objetivo permitir a prática simples com resultados imediatos à execução sem necessidade de todas etapas que outros métodos de geração de programas. pErgunta MontagEM EM pascal O problema tem resultado? sim Function Qual problema estou resolvendo? multiplica2 function multiplica2 O que preciso para resolver? dois números n1,n2 function multiplica2(n1,n2:Integer):Integer; Tem algum valor constante? não function multiplica2(n1,n2:Integer):Integer; Preciso guardar valores para utilizar depois? sim function multiplica2(n1,n2:Integer):Integer; var multiplicacao : Integer; Como resolvo o problema? function multiplica2(n1,n2:Integer):Integer; var multiplicacao : Integer; begin multiplicacao := n1 * n2; Se tenho resultado, aonde ele está armazenado? na variável multiplicação function multiplica2(n1,n2:Integer):Integer; var multiplicacao : Integer; begin multiplicacao := n1 * n2; result := multiplicacao; end; 30 Descrição de cada item destacado: 1. Indica a linha e coluna (linha:coluna) do cursor atual, também serve para localizar a posição aproximada de qualquer erro indicado na área (5) do programa 2. Indicador de linha. 3. Área onde é realizado o desenvolvimento dos exercícios e testes. É nessa área que escreveremos os algoritmos. 4. Nessa parte é onde testamos o que foi criado no item (3). Até o mo- mento, nós não passamos valores para os dados de entrada. É no item 4 que indicamos quais valores queremos que seja realizada a execução do código. Os dados de entrada são separados por vírgula nesse campo. 5. Nessa área são realizadas as escritas, demonstrados os resultados e também aonde são apresentados os erros. 31 ESTRUTURAS DE FLUXO (CONDICIONAIS) AULA 05 32 Para poder representar a maioria dos problemas que encontramos, é neces- sário utilizar estruturas de fluxo e começaremos o estudo delas nessa aula. As estruturas que serão abordadas são as estruturas condicionais e futuramente de repetição. As estruturas condicionais são utilizadas quando é necessário saber a respos- ta a alguma pergunta antes de executar uma tarefa ou tomar uma decisão. Para esta tarefa temos duas estruturas, o “if condição then” e “case valor of”. Antes de utilizar as estruturas condicionais os conceitos de condição devem estar claros e, por isso, primeiro vamos analisar como as condições podem ser formadas e o que devemos esperar como resultado de uma condição. Essas estruturas são representadas pelo desvio no fluxograma que estudamos anteriormente. CONDIÇÕES Condições geralmente são utilizadas diretamente em estruturas condicio- nais e de repetição, porém é possível armazenar o resultado de uma condição em uma variável antes de utilizá-la. As mesmas opções que podem ser utilizadas em um desvio de fluxograma, podem formar uma condição. Uma questão importante é que todas condições devem ser interpretadas como perguntas. condição pErgunta a > b o valor de a é maior que o valor de b? a < b o valor de a é menor que o valor de b? a >= b o valor de a é maior ou igual ao valor de b? a <= b o valor de a é menor ou igual ao valor de b? a = b o valor de a é igual ao valor de b? a <> b o valor de a é diferente do valor de b? As condições podem ser simples ou compostas, as condições simples são como as descritas acima e as condições compostas são uniões de condições de simples. Essa união é feita através dos operadores “e” e “ou”. 33 condição pErgunta (a < b) and (a > 1) (o valor de a é menor que o de b?) e (o valor de a é maior que 1?) (a < b) or (a = b) o valor de a é menor ou igual ao valor de b? Os operadores “e ” e “ou” funcionam da mesma forma que utilizamos as pa- lavras. Logo, se dizemos que (a < b) e (a > 1), isso só será verdade se (a < b) for verdade “e” (a > 1) também for verdade. Já ao utilizarmos “ou”, apenas uma das condições deve ser verdadeira. Para entender melhor essa lógica, utilizamos a tabela verdade para ilustrar as possíveis combinações e possíveis resultados. condição utilizando “E” psEudocódigo condição utilizando “E” (pascal) rEsultado ExEMplo VERDADEIRO e VERDADEIRO TRUE and TRUE VERDADEIRO (5 > 1) e (3 < 5) VERDADEIRO e FALSO TRUE and FALSE FALSO (2 > 1) e (5 = 4) FALSO e VERDADEIRO FALSE and TRUE FALSO (3 < 1) e (2 < 3) FALSO e FALSO FALSE and FALSE FALSO (3 < 1) e (5 = 4) Essas operações são utilizadas quando é necessário verificar mais de uma pergunta antes de tomar uma decisão. Suponha que para fazer uma conta com três números é necessário que o primeiro número seja maior que os demais. Esta condição pode ser escrita da seguinte forma: “(numero1 > numero2) e (numero1 > numero3)”, neste caso isso só será verdade se o numero1 for maior que o nu- mero2 “e” maior que o numero3. No operador “ou”, basta que uma condição seja verdadeira. Caso a tabela verdade do “e” para utilizar o “ou” essa diferença fica clara. condição utilizando “ou” psEudocódigo condição utilizando “ou” (pascal) rEsultado ExEMplo VERDADEIRO ou VERDADEIRO TRUE or TRUE VERDADEIRO (5 > 1) ou (3 < 5) VERDADEIRO e FALSO TRUE or FALSE VERDADEIRO (2 > 1) ou (5 = 4) FALSO e VERDADEIRO FALSE or TRUE VERDADEIRO (3 < 1) ou (2 < 3) FALSO e FALSO FALSE or FALSE FALSO (3 < 1) ou (5 = 4) 34 Utilizando o operador “ou”, ao alterarmos o exemplo anterior, suponha que para fazer uma conta com três números é necessário que o primeiro número seja maior que apenas um dos demais. Esta condição pode ser escrita da seguinte forma: “(numero1 > numero2) ou (numero1 > numero3)”, neste caso isso será verdade se o numero1 for maior que o numero2 “ou” maior que o numero3 “ou” se for maior que o numero2 e numero3. ESTRUTURA “se <condição> então” Esta é uma estrutura simples que pode resolver problemas complexos pois ela pode ser combinada quantas vezes for necessário. A estrutura “se … então” pode ser utilizada sozinha, pode também ser seguida de um “senão” simples, ou pode ser seguida de uma outra estrutura “se … então” após o “senão” formando uma nova verificação no formato “senão se … então” Os mesmos exemplos utilizados na explicação sobre “condições” podem ser utilizados para explicar a utilização da estrutura “se … então” simplesmente adi- cionando a condição no lugar de “…”. condição significado if a > b then se o valor de a for maior que o valor de b então faça if a < b then se o valor de a for menor que o valor de b então faça if a >= b then se o valor de a for maior ou igual que o valor de b então faça if a <= b then se o valor de a for menor ou igual que o valor de b então faça if a = b then se o valor de a for igual ao valor de b então faça if a <> b then se o valor de a for diferente que do valorde b então faça Nesta estrutura também podem ser utilizadas condições compostas, como foi apresentado. condição significado if (a < b) and (a > 1) then se (valor de a for menor que o de b) e (o valor de a for maior que 1) então faça if (a < b) or (a = b) then se o valor de a for menor ou igual que o valor de b então faça 35 Exemplos de estrutura “se … então”: Estrutura ExEMplo “se … então” if (n1 > n2) and (n1 > n3) then begin // se a condição for verdadeira faça isto r := n1; end; “se … então” “senão” if (n1 > n2) then begin // se a condição for verdadeira faça isto r := n1; end else begin // se a condição anterior for falsa faça isto r := n2; end; “se … então” “senão se … então” if (n1 > n2) then begin // se a condição for verdadeira faça isto r := n1; end else if (n2 > n1) then begin // se a condição anterior for falsa e a atual for // verdadeira faça isto r := n2; end; “se … então” “senão se … então” “senão” if (n1 > n2) then begin // se a condição for verdadeira faça isto r := n1; end else begin if (n2 > n1) then // se a condição anterior for falsa e a atual for // verdadeira faça isto r := n2; end else begin // se as condições anteriores forem falsas faça isto end; ESTRUTURA “caso <valor> for” Este tipo de estrutura tem uma finalidade mais específica que a estrutura “se … então”. A estrutura “caso … for” utiliza principalmente a relação de igualdade. Ou seja, caso o valor for igual 1 faça algo, caso for igual a 2 faça outra e assim por diante. Esta estrutura aceita também a estrutura adicional “senão” apenas uma 36 vez para indicar que o valor não tem nenhum igual no “caso”. Exemplos de estrutura “caso … for”: Estrutura ExEMplo “caso … for” case (n1) of 1: begin // se n1 for igual a 1 faça isto end; 2: begin // se n1 for igual a 2 faça isto end; 3: begin // se n1 for igual a 3 faça isto end; end; “caso … for” “senão” case (n1) of 1: begin // se n1 for igual a 1 faça isto end; 2: begin // se n1 for igual a 2 faça isto end; else begin // se n1 diferente de todos anteriores faça isto end; end; Estes exemplos mostram o uso do “caso” em variáveis numéricas, mas “…” pode ser um resultado de conta, ou ainda resultado de função. Da mesma forma, as opções que estão nos exemplos consistem em números, porém podem ser utilizados literais e faixas de números. 37 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO ENQUANTO) AULA 06 38 As estruturas de repetição podem ser representadas em três formas, utilizan- do enquanto, repita ou para, cada uma com a sua função ideal. Cada classe de problema tem uma repetição mais indicada. Quando analisamos um problema que percebemos a necessidade de uma estrutura de repetição, primeiro devemos identificar qual o tipo de condição esse problema exige. Anote isso Acredito que a dica mais importante que posso te dar ao longo dessa dis- ciplina é: leia em voz alta o que está explicando. Isso ajuda a entender a instrução que está sendo passada ao computador. ESTRUTURA “enquanto <condição> faça” A repetição enquanto deve ser utilizada quando precisamos verificar uma condição antes da primeira execução. Diga a frase, enquanto isso for verdade repita aquilo. Onde isso é a condição e aquilo é o que deve ser repetido. Esta estrutura repetirá enquanto a condição for verdadeira. Ou seja, se dissermos “enquanto (n < 10) faça” a estrutura repetirá o que estiver programado enquanto o valor de n for menor que 10. 39 Exemplos: ExEMplo significado while (a > b) do begin r := r + (a * 2); b := b + 1; end; enquanto o valor de “a” for maior que o valor de “b” faça “r” recebe o antigo valor de “r” + (o valor de “a” vezes 2) “b” recebe o antigo valor de “b” + 1 // usado pra “b” alcançar “a” i := 1; while (i <= 10) do begin r := i * 2; i := i + 1; end; “i” recebe o valor inicial 1 enquanto o valor de “i” for menor ou igual a 10 faça “r” recebe o valor de “i” vezes 2 “i” recebe o antigo valor de “i” + 1 // usado pra “i” alcançar 10 i := 10; while (i >= 1) do begin r := i * 2; i := i – 1; end; “i” recebe o valor inicial 10 enquanto o valor de “i” for maior ou igual a 1 faça “r” recebe o valor de “i” vezes 2 “i” recebe o antigo valor de “i” – 1 // usado pra “i” descer até 1 Perceba que nesta estrutura a resposta da condição deve mudar para que em algum momento a repetição acabe. Caso o valor de “b” ou de “i” não fosse alterado, “b” não chegaria ao valor de “a” nem “i” chegaria até 10 ou até 1. Isso resultaria em uma repetição infinita, o programa nunca chegaria ao fim de sua execução. EXEMPLO COMPLETO: Vamos fazer um algoritmo para identificar todos os números pares em um intervalo determinado. Ou seja, dado um valor inicial e um valor final, devemos encontrar todos os valores que são pares. Primeiro vamos verificar como identificamos que um número é par criando uma função que retorna verdadeiro se o número for par e falso se for ímpar. Vamos utilizar a tabela auxiliar para montar essa função. Para identificarmos que um número é par, verificamos se o resto da divisão desse número por 2 tem resto 0. Vamos analisar alguns exemplos 40 Relembrando os elementos de uma divisão temos: Alguns exemplos: Nos exemplos, 2, 4, 5 e 6 possuem resto 0 logo, são números pares. pErgunta MontagEM EM pascal O problema tem resultado? Sim (valor lógico) function ():boolean; Qual problema estou resolvendo? eh_par function eh_par():boolean; O que preciso para resolver? um número n function eh_par(n:Integer):boolean; Tem algum valor constante? não function eh_par(n:Integer):boolean; Preciso guardar valores para utilizar depois? sim function eh_par(n:Integer):boolean; var resto : Integer; Como resolvo o problema? function eh_par(n : Integer):boolean; var resto : Integer; begin resto := n mod 2; if resto = 0 then begin result := true end else begin result := false; end; end; Se tenho resultado, aonde ele está armazenado? O resultado depende da condição do resto ser 0, logo é atribuído em cada caso O fluxograma dessa função pode ser representado da seguinte forma: Vamos analisar os detalhes da função escrita como código para entender cada elemento: 41 Explicação dE cada linha function eh_par(n : Integer):boolean; var resto : Integer; begin resto := n mod 2; if resto = 0 then begin result := true end else begin result := false; end; end; Escopo da função com dado de entrada n e resultado lógico Início da lista de variáveis Variável resto pode armazenar valores inteiros Início do processamento Resto guarda o valor do resto de n dividido por 2 Se o resto for igual a 0 então Início se for verdade Resultado é verdadeiro Fim se for verdadeiro Senão for verdadeiro Início senão Resultado é falso Fim do senão Fim do processamento Com isso, concluímos a função que identifica se um número é par. Agora vamos elaborar o procedimento que indica todos os números pares na faixa. pErgunta MontagEM EM pascal O problema tem resultado? não procedure (); Qual problema estou resolvendo? encontra_par procedure encontra_par(); O que preciso para resolver? início i e fim f procedure encontra_par(i,f : Integer); Tem algum valor constante? não procedure encontra_par(i,f : Integer); Preciso guardar valores para utilizar depois? sim procedure encontra_par(i,f : Integer); var atual : Integer; Como resolvo o problema? procedure encontra_par(i,f : Integer); var atual : Integer; begin atual := i; while (atual <= f) do begin if eh_par(atual) then begin escr(IntToStr(atual)); end; atual := atual + 1; end; end; Se tenho resultado, aonde ele está armazenado? Não tem resultado 42 O fluxograma final desse procedimento pode ser demonstrado conforme abaixo. Perceba que por ser um procedimento, não possui resultado, apenas uma escrita no caso do número ser par. Detalhamentodescritivo do procedimento Explicação dE cada linha procedure encontra_par(i,f: Integer); var atual : Integer; begin atual := i; while (atual <= f) do begin if eh_par(atual) then begin escr(IntToStr(atual)); end; atual := atual + 1; end; end; Escopo do procedimento, dados de entrada i e f Início da lista de variáveis Variável atual pode armazenar valores inteiros Início do processamento Atual inicia em i que é o início da faixa que queremos Enquanto atual for menor ou igual à f faça Início da repetição enquanto Se o resultado de eh_par com o valor atual então Inicio se for verdade Escreve valor atual convertido de inteiro para texto Fim se for verdade Atual guarda atual + 1 para ir para o próximo número Fim da repetição enquanto Fim do processamento Com esse exemplo, concluímos a aula sobre utilização da repetição enquan- to. As demais repetições seguem a mesma linha de raciocínio, e estudaremos a seguir. 43 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO REPITA) AULA 07 44 Neste outro formato de repetição, a condição de parada é verificada após 1 execução, ou seja, utilizamos esse tipo de estrutura quando existe a necessidade de executar pelo menos uma vez, independente da condição. ESTRUTURA “repita … até <condição>” A repetição repita deve ser utilizada quando precisamos verificar uma condi- ção após da primeira execução. Diga a frase, repita isso até que aquilo aquilo seja verdade. Onde isso é a condição e aquilo é o que deve ser repetido. O “repita … até <condição>” funciona da mesma forma que a estrutura “en- quanto <condição> faça”, porém a verificação da condição é diferente. A primeira verificação é feita após a primeira execução da repetição, e repete até que algo seja verdade ou em outras palavras, esta estrutura repete enquanto a condição não for verdadeira. Exemplos: ExEMplo significado repeat r := r + (a * 2); b := b + 1; until (a <= b); repita “r” recebe o antigo valor de “r” + (o valor de “a” vezes 2) “b” recebe o antigo valor de “b” + 1 // usado pra “b” alcançar “a” até o valor de “b” ser maior ou igual ao valor de “a” i := 1; repeat r := i * 2; i := i + 1; until (i > 10); “i” recebe o valor inicial 1 repita “r” recebe o valor de “i” vezes 2 “i” recebe o antigo valor de “i” + 1 // usado pra “i” alcançar 10 até o valor de “i” ser maior que 10 i := 10; repeat r := i * 2; i := i – 1; until (i < 1); “i” recebe o valor inicial 10 repita “r” recebe o valor de “i” vezes 2 “i” recebe o antigo valor de “i” – 1 // usado pra “i” descer até 1 até o valor de “i” ser menor que 1 45 Se repararmos nas condições desta estrutura, elas estão invertidas em rela- ção à estrutura anterior. Isso ocorre, pois aqui a repetição ocorre enquanto a condição não é verdadeira e na estrutura anterior a repetição ocorre enquanto a condição é verdadeira. Para auxiliar na compreensão, vamos resolver um exemplo completo iqual ao da repetição enquanto, porém com a repetição do tipo repita. EXEMPLO COMPLETO: Na repetição anterior, fizemos um algoritmo para identificar todos os valores pares em um determinado intervalo. Vamos montar a tabela para este novo caso. pErgunta MontagEM EM pascal O problema tem resultado? não procedure (); Qual problema estou resolvendo? encontra_par procedure encontra_par(); O que preciso para resolver? início i e fim f procedure encontra_par(i,f : Integer); Tem algum valor constante? não procedure encontra_par(i,f : Integer); Preciso guardar valores para utilizar depois? sim procedure encontra_par(i,f : Integer); var atual : Integer; Como resolvo o problema? procedure encontra_par(i,f : Integer); var atual : Integer; begin atual := i; repeat if eh_par(atual) then begin escr(IntToStr(atual)); end; atual := atual + 1; until (atual > f); end; Se tenho resultado, aonde ele está armazenado? Não tem resultado O fluxograma dessa repetição, se comparada com a anterior, podemos notar várias diferenças. 46 A principal delas está na posição da condição de término da repetição, você pode notar que ou ela volta para o início, ou vai direto para o fim. Na anterior, a condição da repetição que dizia se o processamento da repetição seria executado logo no inicio ou não. Anote isso Por esse motivo, memorize bem o comportamento de cada repetição. • A do tipo enquanto faz a verificação no início da repetição e repete quando a condição é verdadeira. • A do tipo repita, executa uma vez antes da verificação que é realizada no fim e repete quando a condição é falsa. Detalhamento descritivo do procedimento Explicação dE cada linha procedure encontra_par(i,f: Integer); var atual : Integer; begin atual := i; repeat if eh_par(atual) then begin escr(IntToStr(atual)); end; atual := atual + 1; (atual > f); end; Escopo do procedimento, dados de entrada i e f Início da lista de variáveis Variável atual pode armazenar valores inteiros Início do processamento Atual inicia em i que é o início da faixa que queremos Repita os passos abaixo Se o resultado de eh_par com o valor atual então Inicio se for verdade Escreve valor atual convertido de inteiro para texto Fim se for verdade Atual guarda atual + 1 para ir para o próximo número Até atual ser maior que f e, quando for, pare de repetir Fim do processamento Se compararmos os dois fluxogramas lado a lado, fica mais fácil perceber as di- ferenças e identificar as peculiaridades de cada uma das duas formas de repetição. 47 A principal delas está na posição da condição de término da repetição, você pode notar que ou ela volta para o início, ou vai direto para o fim. Na anterior, a condição da repetição que dizia se o processamento da repetição seria executado logo no inicio ou não. Anote isso Por esse motivo, memorize bem o comportamento de cada repetição. • A do tipo enquanto faz a verificação no início da repetição e repete quando a condição é verdadeira. • A do tipo repita, executa uma vez antes da verificação que é realizada no fim e repete quando a condição é falsa. Detalhamento descritivo do procedimento Explicação dE cada linha procedure encontra_par(i,f: Integer); var atual : Integer; begin atual := i; repeat if eh_par(atual) then begin escr(IntToStr(atual)); end; atual := atual + 1; (atual > f); end; Escopo do procedimento, dados de entrada i e f Início da lista de variáveis Variável atual pode armazenar valores inteiros Início do processamento Atual inicia em i que é o início da faixa que queremos Repita os passos abaixo Se o resultado de eh_par com o valor atual então Inicio se for verdade Escreve valor atual convertido de inteiro para texto Fim se for verdade Atual guarda atual + 1 para ir para o próximo número Até atual ser maior que f e, quando for, pare de repetir Fim do processamento Se compararmos os dois fluxogramas lado a lado, fica mais fácil perceber as di- ferenças e identificar as peculiaridades de cada uma das duas formas de repetição. Não se preocupe, tão pouco se assuste, não é um jogo dos 7 erros. Vou des- tacar os principais pontos que você deve revisar até entender essas diferenças. Releia e assista as aulas quantas vezes forem necessárias. 1. A posição do desvio que contém a condição de parada é diferente. • No tipo Enquanto está no início • No tipo Repita está no fim 2. A condição que está dentro do desvio é diferente. • No Enquanto, repete enquanto atual <= f • No Repita, repete até atual > f 3. Os caminhos de sim e não vão para pontos diferentes do fluxo. • No Enquanto, quando falso vai para o fim • No Repita, quando verdadeiro vai para o fim Agora você já tem o conhecimento necessário para elaborar algoritmos com condicionais e as formas de repetições mais abrangentes disponíveis. Por terem condições que podem ser definidas, são mais genéricas. Na próximaaula, vamos estudar a última forma de repetição. Ela atende uma classe de problemas mais específica, que em alguns casos pode facilitar a elabo- ração do algoritmo. 48 ESTRUTURAS DE FLUXO (REPETIÇÃO TIPO PARA) AULA 08 49 Na última forma de repetição, temos a estrutura de repetição “para”. Esse estilo de repetição atende uma classe mais restrita de problemas. Isso se dá pelo fato de haver a necessidade de sabermos aonde começar e aonde a repetição deve terminar através de uma faixa de números inteiros. Isso significa que devemos saber de antemão exatamente quantas vezes a repetição ocorrerá. Diferente das repetições anteriores onde era verificado na hora da execução dos passos se era o momento de parar. ESTRUTURA “para <índice> de <inicio> até <fim> faça” Como estamos falando sobre ser um tipo de repetição para uma classe es- pecial de problemas. O fluxograma para representar tem alguns pontos desta- cados. Esses pontos destacados são fixos, ou seja, temos que ter uma variável para o contador, temos que ter um início e também é obrigatório o fim. A condição também permanece a mesma, apenas mudando a comparação em uma variação que será explicada mais a frente. A estrutura “para <índice> de <inicio> até <fim> faça” é considerada a mais simples de ser utilizada. Isso se dá ao fato de sabermos qual o índice que indica a contagem, assim como sabemos qual o início e o fim da repetição. 50 ExEMplo significado for b := 1 to a do begin r := r + (a * 2); end; para o índice “b” de 1 até “a” faça “r” recebe o antigo valor de “r” + (o valor de “a” vezes 2) // nesta estrutura “b” é atualizado automaticamente até alcançar “a” for i := 1 to 10 do begin r := i * 2; end; para o índice “i” de 1 até 10 faça “r” recebe o valor de “i” vezes 2 // nesta estrutura “i” é atualizado automaticamente até alcançar 10 for i := 1 downto 10 do begin r := i * 2; end; para o índice “i” de 10 descendo até 1 faça “r” recebe o valor de “i” vezes 2 // nesta estrutura “i” é atualizado automaticamente até descer a 1 Se compararmos esta estrutura com as anteriores realmente parece a mais simples de ser utilizada, porém para cada uma tem uma vantagem. Apesar de parecer melhor, caso seja necessário atualizar o índice de 2 em 2 (i := i +2) em vez de 1 em 1 (i := i + 1), esta estrutura já não pode ser utilizada. Mas caso você tenha notado, na tabela de exemplos temos o último exemplo descendo para um valor ao invés de subindo. Isso pode levantar uma dúvida, esse exemplo não vai contra a última frase? Nesse caso não pois, o modo descendente é contemplado como opção de sequência. Isso traria apenas uma pequena variação no fluxo. Ao invés do contador chamado no exemplo de “cont” guardar o valor antigo dele somando 1, o temos armazenando o valor antigo subtraindo 1. Isso compi- nado com a troca da condição de parada de <= para >= gera o comportamento descendente. 51 EXEMPLO COMPLETO Agora vamos detalhar o exemplo da tabuada que vimos em aula anterior. Nesse exemplo, temos que calcular a tabuada de um numero. Na tabuada nós sabemos que ela começa multiplicando o número por 1 e segue multiplicando os demais até chegar no 10. Esse é um caso onde a aplicação da repetição do tipo Para é ideal pois, conhe- cemos o início e o fim da sequencia de repetição. pErgunta MontagEM EM pascal O problema tem resultado? não Procedure Qual problema estou resolvendo? tabuada procedure tabuada O que preciso para resolver? um número (n) procedure tabuada(n: Integer); Tem algum valor constante? não procedure tabuada(n: Integer); Preciso guardar valores para utilizar depois? sim procedure tabuada(n: Integer); var indice, atual : Integer; Como resolvo o problema? procedure tabuada(n:Integer); var indice, atual : integer; begin for indice := 1 to 10 do begin atual := indice * n; escr(IntToStr(n)+’ x ‘+ IntToStr(indice)+’ = ‘+ IntToStr(atual)) end; end; Se tenho resultado, aonde ele está armazenado? Não tem resultado Para esse exemplo, o fluxograma pode ser descrito na forma abaixo, mas pres- te atenção nos nomes das variáveis e nas partes que destaquei anteriormente como fixas. 52 Agora vamos ao detalhamento do procedimento da tabuada, lembrando que n é o numero que queremos calcular a tabuada. Explicação dE cada linha procedure tabuada(n:Integer); var indice, atual : integer; begin for indice := 1 to 10 do begin atual := indice * n; escr(IntToStr(n)+’ x ‘+ IntToStr(indice)+’ = ‘+ IntToStr(atual)) end; end; Escopo do procedimento, dado de entrada n Início da lista de variáveis Variáveis indice e atual podem armazenar valores inteiros Início do processamento Para o indice iniciando em 1 até 10 faça Inicio da repetição Atual guarda o valor do indice multiplicado por n Escreve o valor de n convertido para texto com x na frente Na frente disso, o texto do indice com = na frente Na frente disso, o valor calculado da tabuada Fim da repetição Fim do processamento As variáveis indice e atual são modificadas ao longo da repetição, onde indice é o valor que está sendo calculada a tabuada e atual é o resultado da multiplicação entre o indice e n. Como estamos definindo que o indice vai de 1 à 10, já podemos adiantar que indice terá todos valores inteiros iniciando em 1 e terminando em 10 Indice := 1 Indice := 2 … Indice := 10 Atual := 1 * 7 Atual := 1 * 7 … Atual := 10 * 7 escr(7+’x‘+1+’=‘+7) escr(7+’x‘+2+’=‘+7) … escr(7+’x‘+10+’=‘+7) escr(‘7 x 1 = 7’) escr(‘7 x 2 = 14’) … escr(‘7 x 10 = 70’) Nesse exemplo, vou aproveitar para chamar a atenção à uma função especial do PDT, você pode ter notado dentro da repetição um procedimento chamado escr. Esse procedimento permite que seja dada uma ordem de escrita para o algoritmo. Também é utilizado o recurso de concatenação (união) de textos. Quando estamos utilizando textos, o sinal de adição (+) faz a união entre dois textos. Esse recurso foi utilizado para escrever a tabuada no formato que estamos acostuma- dos a fazer. 53 Com a execução da tabuada dentro do PDT posso detalhar esses elementos. Nas linhas 8, 9 e 10 estamos “montando o texto” para passar como dado de entrada para o procedimento escr. Como vimos anteriormente, IntToStr converte de Inteiro Para Texto, então esta- mos unindo o texto do valor n com ‘ x ‘ com o texto do valor do indice com ‘ = ‘ finalizan- do com o texto do valor atual. As aspas simples são para o computador entender que se trata de um texto. E o resultado pode ser visto na parte in- ferior do PDT por causa do uso do procedi- mento de escrita escr E com isso finalizamos as estruturas de repetição, revise o conteúdo para en- tender as diferenças entre elas e também o uso das condicionais. Esse conjunto de estruturas é o mais utilizado na maioria dos algoritmos criados. 54 APLICAÇÕES DE ALGORITMOS 1 AULA 09 55 Nesta aula, teremos uma visão prática de algoritmos. A ideia por traz desse conteúdo é de exemplificar todo o processo de raciocínio até a elaboração do código final. Nós vamos estudar uma aplicação simples, para reforçar a teoria já estudada em uma aplicação em um problema real do dia a dia. Com isso espero reforçar os conceitos definidos até este ponto da disciplina. Seria possível exemplificar com qualquer problema que envolve algum tipo de calculo complexo da engenharia ou uma super fórmula cheia de elementos que você já viu ou poderia ver em alguma outra disciplina. Porém, como estamos aprendendo o raciocínio de algoritmos, vamos manter problemas corriqueiros. A utilização de problemas que enfrentamos no dia a dia, tira o foco do pro- blema e nos permite focar em entender o raciocínio por trás da elaboração do algoritmo. Agora vamos ao problema. Considere que você vai ao mercado e eu te peça para comprar algum produto, porém, que tenha o melhor custo benefício. Isso significa que eu quero quevocê encontre o produto, da mesma marca, que tenha maior quantidade e menor preço. Nesse momento, eu gostaria que antes de você continuar a leitura, que ten- tasse pensar em como resolveria esse problema. Agora vou explicar uma forma simples de resolver esse problema. Nele, vamos basicamente utilizar a regra de 3. Para essa solução não importa se a quantida- de está em gramas, kilos, litros, etc., nem qual a moeda corrente. vamos tratar somente de quantidade e preço. A solução consiste em identificar qual o produto está com o menor preço na menor unidade de medida dele. Nós podemos verificar isso calculando o preço que cada unidade custa para aquele determinado produto. Isto está na rede Regra de 3 https://www.somatematica.com.br/fundam/regra3s.php https://www.somatematica.com.br/fundam/regra3s.php 56 Sei que pode parecer confuso, mas com um exemplo prático a ideia ficará mais simples de entender. Vamos considerar que vamos comprar um pote de chocolate em pó e, ao chegar no mercado, encontramos uma embalagem com a quantidade de 200g e preço 5,00 e outra embalagem com a quantidade de 500g pelo preço de 10,00. Qual devemos comprar? Para descobrirmos isso, vamos calcular quanto está o preço de 1g da embala- gem maior e também qual o preço de 1g da embalagem menor. Vamos calcular o preço unitário utilizando a seguinte regra de 3. Utilizando essa regra, sabemos que ao dividir o preço pela quantidade teremos o preço unitário. Sendo que o unitário se refere sempre à unidade que definirmos em cada caso. Ou seja, se o produto estiver em gramas, teremos o preço de um grama. Se for em quilos, o preço de um quilo, mesmo que estivesse em ml, ainda teríamos o preço de 1 ml. Sabendo disso, para comprar as embalagens temos apenas que dividir o preço de cada uma pela quantidade e depois identificarmos o preço unitário de menor valor. No nosso exemplo, a embalagem de chocolate em pó maior tem o preço uni- tário de 10/500 que dá 0,02 por unidade. Já a menor, o preço de 5/200 é de 0,025. Isso significa que a embalagem com o melhor preço é a de embalagem maior, pois o seu valor unitário é o menor. Agora que temos todas as informações necessárias, antes de continuar a lei- tura, tente fazer a análise, o fluxograma e o código desse problema. Para a análise, vamos identificar os dados de entrada, o processamento e os dados de saída. Os dados de entrada sabemos que são as quantidades e preços Preço PreçoUnitário Quantidade 1 1 Preço X 1 = PreçoUnitário X Quantidade 3 Preço = PreçoUnitário X Quantidade 4 PreçoUnitário = Preço Quantidade 5 Preço PreçoUnitário Quantidade 1 2 57 das duas embalagens, o processamento é o calculo do preço unitário da emba- lagem maior e menor que será comparado. Por fim, temos o dado de saída com qual embalagem devemos comprar. Dados de entrada: Preco1, Quantidade1, Preco2 e Quantidade2 Processamento: 1. Dividir Preco1 por Quantidade1 2. Dividir Preco2 por Quantidade2 3. Se (1.) for menor que (2.) então 4. A embalagem 1 é a de menor preço 5. Senão se (1.) for maior que (2.) então 6. A embalagem 2 é a de menor preço 7. Senão 8. As embalagens são equivalentes em preço Dados de saída: Linha 4, 6 ou 8. Para diminuir o tamanho do fluxograma e do código, vamos simplificar os no- mes dos dados de entrada da seguinte maneira: Preco1 (P1), Quantidade1 (Q1), Preco2 (P2) e Quantidade2 (Q2). Também vamos chamar PrecoUnitario1 de PU1 e PrecoUnitario2 de PU2. O Fluxograma desse problema poderia ser representado na seguinte forma. Início P1, Q1, P2, Q2 PU1 := P1 / Q1; PU2 := P2 / Q2; PU1 < PU2 'Produto 1' PU1 > PU2 'Produto 2' 'Qualquer' Fim Sim Sim Não Não 58 E por fim, temos o código que devemos elaborar seguindo as etapas anteriores. Para elaboração utilizaremos a tabela auxiliar que estudamos anteriormente. Concluímos então todo o processo de análise e tradução de um problema para um algoritmo computacional. Nesta aula revisamos as melhores práticas para a elaboração de um algoritmo. Entendemos o problema, desenvolvemos a análise, elaboramos o fluxograma e por último montamos o código. Essas etapas são importantes para reduzir as chances de erro no processo de elaboração. Revise esta aula observando que todos os elementos estão presentes nas três formas de representação do algoritmo proposto. pErgunta MontagEM EM pascal O problema tem resultado? sim Function Qual problema estou resolvendo? Compara function compara2 O que preciso para resolver? dados dos produtos function compara2(P1,Q1,P2,Q2:Real):String; Tem algum valor constante? Não function compara2(P1,Q1,P2,Q2:Real):String; Preciso guardar valores para utilizar depois? sim function compara2(P1,Q1,P2,Q2:Real):String; var PU1, PU2 : Real; Como resolvo o problema? function compara2(P1,Q1,P2,Q2:Real):String; var PU1, PU2 : Real; begin PU1 := P1 / Q1; PU2 := P2 / Q2; if PU1 < PU2 then begin result := ‘Embalagem 1 tem menor preço’; end else if PU1 > PU2 then begin result := ‘Embalagem 2 tem menor preço’; end else begin result := ‘As embalagens tem mesmo preço’; end; end; Se tenho resultado, aonde ele está armazenado? em result 59 ENTENDENDO O CÓDIGO AULA 10 60 Uma maneira para entender como montar procedimentos e funções é enten- der como estas estruturas funcionam. Para entender, primeiro precisamos saber identificar os elementos e estruturas que foram estudados até este ponto, e para isso não é necessário entender o processamento. IDENTIFICANDO CONSTANTES Constantes não tem seu valor alterado, por possuir essa característica é um dos elementos mais simples de ser identificado. Para identificar uma constante basta analisar se o identificador nunca tem um valor atribuído a ele. Ou seja, caso um identificador esteja na esquerda da atribuição (id :=) não é constante, caso esteja sempre na direita da atribuição (:= id) ou apenas utilizado para cálculos (id * n) é constante, exceto quando é dado de entrada. ExEMplo quais idEntificadorEs são constantEs, quais não são E por quê? procedure nome(C:Int…); ? begin X := A; if X < (B + C) then begin W := X * (A – B); end; end; São constantes: A e B A e B aparecem apenas à direita de “:=” e aparecem em contas. Não são constantes: C, X e W X e W aparecem à esquerda de “:=” C aparece apenas em contas mas é dado de entrada IDENTIFICANDO VARIÁVEIS Variáveis tem seu valor alterado pelo menos uma vez no processamento, por possuir essa característica é outro elemento simples de ser identificado. Para identificar uma variável basta analisar se o identificador aparece pelo menos uma vez à esquerda de uma atribuição. Ou seja, caso um identificador esteja na es- querda da atribuição (id :=) é variável. 61 ExEMplo quais idEntificadorEs são VariáVEis, quais não são E por quê? function nome(…):…; ? begin Z := D; if Z < (E * F) then begin F := Z mod (D / E); end; result := F; end; São variáveis: Z e F Z e F aparecem pelo menos uma vez à esquerda de “:=”. Não são Variáveis: D, E e F D, E e F não aparecem à esquerda de “:=” IDENTIFICANDO ESTRUTURAS CONDICIONAIS Identificar estruturas condicionais é uma tarefa simples, basta procurar no código a presença das estruturas estudadas. Caso o código tenha algum “if … then” ou “case … of” então temos a presença de estruturas condicionais. E caso queiramos saber qual a condição de cada estrutura, basta analisar o que está em “…”. ExEMplos idEntificação function nome(…):…; ? begin if Z > 10 then begin F := Z mod D; end; result := F; end; Possui condicional? Sim Quantas? 1 Quais as condições? 1º (Z > 10) procedure nome(…); ? begin for i := 1 to 10 do begin if W <= 5 then begin X := W + 5; end else if W > 7 then begin X := W – 7; end; end; end; Possui condicional? Sim Quantas? 2 Quais as condições? 1º (W <= 5) 2º (W > 7) 62 function nome(…):…; ? begin while (Z > 10) do begin Z := Z modD; end; result := Z; end; Possui condicional? Não Quantas? 0 Quais as condições? Com estes exemplos, podemos perceber que não é necessário saber o que está acontecendo no código, basta procurar as estruturas e analisá-las. IDENTIFICANDO ESTRUTURAS DE REPETIÇÃO Para identificar estruturas de repetição, o mesmo processo que para identificar condicionais é utilizado com a diferença que procuramos estruturas de repetição. Ou seja, devemos procurar “while … do”, “until …” e “for … do”. Os exemplos que serão apresentados podem apresentar mais de uma estru- tura de repetição, pois isso pode acontecer na resolução de alguns problemas, mas assim como na identificação de estruturas condicionais, não é necessário entender o que está acontecendo no código. ExEMplos idEntificação function nome(…):…; ? begin while (W < 20) do begin W := W mod D; end; result := W; end; Possui repetição? Sim Quantas? 1 Quais as condições? 1º (Z > 10) procedure nome(…); ? begin for i := 1 to 10 do begin if W <= 5 then begin X := W + 5; end else if W > 7 then begin X := W – 7; end; end; end; Possui repetição? Sim Quantas? 1 Quais as condições? 1º (1 <= i <= 10) 63 function nome(…):…; ? begin if Z > 10 then begin F := Z mod D; end; result := Z; end; Possui repetição? Não Quantas? 0 Quais as condições? function nome(…):…; ? begin while (W > 20) do begin repeat W := W * D; until (W < 10); W := W mod D; end; result := W; end; Possui repetição? Sim Quantas? 2 Quais as condições? 1º (W > 20) 2º (W < 10) Com esses exemplos concluímos a identificação de repetições, e como mencio- nado anteriormente o processo de identificação é o mesmo que o utilizado para identificar condicionais. IDENTIFICANDO PROCEDIMENTOS E FUNÇÕES Para concluir os tópicos de identificação, por último deixamos a identificação de procedimentos e funções. Quando o intuito é identificar se o código anali- sado se refere a um procedimento ou função basta verificar a presença de resultado (result) e caso exista um resultado é função, senão se trata de um procedimento. Vale ressaltar que a procura por um resultado deve ser feita com cuidado pois em alguns casos o resultado se encontra no meio do código, não sendo obrigatório ele estar sempre no final. 64 ExEMplos idEntificação ? nome(…)? … begin while (W < 20) do begin W := W mod D; end; result := W; end; Possui resultado? Sim Portanto: é uma função ? nome(…)? … begin for i := 1 to 10 do begin if W <= 5 then begin result := W + 5; end else if W > 7 then begin result := W – 7; end; end; end; Possui resultado? Sim Portanto: é uma função ? nome(…)? … begin if Z > 10 then begin F := Z mod D; end; end; Possui resultado? Não Portanto: é um procedimento ? nome(…)? … begin while (W > 20) do begin repeat W := W * D; until (W < 10); result := W mod D; end; end; Possui resultado? Sim Portanto: é uma função 65 EXEMPLO DE IDENTIFICAÇÃO COMPLETA Para reforçar o que foi visto no processo de identificação, será apresentado um exemplo onde será feita a identificação de todos os itens vistos até agora. Até este ponto foi identificado que “X” é uma constante e que “n”, apesar de não estar à esquerda de nenhuma atribuição, não é constante pois está nos dados de entrada. Também identificamos “W” e “i” como variáveis, pois ambos aparecem pelo menos uma vez à esquerda de atribuição. Percebemos que apesar de saber- mos que “X” é uma constante, seu valor não pode ser identificado. constantEs constantEs idEntificadas VariáVEis VariáVEis idEntificadas ? nome(n:Integer)?; ? ? ? ? begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; ? nome(n:Integer)?; const X = ?; ? ? begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; ? nome(n:Integer)?; const X = ?; ? ? begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; ? nome(n:Integer)?; const X = ?; var W, i : Integer; begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; condicionais condicionais (inf.) rEpEtiçõEs rEpEtição (inf.) ? nome(n:Integer)?; const X = ?; var W, i : Integer; begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; Possui condicional? Sim Quantas? 1 Quais as condições? 1º (W <= X) ? nome(n:Integer)?; const X = ?; var W, i : Integer; begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end end; end; Possui repetição? Sim Quantas? 1 Quais as condições? 1º (1 <= i <= n) 66 Agora identificamos que no código temos tanto estruturas condicionais quanto de repetição. Para finalizar, falta apenas verificar se o código é referente a uma função ou a um procedimento. procEdiMEnto/função procEdiMEnto/função (inf.) função final ? nome(n:Integer)?; const X = ?; var W, i : Integer; begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end; end; end; Possui resultado? Sim Portanto: é uma função function nome(n:Integer):Integer; const X = ?; var W, i : Integer; begin W := n; for i := 1 to n do begin if W <= X then begin result := W + X; end; end; end; Ao término do processo de identificação, pode-se notar que mesmo sem todas as informações presentes, é possível descobrir muitas informações mesmo sem se preocupar com o que acontece durante a execução do código. A única informação que não pode ser obtida é o valor da constante “X”, este valor não pode ser obtido em nenhum lugar exceto quando sabemos qual resultado esperar do código. Este é o último tópico sobre identificação de informações no código. Para con- cluir o capítulo será feito o teste de código. 67 TESTANDO O CÓDIGO (TESTE DE MESA) AULA 11 68 Existem dois motivos para testar um código, o primeiro é compreender seu funcionamento e o segundo é verificar se ele está gerando o resultado espe- rado. Este é um processo importante para ser realizado após o desenvolvimento de qualquer algoritmo. Aqui será apresentado um exemplo de teste e, quais os passos mais comuns para executar esta tarefa. Tenha sempre em mente que o computador executa o código linha por linha e é da mesma forma que devemos prosseguir. Além das linhas, devemos também considerar em qual bloco de código estamos no momento. Para identificar um bloco de código, basta procurar as palavras “begin” e “end” e associá-los aos pares. Lembrando que para todo “begin” deve existir um “end”. A execução de um teste necessita também que sejam definidos valores fictícios para os dados de entrada. Ao longo do teste, como o código é executado linha por linha, as linhas que ficaram para trás do bloco atual serão apagadas pois não serão mais utilizadas f1(1,4,3); passo1: atualizar a,b,c function f1(a,b,c:Integer):Integer; const q = 2; var i, z, r : Integer; begin if a > b then begin z := a; end else begin z := b; end; r := 0; for i := 0 to c do begin r := r + (z * q); end; result := r; end; function f1(a,b,c:Integer):Integer; const q = 2; var i, z, r : Integer; begin if 1 > 4 then begin z := 1; end else begin z := 4; end; r := 0; for i := 0 to 3 do begin r := r + (z * q); end; result := r; end; Com a atualização dos dados de entrada o escopo pode ser apagado, pois como ainda não aprendemos sobre recursividade, não voltaremos a utilizá-lo. Os próximos blocos a serem analisados serão as constantes, as variáveis devem permanecer pois devemos verificar se não estamos tentando armazenar outro tipo de informação. Então após as constantes chegarmos ao processamento.
Compartilhar