Prévia do material em texto
Disciplina Algoritmos e Lógica de Programação Unidade 1 Lógica de programação Aula 1 Conceitos introdutórios Introdução Olá, estudante. Nesta aula iniciamos os estudos sobre programação de computadores em que você terá contato com os primeiros conceitos de algoritmos, variáveis, tipos de dados e os operadores básicos. A compreensão dos fundamentos da programação é importante para que o restante do aprendizado adiante não seja comprometido, assim como compreender a base sobre a qual a grande área de Tecnologia da Informação é construída. Desse modo, aproveite esta etapa para estudar com calma, lendo e relendo os conceitos e exemplos apresentados, realizando os exercícios, assistindo aos vídeos das aulas para que o conteúdo seja entendido de modo adequado e sua jornada seja tranquila. Disciplina Algoritmos e Lógica de Programação Bons estudos! Primeiros conceitos Vamos começar abordando os primeiros conceitos da lógica de programação e a de�nição de algoritmo, que é o núcleo da sua aprendizagem nesta disciplina. A programação de computadores é um termo abrangente e que pode ser compreendido de diversas formas. “Programar”, no nosso contexto, refere-se a aplicar técnicas e sequências de instruções a um dado artefato tecnológico com o objetivo de que suas tarefas sejam executadas automaticamente. Pense no exemplo dos robôs de limpeza utilizados para limpar o chão de casas de modo autônomo. Para que este artefato tecnológico consiga realizar suas tarefas sem dani�car objetos da residência, muitas instruções estão gravadas em seu sistema para controlar sua operação. A partir do momento que ele é ligado, deve mapear o ambiente, veri�car a existência de móveis, calcular a rota e assim por diante. Todas essas operações já estão programadas. Por exemplo, caso encontre um objeto à frente, gire 90º para a direita e siga em frente. Para que uma instrução como essa seja salva no sistema do robô, é necessário que linguagens especí�cas sejam utilizadas, a�nal, o objetivo é instruir uma máquina formada por dezenas e milhares de transistores, resistores e circuitos. Assim, uma instrução na linguagem humana deve ser traduzida para linguagens compreendidas pela máquina por meio do que Disciplina Algoritmos e Lógica de Programação chamaremos de comandos. Portanto, uma operação que pode parecer simples do nosso ponto de vista muitas vezes será dividida em dezenas, centenas ou milhares de comandos para a máquina. Desse modo, é possível inferir que o estudo da programação deve ser composto de outras áreas do conhecimento, como a lógica, pois é necessário que as sequências de comandos estejam organizadas logicamente de modo a fazer funcionar a máquina em toda sua complexidade. Além disso, elementos da matemática e até mesmo da linguística também são utilizados, pois para escrever um programa com instruções e comandos é fundamental que sigam as sintaxes e padrões estabelecidos. O que é algoritmo É comum hoje nos depararmos com a palavra algoritmo em notícias, vídeos, reportagens, pois ela é utilizada em contextos diferentes como: eleições, propagandas, recomendação de �lmes e séries, etc. O motivo para a difusão desta palavra é simples: o algoritmo é a base da programação. Mais especi�camente, um programa de computador é a implementação de um ou mais algoritmos como solução para resolver um problema. Do modo sucinto, pois abordaremos os detalhes em outro momento, um algoritmo é uma sequência de instruções e comandos para resolver um problema. _______ Re�ita Quais algoritmos você já utilizou em sua vida? Podemos pensar no ensino fundamental, quando aprendemos o algoritmo da divisão. Ou então os passos para resolver uma fórmula de Bhaskara; os passos para descobrir se um número é primo, entre outros. Em resumo, um algoritmo é como uma receita, isto é, a descrição dos passos necessários para se chegar a um resultado esperado. Variáveis, tipos e operadores Para que um programa implemente um algoritmo é preciso, além da lógica do algoritmo em si, um ferramental para manipular os dados e organizar as instruções. De modo geral, a maioria das linguagens de programação apresentam variáveis para armazenar dados, que possuem tipos especí�cos e podem ser relacionadas por meio de operadores. Ao retomarmos o exemplo do robô aspirador, podemos imaginar de que modo vamos guardar a direção que o robô se encontra, sua velocidade, sua energia, se há ou não objetos próximos e assim por diante. Todas as informações devem ser armazenadas em variáveis. E, caso necessário, seus valores podem ser alterados, como ao alterar a direção. Por essa capacidade de modi�car os dados armazenados chamamos a estrutura de variáveis, em oposição a constantes, que são dados armazenados imutáveis. Por exemplo: o peso do robô será uma constante, pois não deve sofrer variações de acordo com sua execução. Por último, para que as variáveis sejam alteradas é necessário manipulá-las, o que é feito com os operadores. Um programa e seus elementos Disciplina Algoritmos e Lógica de Programação Agora, vamos aprofundar o estudo inicial de programas de computador e uso e tipos de variáveis. Para iniciar, temos uma receita de bolo abaixo: Receita de bolo 2 xícaras de açúcar 3 xícaras de farinha 4 colheres de manteiga 3 ovos 1 colher de fermento Modo de preparo: Bata as claras em neve; Misture as gemas, o açúcar e a manteiga; Acrescente o leite e a farinha de trigo aos poucos; Adicione as claras em neve e o fermento; Despeje a massa em uma forma grande de furo central; Asse em forno médio a 180 °C, preaquecido, por aproximadamente 40 minutos. Observe que uma receita tem duas partes principais: os ingredientes utilizados e o modo de preparo (no nosso caso, o algoritmo), que é o passo a passo da manipulação dos ingredientes para obter o bolo conforme esperado. Assim, a sequência correta da execução das instruções é essencial para o resultado correto. Caso a última instrução fosse executada antes da hora, provavelmente o bolo não seria saboroso. Da mesma forma, as instruções de um programa de computador devem seguir uma sequência lógica de passos. Disciplina Algoritmos e Lógica de Programação Ademais, não basta seguir a sequência correta se os recipientes e ingredientes não estiverem de acordo com a receita. Observe que na receita há um número certo de xícaras de farinha. Na nossa analogia da receita com um programa, os ingredientes seriam as variáveis, que podem ter suas quantidades alteradas de acordo com o tamanho do bolo desejado e manipulados de acordo com cada operador, como adicionar as claras em neve e o fermento. Tomemos agora um exemplo de um programa em que se deseja calcular a média de três números inteiros. Poderíamos escrever as instruções desse programa da seguinte maneira: Some os três números. Divida a soma dos três números pelo número 3. Imprima na tela o resultado. Para os números 3, 4 e 9, por exemplo, poderíamos escrever o seguinte programa: 1. 3 + 4 + 9 2. (3 + 4 + 9) / 3 Observe que os parênteses são utilizados da mesma forma que na notação da matemática 3. imprimir((3+4+9)/3)) Porém, caso quiséssemos utilizar o programa para calcular a média de 6, 7 e 10, teríamos que reescrever todo o programa para tal. 1. 6 + 7 + 10 2. (6 + 7 + 10) / 3 3. imprimir((6 + 7 + 10)/3)) E assim por diante, isto é, para cada três novos valores seria necessário reescrever todo o programa. Para resolver esta situação, introduzimos o uso das variáveis e assim nosso código pode ser reutilizado. Utilizaremos as variáveis x, y e z para representar os números, mas observe que você pode dar o nome que quiser, desde que o primeiro caractere seja uma letra. Por exemplo: numero1, numero2 e numero3, ou a, b e c, etc. E as variáveis soma e média representarão outras variáveis auxiliares. Desse modo, o programa �caria da seguinte maneira: 1. soma x + y + z 2. media (soma)/3 3. imprimir(media) E, com isso, pode ser reaproveitado para quaisquer números, bastando modi�car osvalores de x, y e z. Assim temos um programa mais completo e e�ciente. Contudo, ainda é preciso estar atento aos tipos das variáveis, a�nal, a divisão de números inteiros nem sempre é inteira. Desse modo, é preciso especi�car qual o tipo numérico de cada variável: 1. x: inteiro; 2. y: inteiro; Disciplina Algoritmos e Lógica de Programação 3. z: inteiro; 4. soma: inteiro; 5. media: decimal. Desse modo, nosso primeiro programa está praticamente completo, com as variáveis e tipos de�nidos e o algoritmo de cálculo da média implementado: a primeira parte refere-se ao que chamamos de declaração das variáveis e a segunda parte às instruções propriamente ditas do algoritmo: // Declaração das variáveis 1. x: inteiro; 2. y: inteiro; 3. z: inteiro; 4. soma: inteiro; 5. media: decimal; // Instruções do programa 6. soma x + y + z 7. media (soma)/3 8. imprimir(media) Apesar de completo, este exemplo tem �ns apenas didáticos, pois não está em uma linguagem reconhecida por nenhum compilador ou tradutor de linguagem de máquina. É o que chamamos de pseudocódigo, pois simula o código de um programa em linguagem e símbolos mais fáceis de serem compreendidos por nós, o que é a forma ideal de iniciar na programação. O uso de variáveis e operadores Disciplina Algoritmos e Lógica de Programação Agora, veremos alguns exemplos de criação de programas básicos e sua implementação utilizando pseudocódigo para representar as variáveis e as operações. Tome o exemplo a seguir: 1. x: inteiro; 2. y: inteiro; 3. x 2 4. y x 5. imprimir(y) Qual o valor de y após a execução das duas linhas? Neste caso, a variável y recebe o valor que estava armazenado em x, no caso, o valor 2. Agora observe o caso a seguir: 1. x: inteiro; 2. y: inteiro; 3. x 2 4. imprimir(x) 5. y x + 1 Disciplina Algoritmos e Lógica de Programação �. x x + y 7. imprimir(x) O programa possui dois comandos de impressão na tela. Quais os valores de x serão impressos? Pare responder a essa pergunta precisamos executar o código passo a passo. Quando o programa executar o primeiro comando “imprimir(x)” (linha 4), o valor de x será 2, pois até aquele momento foi a última atualização da variável x. Contudo, no momento da execução do segundo comando “imprimir(x)” (linha 7), o valor impresso será 5, você sabe explicar o porquê? Após a primeira impressão, a variável y recebe o valor armazenado na variável x (que é igual a 2) mais o número 1, portanto, y está valendo 3. No próximo comando, a variável x recebe a soma dos valores armazenados em x (igual a 2) mais o valor armazenado na variável y (igual a 3). Portanto, a variável x é atualizada para o valor 5. Ou seja, deixa de armazenar o valor 2 para armazenar o valor 5. Façamos agora um outro exemplo para �xar o conteúdo visto até o momento. O objetivo do programa será implementar um algoritmo que leia o nome de duas pessoas junto com suas respectivas idades e imprima na tela uma mensagem de texto informando a soma da idade das duas pessoas. Por exemplo: se o usuário digitar o nome João e a idade 24 e o nome Maria com a idade 25, deve imprimir na tela a mensagem: “A soma da idade de João e Maria é 49”. Para tanto, passamos a precisar de variáveis que representem texto e variáveis que representam números inteiros. Além disso, é preciso ler os nomes e idades, calcular a soma das idades e imprimir a mensagem solicitada, conforme o programa abaixo. 1. nome1: texto; 2. nome2: texto; 3. idade1: inteiro; 4. idade2: inteiro; 5. Ler(nome1); //neste momento é lido o primeiro nome �. Ler(idade1); //neste momento é lida a primeira idade 7. Ler(nome2); //neste momento é lido o segundo nome �. Ler(idade2); //neste momento é lida a segunda idade 9. soma idade1 + idade2; 10. Imprimir(“A soma da idade de “ nome1 “ e “ nome2 “ é “ soma); ______ Observação As duas barras // indicam um comentário. Isso signi�ca que o texto após as barras não faz parte do código, como nas linhas 5, 6, 7 e 8. ______ Como último exercício de �xação, execute mentalmente (ou em um papel) o programa acima com diferentes nomes e idades e observe quais mensagens serão impressas ao �nal. Este é um Disciplina Algoritmos e Lógica de Programação bom exercício para compreender que um programa deve poder ser utilizado para diferentes tipos de valores, o que chamamos de entradas de dados. Nesta aula, você aprendeu de maneira introdutória os principais conceitos de algoritmo, programa, variáveis, tipos de dados e alguns operadores. Bons estudos! Videoaula: Conceitos introdutórios Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, no vídeo desta aula abordaremos os primeiros conceitos da lógica de programação de modo a complementar este material escrito. Abordaremos e ilustraremos a de�nição e os exemplos do uso de variáveis com os principais operadores de maneira a consolidar essa etapa introdutória e essencial ao seu aprendizado. Saiba mais Disciplina Algoritmos e Lógica de Programação O estudo da lógica de programação e dos primeiros passos para pensar e construir algoritmos pode ser uma novidade interessante e desa�adora para muitas pessoas. Por isso, há diversas ferramentas disponíveis para auxiliar os estudantes nesta etapa. Uma das mais utilizadas para o nível introdutório é a linguagem Scratch, criada em 2007 pelo MIT e que utiliza elementos ilustrativos e blocos para ensinar o pensamento algoritmo de maneira lúdica e didática. Scratch, sua documentação e instruções para download estão disponíveis em seu site. Referências https://scratchmit.edu/ Disciplina Algoritmos e Lógica de Programação DASGUPTA, S.; PAPADIMITRIOU, C.; VAZIRANI, U. Algoritmos. Porto Alegre: AMGH Editora, 2009. ZIVIANI, N. et al. Projeto de algoritmos: com implementações em Pascal e C. Luton: Thomson, 2004. Aula 2 De�nições de lógica Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante. Nesta aula, você conhecerá uma temática fundamental para a compreensão do pensamento algorítmico: a lógica proposicional, o ramo da lógica que auxilia a compreender e organizar as variáveis, os métodos e as funções de maneira estruturada. Assim, por meio de de�nições e conceitos iniciais, você aprenderá o básico da lógica, os principais conectivos como conjunção, disjunção e condicional, bem como sua representação utilizando a tabela verdade. Portanto, é importante que você acompanhe este material com atenção para que o conteúdo abordado sirva como base para o seu desenvolvimento futuro no mundo da programação. Bons estudos! Introdução à lógica Disciplina Algoritmos e Lógica de Programação A lógica é um campo fundamental da ciência e da �loso�a que estuda a representação do conhecimento, em que a preocupação principal é a validação da argumentação. Assim, a lógica, como veremos nesta aula, não busca veri�car se uma ou mais a�rmações são verdadeiras, mas se o modo como as a�rmações são organizadas é válido. No programação, um dos maiores desa�os é como representar as informações do mundo real que são necessárias para a operação correta de um sistema. Assim, o estudo da lógica nos servirá para compreender a linguagem de representação de informações do mundo real assim como validar e organizar as instruções nos algoritmos. A lógica é um extenso campo subdividido em diversos ramos. Entre eles, podemos destacar a lógica clássica (também chamada de lógica aristotélica em referência a Aristóteles), que é composta em alguns princípios elementares que de�nem suas regras: O princípio da identidade: este princípio, um tanto óbvio, a�rma que algo é sempre algo. Isto é, a = a e b = b; O princípio da não contradição: estabelece que se uma a�rmação é falsa, sua contraditória deve ser verdadeira. Ou seja, se uma a�rmação A é verdadeira e outra a�rmação B é o contrário de A, então B deve, obrigatoriamente, ser falsa; O princípiodo terceiro excluído: estabelece que uma a�rmação não pode ser falsa e verdadeira ao mesmo tempo. Assim, uma vez de�nidos os princípios, é preciso de�nir o que é uma proposição. Uma proposição lógica é uma a�rmação, uma declaração de algo. Mas, atenção, pois nem toda sentença é uma proposição lógica. Por exemplo: "Feliz ano novo" é uma sentença exclamativa e não declarativa e, portanto, não é uma proposição. Para identi�car uma proposição é preciso sempre pensar que deve ser possível atribuir um valor lógico, isto é, uma proposição será sempre verdadeira ou falsa. Por exemplo: "5 é menor que 3". Neste caso há uma declaração e a proposição em questão tem valor lógico falso, pois 5 não é menor que 3. Um outro exemplo de proposição é: "O Brasil é o maior país da América do Sul e o Amazonas é o maior estado do Brasil". Neste caso, temos duas proposições que formam uma proposição composta. Como podemos veri�car, as duas proposições simples são verdadeiras e, portanto, a proposição composta também é verdadeira. Disciplina Algoritmos e Lógica de Programação Por �m, podemos observar um último elemento importante que abordaremos em maior profundidade a seguir que são os conectores. A proposição composta anterior foi formada por meio do conector e, que uniu as duas proposições menores. Os conectores que estudaremos são conjunção, disjunção, negação e condicional. A conjunção é também representada pelo e, a disjunção pelo ou, a negação pelo não e a condicional pelo se. Elementos da lógica proposicional A lógica proposicional é baseada no estudo dos valores lógicos, sentenças e a�rmações que se representam por meio de proposições, como você observou no bloco anterior. Assim, você verá como essas sentenças declarativas podem ser relacionadas, formando proposições compostas em que o valor lógico depende dos valores de cada variável. Neste sentido, vamos aprofundar o conhecimento de cada uma delas para, no último bloco, analisar a aplicação desses conceitos por meio da tabela verdade. Disciplina Algoritmos e Lógica de Programação Negação A primeira das relações a ser estudada é a mais simples, a negação. Nesta operação, se uma variável p tem certo valor lógico, sua negação (representada por ~p) terá o valor oposto. Por exemplo, dada a proposição: p: o céu é amarelo Sua negação será: ~p: o céu não é amarelo A negação pode ser aplicada a uma variável isolada ou em proposições com mais variáveis. Conjunção A próxima operação analisada é a conjunção, que necessita de duas variáveis para sua aplicação. A conjunção nada mais é do que o conectivo que representa a intersecção, ou então, na língua portuguesa o E, isto é, uma coisa e outra. Por exemplo, tomando duas proposições p e q: p: Brasília é a capital do Brasil q: Buenos Aires é a capital da Argentina Neste caso, a conjunção é representada da seguinte forma: p^q: Brasília é a capital do Brasil e Buenos Aires é a capital da Argentina E, como ambas as proposições são verdadeiras a proposição resultante também é. Disjunção Outro conectivo muito importante é a disjunção, que representa a união da matemática, ou, em língua portuguesa, o OU. Mas atenção: a disjunção será verdadeira quando uma das variáveis for verdadeira ou ambas forem verdadeiras. Como exemplo temos as duas proposições p e q: p: a água é transparente q: o mar é vermelho Deste modo, a disjunção é representada da seguinte forma: p V q: a água é transparente ou o mar é vermelho Condicional e bicondicional Outros dois conectivos fundamentais para o estudo da lógica são o condicional e o bicondicional. Como o nome indica, a operação condicional representa uma condição e pode ser lida como se p então q (indicado pela seta à). Por exemplo, p: choveu hoje q: o asfalto está molhado Assim, a condicional é representada por: p à q: se choveu hoje então o asfalto está molhado De modo análogo, temos a bicondicional, que é a condicional aplicada a ambas as direções e lida como p se e somente se q(representada por <->). Como exemplo temos: p: a é primo q: a é divisível por 2 Neste caso, a bicondicional é representada por: p <-> q: a é primo se e somente se a é divisível por 2 Que, observando os valores lógicos de p e q, é falso. Disciplina Algoritmos e Lógica de Programação Desse modo, você conheceu os principais conectivos lógicos da lógica proposicional que conformam o arcabouço que auxilia na compreensão e no desenvolvimento do pensamento algorítmico necessário para a programação. A tabela verdade e alguns exemplos Agora, veremos a aplicação dos conceitos da lógica por meio de exemplos e do uso da tabela verdade para a validação das proposições. Tabela verdade A representação mais interessante no início dos estudos da lógica proposicional é a tabela verdade, pois permite avaliar os valores lógicos resultantes das operações entre as proposições de maneira mais direta. A tabela é formada por colunas, sendo uma para cada variável proposicional e uma ou mais colunas para a proposição composta resultante, a depender do seu tamanho. No nosso caso, utilizaremos apenas a tabela com três colunas, conforme o exemplo a seguir, que representa a operação E indicada pelo operador ^. Observe que temos duas variáveis, p e q e, para cada uma, há 4 linhas com os possíveis valores lógicos. A terceira coluna corresponde à proposição composta p ^ q e possui os valores de todas as combinações possíveis entre os valores lógicos de cada variável. Disciplina Algoritmos e Lógica de Programação Tabela 1 | Tabela verdade da conjunção. Fonte: elaborada pelo autor. Observe que a primeira linha interna da tabela tem a variável p com valor falso (F), a variável q também com F e, na terceira coluna, o resultado da operação p ^ q com ambas as variáveis F, que resulta em F. Na segunda linha, quando p é verdadeiro (V), q é F, o resultado de p ^ q é F, a�nal, para a conjunção ser verdadeira, é necessário que ambas as proposições sejam verdadeiras, o que ocorre apenas na última linha da tabela. A seguir temos a tabela da disjunção, isto é, dados p e q, a operação p V q. É importante lembrar que a disjunção é a operação também conhecida como OU, ou seja, o resultado será verdadeiro quando uma das duas proposições forem verdadeiras (ou ambas) – como observamos nas três primeiras linhas – e falso quando nenhuma das duas forem verdadeiras, conforme observamos na primeira linha da tabela. Tabela 2 | Tabela verdade da disjunção. Fonte: elaborada pelo autor. Fonte: elaborada pelo autor. É importante observar que a aplicação da tabela verdade é útil em muitos casos, mas pode se tornar inviável a depender do número de variáveis que compõem a proposição. Suponha que tenhamos 10 proposições simples formando uma proposição composta por meio de operadores lógicos. Qual seria o número de linhas da tabela verdade? Para responder a essa questão é preciso observar que o número de linhas de uma tabela com uma única variável será 2, pois há apenas duas combinações possíveis. A tabela as seguir ilustra a tabela verdade com apenas a variável p formando a proposição ~p, que é a negação de p. Disciplina Algoritmos e Lógica de Programação Tabela 3 | Tabela verdade da negação. Fonte: elaborada pelo autor. Fonte: elaborada pelo autor. Assim, retornando ao questionamento, uma tabela com uma variável possui 2 linhas, uma tabela com duas variáveis possui 4 linhas, uma tabela com 3 variáveis terá 8 linhas. Forma-se um padrão que é representado pela expressão , portanto uma proposição composta por 10 variáveis terá 2¹⁰ linhas, ou 1024 linhas, o que torna difícil sua representação para muitas variáveis. Videoaula: De�nições de lógica Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, no vídeo desta aula abordaremos alguns conceitos da lógica, sua de�nição e elementos práticos de como manipular e validar argumentos por meio de exemplos e da construçãoda tabela verdade. Saiba mais Disciplina Algoritmos e Lógica de Programação O estudo da lógica proposicional pode ser complementado por estudos paralelos e pela prática em forma de exercícios. Desse modo, seguem alguns links com jogos educativos para praticar seu conhecimento em relação aos conceitos apresentados: Lógica Proposicional Clássica - Quiz com exercícios sobre lógica. Raciocínio Lógico - Conceitos Básicos – I - Quiz com perguntas. Referências https://quizizz.com/admin/quiz/5e184173be7d73001c424bf7/logica-proposicional-classica https://www.quiz.com.br/quiz/716/raciocinio-logico-conceitos-basicos-i/ https://www.quiz.com.br/quiz/716/raciocinio-logico-conceitos-basicos-i/ Disciplina Algoritmos e Lógica de Programação LABRA, J. E.; FERNÁNDEZ, A. I. Lógica proposicional para informática. Cuaderno Didáctico, n. 12, 1998. MORTARI, C. A. Introdução à lógica. Unesp, 2001. Aula 3 Elementos fundamentais de programação Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante. Nesta aula você terá contato com os primeiros elementos necessários para iniciar o desenvolvimento de programas de computador, o que será essencial para a evolução na sua aprendizagem. Veremos como os algoritmos formam a base da computação e são fundamentais para que um sistema possa ser executado de maneira e�ciente e adequada. Veremos também elementos estruturantes para a produção de códigos como os principais operadores aritméticos, lógicos e relacionais, e a noção e manipulação de variáveis e constantes. Esperamos que este material contribua para que seus estudos na introdução à programação sejam completos e auxiliem em sua vida acadêmica e pro�ssional. Bons estudos! Os algoritmos na programação Disciplina Algoritmos e Lógica de Programação A computação tem como objetivo central a resolução de problemas pelo uso de máquinas potentes que são capazes de realizar bilhões de operações por segundo. E para que essas máquinas e esses equipamentos possam realizar seus cálculos e operações corretamente é necessário que as instruções sejam estruturadas de maneira lógica. Para isso, cabe aos programadores a tarefa de escrever as instruções a serem executadas. Assim, programar não é uma tarefa simples, pois exige conhecimentos sobre os equipamentos, linguagens de programação e, principalmente, sobre as melhores maneiras de resolver os problemas. Neste sentido, antes de escrever as dezenas, centenas ou milhares de linhas de código para um sistema computacional, é fundamental o estudo e planejamento da solução e de sua lógica, para só então transformá-la em programas de computador. E é aqui que são desenvolvidos os algoritmos, que são as instruções de um programa em sequência e ordem determinadas, as quais garantem que uma entrada de dados será processada e resultará em uma saída que deve resolver o problema. É análogo a uma receita de bolo, em que o algoritmo deve instruir o cozinheiro ou cozinheira como processar os ingredientes e transformá-los em um bolo perfeito. Desse modo, faz-se essencial estudar como desenvolver um bom algoritmo e conhecer as ferramentas utilizadas para construí-los e transformá-los em código. Para tanto, nesta aula abordaremos alguns dos elementos para darmos início à construção de códigos, como os operadores aritméticos, operadores relacionais, operadores lógicos, variáveis e constantes. Em linhas gerais, os operadores possibilitam manipular e relacionar dados. Estes dados podem ser de vários, tipos: numéricos, textuais, lógicos, entre outros. E, na programação, a lógica de Disciplina Algoritmos e Lógica de Programação manipulação segue a lógica matemática que você conhece do ensino médio. Assim, como os dados podem sofrer alterações durante o algoritmo, há estruturas conhecidas como variáveis que servem para armazenar temporariamente um dado valor de dado tipo, de acordo com o que o programador de�nir. Essas variáveis, como o nome indica, podem sofrer variações em seus valores durante a execução do programa, diferente das constantes, que são dados imutáveis. Ressaltamos a importância deste momento do aprendizado, pois a manipulação correta de variáveis, por exemplo, é a base para a execução e�ciente de um programa de computador. Imagine, por exemplo, um programa de computador para orientar o lançamento de foguetes espaciais. São inúmeros cenários e fatores que podem decidir o sucesso ou fracasso do lançamento que devem ser todos considerados para o desenvolvimento do sistema. Como são milhares ou milhões os fatores que podem ser transformados em dados e analisados pelos programas, é dever do programador criar algoritmos corretos e e�cientes utilizando corretamente as variáveis e as operações pois um programa com excesso de variáveis pode levar a estourar a capacidade de memória, e um algoritmo com operações em excesso pode sobrecarregar a capacidade de processamento. São detalhes como este que fazem diferença tanto no mercado de trabalho quanto na vida acadêmica de computação e que iniciaremos o estudo nesta aula. O uso de operadores e variáveis Vamos aprofundar os conhecimentos sobre os operadores, variáveis e constantes, de�nindo cada um deles. Operadores aritméticos Disciplina Algoritmos e Lógica de Programação Os operadores aritméticos são aqueles utilizados para realizar cálculos aritméticos, da mesma maneira que você aprendeu na matemática. Neste bloco veremos os 4 principais: adição, subtração, divisão e multiplicação: 1. Adição O operador de adição é o símbolo +. Para utilizá-lo, basta relacionar dois elementos sejam eles variáveis, constantes ou números. Por exemplo: a expressão 3 + 2 é uma adição válida, assim como 3 + num, desde que a variável num seja do tipo numérico. É possível também associar duas variáveis como num1 + num2, ou então variáveis e constantes, como em num2 + NUM3, em que num2 é uma variável e NUM3 uma constante. A ordem neste caso não faz diferença. 2. Subtração O operador da subtração é o símbolo -. Analogamente à adição, é possível relacionar números, variáveis e constantes, como 3 - 4, ou então num1 - num2, ou então NUM3 - 4. 3. Divisão O operador da divisão utilizado na maioria das linguagens de programação e em pseudocódigo é o /. Com ele é possível realizar divisões entre valores numéricos (números, variáveis e constantes). Assim como na matemática, também pode ser necessário o uso de parênteses para o correto resultado. Por exemplo, a divisão 3 + 4/2 é diferente de (3+4)/2. Uma observação importante é que a divisão de números inteiros geralmente resultará um um resultado inteiro, portanto, é preciso estar atento ao tipo das variáveis e números utilizados. 4. Multiplicação O último operador aritmético analisado é o de multiplicação, com o símbolo *. Neste caso, assim como na divisão, é preciso estar atento ao uso de parenteses. Por exemplo, 5 * 2 - 3 é igual a 7, já 5 * (2 - 3) é igual a 5. Uma característica importante, assim como na matemática, é a precedência dos operadores, pois a divisão e a multiplicação são realizadas antes da soma e da subtração. Com base no que vimos, um exercício interessante é descobrir qual o valor da seguinte expressão: 4 - (5 * 2) / 5 ? Operadores relacionais Os operadores relacionais servem para testar os valores lógicos de uma dada expressão, isto é, se a expressão é verdadeira ou falsa. 1. Igualdade Para testar a igualdade, utilizaremos o símbolo ==, como no exemplo: 5 == 7. Neste caso, o resultado da expressão é falso, pois 5 não é igual a 7. 2. Diferença Disciplina Algoritmos e Lógica de Programação Para testar a diferença, utilizamos o operador !=, como no exemplo 5 != 7. Neste caso, o resultado da expressão é verdadeiro, pois 5 é diferente de 7. 3. Maior e menor Já para testar se um valor é maior ou menor que outro, utilizamos os mesmos operadores que a matemática, > para testar se um valor é maior que outro e < para testar se um dado valor é menor que outro. Por exemplo, 5 < 2 possui valor lógico falso, pois não é verdade que 5 é menor que 2, enquanto 5> 2 retorna verdadeiro, pois de fato 5 é maior que 2. Ainda é importante salientar que é possível utilizar o símbolo >= e <= para testar se valores são maiores ou iguais e menores ou iguais a outros, respectivamente. Operadores lógicos Os operadores lógicos são utilizados, no nosso caso, para concatenar expressões, isto é, se uma expressão composta é verdadeira ou falsa. Por exemplo: se quisermos avaliar as expressões 4 > 5 e a expressão 5 > 6 pela conjunção, escrevemos da seguinte maneira: 4 > 5 && 5 > 6. Neste caso, o resultado será falso, já que ambas as expressões são falsas. No caso da disjunção utilizaremos o símbolo ||. Por exemplo: 5 > 3 || 6 >= 7. Neste caso, a expressão 5>3 é verdadeira e a expressão 6>=7 é falsa. Porém, a expressão completa 5 > 3 || 6 >= 7 é verdadeira, pois trata-se de uma disjunção. Variáveis e constantes Por �m, vamos conhecer um pouco mais sobre variáveis e constantes. Uma variável é um espaço na memória reservado para armazenar um valor de tipo pré- determinado. Por exemplo: se quisermos armazenar um número inteiro, devemos declarar uma variável com um nome que o programador escolhe e o tipo desta variável. Para declarar uma variável inteira e uma real, é possível indicar: num1: inteiro; num2: real; A partir de então é possível armazenar valores nestas variáveis, utilizá-las em expressões e até mesmo substituir seus valores. Já as constantes são valores �xos. Uma vez atribuídos valores para as constantes (que também recebem nomes e tipos), estes valores não podem mais ser modi�cados. Convenciona-se escrever as constantes em letra maiúscula, como no exemplo a seguir: NUM1: inteiro; NUM1 <- 5; A partir deste momento a constante NUM1 sempre conterá o valor 5. Exemplos de algoritmos completos Disciplina Algoritmos e Lógica de Programação Agora, você irá consolidar o conhecimento adquirido anteriormente por meio da aplicação da lógica de desenvolvimento de um algoritmo, a noção de operadores e a manipulação de variáveis na solução de problemas. A primeira etapa, conforme abordamos, é compreender o problema proposto. Vamos iniciar com um problema simples: imprimir a soma de dois números inteiros. Para isso, temos como entrada dois números, que precisamos salvar em duas variáveis, como no código a seguir: 1. num1: inteiro; 2. num2: inteiro; 3. soma: inteiro; 4. ler(num1, num2); Observe que nas três primeiras são declaradas as variáveis inteiras que utilizaremos. A seguir, é necessário utilizar o operador aritmético de adição para realizar a soma das variáveis e operador de atribuição para salvar o resultado na variável soma: Disciplina Algoritmos e Lógica de Programação 1. num1: inteiro; 2. num2: inteiro; 3. soma: inteiro; 4. ler(num1, num2); 5. soma <- num1 + num2; 6. imprime(soma) Na linha 5 realizamos a operação de soma e, na linha 6, imprimimos na tela o resultado calculado. Agora passemos a um exemplo mais completo: ler 5 números inteiros e imprimir na tela quantos números positivos e negativos. Para isso, é preciso inicialmente fazer a leitura de cada número. Quando um número é lido, é necessário salvar em uma variável, que neste caso será do tipo inteiro. Em seguida, é necessário utilizar o operador relacional para comparar se o número é maior ou menor que zero e então incrementar a variável correspondente, conforme o pseudocódigo a seguir: 1. contador: inteiro; 2. num: inteiro; 3. qtdePositivos: inteiro; 4. qtdeNegativos: inteiro; 5. contador <- 0, qtdePositivos <- 0, qtdeNegativos <- 0; 6. enquanto contador < 5 faça: 7. ler(num) 8. se num > 0 então: 9. qtdePositivos <- qtdePositivos + 1; Disciplina Algoritmos e Lógica de Programação 10. se num < 0 então: 11. qtdeNegativos <- qtdeNegativos + 1; 12. 13. imprima(qtdePositivos, qtdeNegativos); Agora vamos compreender o código acima. Nas linhas 1 a 4 são declaradas as variáveis que serão utilizadas, bem como o tipo de cada uma, que no caso são inteiras. A variável contador servirá para contar a quantidade de números lidos; as variáveis qtdePositivos e qtdeNegativos servem para contar a quantidade de números positivos e negativos, respectivamente; a variável num armazena cada número lido por vez. Na linha 5, há a inicialização dos valores de cada variável utilizando o operador de atribuição. A linha 6 declara um laço de repetição, assunto que será abordado em aulas futuras. Entre a linha 7 e a linha 11, o algoritmo em si, conforme explicado anteriormente, é executado com sua lógica de comparação e incremento das variáveis. E, por �m, na linha 13 há a impressão do resultado. Observe que no decorrer do código utilizamos os operadores aritméticos de adição, os operadores relacionais de maior e menor e operador de atribuição. Um exercício interessante para �xar ainda mais o conteúdo é reler o código e marcar todas as ocorrências de cada operador indicando seu tipo. Desse modo você aprendeu a manipular variáveis e operadores para construir algoritmos básicos utilizando pseudocódigo. Videoaula: Elementos fundamentais de programação Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, no vídeo desta aula abordaremos a importância de pensar em algoritmos, como desenvolver um algoritmo e�ciente, assim como os principais elementos que o constituem como variáveis, constantes e os principais operadores. Disciplina Algoritmos e Lógica de Programação Saiba mais O pensamento algorítmico é fundamental para um bom programador. Nesse sentido, uma das maneiras de entrar no mundo dos códigos é por meio dos jogos. CodeCombat - Jogo online para aprender a programar. CodinGame - jogo que envolve programação em várias linguagens. Referências https://codecombat.com/ https://codecombat.com/ https://www.codingame.com/start https://www.codingame.com/start Disciplina Algoritmos e Lógica de Programação DASGUPTA, S.; PAPADIMITRIOU, C.; VAZIRANI, U. Algoritmos. Porto Alegre: AMGH Editora, 2009. ZIVIANI, N. et al. Projeto de algoritmos: com implementações em Pascal e C. Luton: Thomson, 2004. Aula 4 Algoritmos Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante. Nesta aula você terá um contato mais aprofundado com a construção e o desenvolvimento dos algoritmos. Serão introduzidos conceitos importantes de representação de algoritmos antes do momento da implementação utilizando linguagens de programação. A�nal, você deve se perguntar se um algoritmo só pode ser implementado utilizando uma linguagem especí�ca como a C, Java ou outras. E, para isso, mostraremos as técnicas de descrição narrativa e pseudocódigo, além de abordar a declaração de variáveis e entrada e saída de dados por meio delas. Bons estudos! Construção de algoritmos Disciplina Algoritmos e Lógica de Programação Estudante, neta aula, você aprenderá mais algumas características dos algoritmos que são importantes neste momento do início da sua jornada pelo mundo da programação. Você já aprendeu que para desenvolver uma solução para qualquer problema computacional é preciso compreender o problema, esboçar uma solução e aí então iniciar a escrita. Neste momento, introduziremos duas maneiras de escrever o projeto de algoritmos: a descrição narrativa e o pseudocódigo. Vale ressaltar que ambas as técnicas não são programas em linguagem de máquina, isto é, que podem ser compilados e executados, mas, sim, instruções redigidas em ordem e estrutura de�nidas para que a lógica da programação esteja clara para futuros desenvolvimentos. Neste sentido, podemos a�rmar que essas técnicas assemelham-se a um esboço do código �nal, apresentando os principais passos para resolver um problema em um nível de abstração mais alto, em que detalhes da implementação por vezes não estão presentes. Por isso, esse tipo de representação pode ser chamado de também de alto nível,pois o nível de abstração é maior, em oposição às linguagens de baixo nível, que são linguagens mais próximas à linguagem utilizada para a manipulação direta das estruturas físicas do computador. Assim, a de�nição da descrição narrativa pode ser ampliada para a representação passo a passo em linguagem natural das instruções do algoritmo e o pseudocódigo, de modo muito similar, da descrição dos passos em maiores detalhes e com maior capacidade de representação de estruturas. Por exemplo: com o pseudocódigo é possível explicitar a declaração de variáveis, isto é, deixar claro o nome da variável e seu tipo, como no exemplo a seguir: Disciplina Algoritmos e Lógica de Programação num1: inteiro; Neste caso foi declarada a variável chamada num1 do tipo numérico inteiro. Note que, na descrição narrativa, não há a preocupação em declarar as variáveis, mas apenas informar passos mais gerais. Outro elemento que a técnica de pseudocódigo permite aprofundar é a entrada e saída de dados, que são as operações de leitura e impressão, por exemplo. São estas operações que realizam a comunicação com cenários externos ao programa, pois recebem os dados que serão utilizados para a execução de um programa e, após seu processamento, devolvem o resultado em forma de saída. Uma maneira de representar a leitura de um número no pseudocódigo seria: ler(num1); Assim, informa-se ao leitor que será realizada a operação (função ou método) de leitura de algum valor e que este valor será armazenado na variável chamada num1. Analogamente, a saída de dados também é representada da seguinte forma: imprime(num1); Neste caso está representada uma chamada a uma operação de impressão da variável num1. Esta impressão poderia ser realizada em um terminal de saída, por exemplo, ou até mesmo gravada em arquivos. Etapas de desenvolvimento de algoritmos Disciplina Algoritmos e Lógica de Programação Você já estudou sobre a importância de um bom algoritmo para resolver um problema computacional, conheceu os principais operadores, as variáveis e constantes, porém pode se questionar qual o próximo passo. A�nal, o projeto de algoritmos mentalmente é importante, porém não su�ciente, já que é preciso documentar e escrever os passos utilizados. Contudo, como estamos introduzindo o ensino da programação, antes de iniciar os códigos diretamente utilizando uma linguagem de programação como o C, Java ou Python, você aprenderá duas técnicas úteis para representar o algoritmo de modo inicial, de modo a auxiliar no planejamento e visualização de uma solução para algum problema proposto. Descrição narrativa A técnica da descrição narrativa tem como função a descrição em linguagem natural (no nosso caso o português) dos passos necessários para resolver o problema proposto. Ou seja, trata-se da descrição do algoritmo em uma linguagem mais próxima da resolução mental proposta e, por isso, é a primeira forma de documentar e planejar um programa. Podemos pensar em uma receita que buscamos na internet como uma descrição narrativa, pois ali estão descritos os passos para realizar um prato em língua portuguesa, ou seja, é altamente compreensível para o ser humano mas não é capaz de executar um programa de computador. Para escrever uma descrição narrativa, basta inserir cada passo da solução por linha. Por exemplo, para calcular o menor número dentre dois números dados, o algoritmo em descrição narrativa seria o seguinte: 1. Ler os dois números Disciplina Algoritmos e Lógica de Programação 2. Comparar os números 3. Imprimir o menor Dessa maneira, nota-se que a descrição narrativa é mais enxuta e objetiva. Um elemento que aparece neste caso é a entrada e saída de dados. A entrada está representada na linha 1, em que a instrução de leitura de dois números é informada. Esta leitura pode ser do teclado ou de um arquivo. E a saída pode ser a impressão na tela, ou a gravação em algum arquivo Pseudocódigo O uso do pseudocódigo pretende utilizar a linguagem natural com maiores detalhes técnicos, indicando quais variáveis serão utilizadas e como as expressões serão formadas. Para resolver o mesmo problema anterior, o pseudocódigo seria o seguinte: 1. num1: inteiro; 2. num2: inteiro; 3. ler(num1, num2); 4. 5. se num1>num2: �. imprime(num2); 7. se num2 > num1: �. imprime(num1); Observe que neste caso deixamos claro quais as variáveis, seu tipo, como serão lidas e alguns elementos mais claros de sintaxe, como o uso de ponto e vírgula ao �m de cada linha. Apesar de possuir mais regras de sintaxe que a descrição narrativa, o pseudocódigo também não serve para ser executado como um programa de computador, mas sim para elucidar e auxiliar no planejamento de algoritmos. Algoritmos na prática Disciplina Algoritmos e Lógica de Programação Agora, veremos alguns exemplos práticos na construção de algoritmos utilizando a descrição narrativa e a técnica de pseudocódigo apresentadas anteriormente. Tomemos como base para a construção dos códigos o seguinte problema: você deve desenvolver um programa de computador para uma agência de monitoramento climático e foi solicitado que, com os dados de temperatura de sete dias da semana, você escreva um programa que calcule a média das temperaturas. Para iniciar o desenvolvimento do código, é preciso, inicialmente, estudar o problema e analisar as entradas do programa. Neste caso, o problema principal é calcular a média de 7 temperaturas e a solução é aplicar a fórmula da média, sendo dividir a soma dos valores pela quantidade de valores, no caso o número de dias da semana. Para analisar as entradas, observamos que o programa irá receber 7 valores de temperatura, que serão valores reais. Portanto, até o momento, já sabemos a fórmula que devemos implementar e os tipos dos valores utilizados que serão transformados em variáveis. Por �m, é preciso analisar qual será a saída do programa, isto é, qual o resultado. No nosso caso, o resultado será a impressão da média calculada. Desse modo, temos as condições necessárias para desenvolver o código. Iniciaremos mostrando o código em descrição narrativa: 1. Ler os 7 valores de temperatura 2. Somar os 7 valores 3. Dividir a soma dos valores por 7 4. Armazenar o resultado na média 5. Imprimir a média calculada Assim, é possível notar que o programa em descrição narrativa é simples e direto, evidenciado em linhas gerais os passos que serão efetuados, porém sem apresentar detalhes maiores, como Disciplina Algoritmos e Lógica de Programação as variáveis utilizadas. Em seguida, apresentamos o código em pseudocódigo: 1. temp1: real; 2. temp2: real; 3. temp3: real; 4. temp4: real; 5. temp5: real; �. temp6: real; 7. temp7: real; �. soma: real; 9. media: real; 10. 11. ler(temp1, temp2, temp3, temp4, temp5, temp6, temp7); 12. soma <- temp1 + temp2 + temp3 + temp4 + temp5 + temp6 + temp7; 13. media <- soma/7; 14. imprime(media); Em relação ao exemplo em pseudocódigo, é possível observar que o código tem mais detalhes que a descrição narrativa e é mais próximo a uma implementação real em linguagem de programação. Neste caso, são descritas quais as variáveis e quais seus tipos, como descrito das linhas 1 a 9, como se dá a entrada de dados, na linha 11, as operações em si, linhas 12 e 13 e a saída de dados na linha 14. Assim, você aprendeu duas técnicas para representar algoritmos que auxiliam no planejamento e projeto, etapas importantes para a futura implementação nas linguagens de programação. Videoaula: Algoritmos Disciplina Algoritmos e Lógica de Programação Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Neste vídeo você verá maiores detalhes sobre as técnicas de descrição narrativa e pseudocódigo por meio de mais um exemplo de cada, de modo a �xar este importante conteúdo. Também abordaremos as estratégias deconstrução de algoritmos utilizando variáveis e entrada e saída de dados. Saiba mais O uso de pseudocódigo é muito importante para visualizar a estratégia de resolução de problemas antes da implementação em si. Existem diversas ferramentas que auxiliam no aprendizado como a linguagem em pseudocódigo Portugol. Referências https://dgadelha.github.io/Portugol-Webstudio/ https://dgadelha.github.io/Portugol-Webstudio/ https://dgadelha.github.io/Portugol-Webstudio/ Disciplina Algoritmos e Lógica de Programação DASGUPTA, S.; PAPADIMITRIOU, C.; VAZIRANI, U. Algoritmos. Porto Alegre: AMGH Editora, 2009. ZIVIANI, N. et al. Projeto de algoritmos: com implementações em Pascal e C. Luton: Thomson, 2004. Aula 5 Revisão da unidade Introdução à lógica de programação Disciplina Algoritmos e Lógica de Programação Olá, estudante, nesta unidade, você conheceu os primeiros elementos da lógica de programação. São conceitos que lhe orientarão no restante de sua aprendizagem e por isso têm grande importância neste primeiro momento. A programação de computadores é fundamentada na noção de criar comandos e instruções para serem executados pelo computador em uma determinada ordem para resolver certo problema. Nesse sentido, você pode pensar no seu celular (que também é um computador) e quantos programas diferentes estão em execução quando ele está ligado. O sistema operacional, por exemplo, é um conjunto de programas que são executados com o objetivo de gerenciar a manipulação do hardware por você. Além disso, toda vez que um aplicativo é aberto, outros programas com centenas e milhares de comandos são postos em execução. Portanto, é possível notar o grau de complexidade que exige a perfeita execução de todos estes programas simultaneamente de modo que a operação seja harmônica. É preciso ordenar e gerenciar as instruções seguindo determinadas lógicas. É neste momento que o papel da lógica se faz presente. A�nal, as instruções devem estar postas em uma sequência que faça sentido, o que demanda uma estrutura logicamente organizada. Para isso, é importante ter em mente que os princípios da lógica proposicional são utilizados na programação. Dentre eles, os fundamentais são as operações lógicas de conjunção, disjunção, negação e condicional que estão presentes desde a manipulação dos circuitos até a programação em linguagens especí�cas. Neste sentido, a apreensão dos conceitos da lógica é fundamental para que o elemento central da programação seja dominado: o algoritmo. Um algoritmo é o elemento central para a Disciplina Algoritmos e Lógica de Programação construção de programas e�cientes. Trata-se da lógica de programação aplicada para resolução de um dado problema, ou seja, são as instruções e os comandos em uma determinada ordem. Uma analogia interessante para compreender o conceito de algoritmo é pensar em uma receita de bolo. Uma receita deve seguir passos bem de�nidos e especi�cados para atingir o resultado esperado, e caso uma das etapas não seja seguida, a chance de resultar em erro aumenta. Neste sentido, um algoritmo é uma sequência de passos que também devem ser seguidos corretamente pelo computador. Além disso, existem várias maneiras para representar algoritmos sendo que, no início da aprendizagem, é interessante se adaptar e utilizar a descrição narrativa e o pseudocódigo. A descrição narrativa é, como uma receita, a descrição dos passos realizados em língua portuguesa. Não são especi�cados detalhes das variáveis e outras estruturas, mas �ca clara qual a estratégia utilizada. Já o pseudocódigo, também em linguagem natural, pode especi�car maiores detalhes como os nomes e tipos das variáveis, além de utilizar uma sintaxe própria. Desse modo, com estes conceitos iniciais, sua jornada pela programação pode ser iniciada e esperamos que o aprofundamento destes conceitos somado às resoluções dos exercícios sirvam como uma base sólida de sua aprendizagem. Videoaula: Revisão da unidade Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo você irá relembrar os principais conceitos abordados na unidade de Lógica de Programação, com ênfase e exemplos sobre como conceituar e criar algoritmos e suas principais formas de representação. Estudo de caso Disciplina Algoritmos e Lógica de Programação Olá, estudante. Um dos grandes problemas da computação é encontrar o melhor caminho a ser seguido para algum caso especí�co. Por exemplo: qual é o melhor caminho que um caminhão deve percorrer para chegar mais rápido ao destino, considerando as melhores ruas, menos trânsito, entre outros aspectos. Questões deste tipo muito importantes e atuais que demandam muito estudo e que podem garantir um custo reduzido para empresas de entrega, por exemplo. Para contextualizar sua aprendizagem desta unidade, observe o cenário proposto: imagine que você foi contratado por uma empresa de logística para projetar a solução que encontre a melhor rota de entrega de mercadorias e alimentos. São 3 rotas disponíveis, a rota A, pela estrada, a rota B, por uma ferrovia e a rota C por uma hidrovia. Para cada viagem, há o ponto de partida, um ponto de abastecimento e um ponto de chegada. Além disso, são fornecidos os dados de distância entre os pontos para cada tipo de rota e a velocidade média de cada trecho para cada rota. Por exemplo: a rota B terá uma distância entre o ponto inicial até o ponto de abastecimento em que a velocidade média possui determinado valor e outra distância entre o ponto de abastecimento e o ponto de destino que pode possuir outra velocidade média. A questão é que, para cada nova entrega, os dados podem variar, pois o comprimento das rotas pode sofrer variações, assim como a velocidade de transporte, e que o tempo �nal deve ser calculado com base nos dados fornecidos. Desse modo, você está responsável por projetar uma algoritmo que, recebendo como entrada os dados informados acima, deve oferecer como resultado a rota mais rápida entre A, B ou C para uma certa entrega considerando o menor tempo. Assim, você deve escrever, em formato de descrição narrativa, um algoritmo capaz de resolver o problema. Disciplina Algoritmos e Lógica de Programação _______ Re�ita A programação de computadores está presente em todos os ambientes no mercado de trabalho atualmente. Seja para otimizar os gastos, reduzir custos, salvar vidas, garantir o entretenimento, entre outras. Um dos fatores que aparece cada vez mais é a dimensão ética da computação. A�nal, cada vez mais a programação busca automatizar tarefas que são realizadas por seres humanos e que, por muitas vezes, acabam extinguindo postos de trabalho, podendo ocasionar em maiores taxas de desemprego. Um dos casos é o abordado neste estudo de caso, em que tarefas de engenheiros e gerentes de logística são executados por algoritmos e máquinas com elevado processamento. É interessante re�etir quanto o mercado de trabalho está sendo alterado com a tecnologia, novas vagas surgem enquanto outros postos de trabalho tradicionais são substituídos pelos computadores. A sociedade como um todo precisa estar ciente destas transições e se preparar para vivenciá-las. Videoaula: Resolução do estudo de caso Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Para resolver o estudo de caso proposto, deve-se lembrar que a descrição narrativa é a forma de representação de um algoritmo utilizando a linguagem natural, muito parecido com uma receita de bolo, por exemplo. No problema apresentado, você foi contratado por uma empresa para criar um programa que responda qual a melhor rota (com o menor tempo de trajeto) a se tomar dadas a distância do ponto de partida até o ponto de abastecimento; a distânciado ponto de abastecimento até o destino; e a velocidade média entre os pontos de início, abastecimento e destino. É preciso salientar que podem existir soluções diferentes desta apresentada que também resolvem o problema e poderiam ser utilizadas em situações reais. Contudo, o foco da solução deve ser o cálculo do menor tempo resultante calculado. 1. Ler os dados de cada rota; 2. Para cada rota: 3. calcular o tempo gasto do ponto inicial ao ponto de abastecimento; 4. calcular o tempo gasto do ponto de abastecimento ao destino; 5. somar os tempos; 6. salvar o tempo total calculado. Disciplina Algoritmos e Lógica de Programação 7. Após calcular o tempo total de cada rota: 8. comparar a rota A com a rota B e salvar a que tiver o menor tempo; 9. comparar a com menor tempo calculado com a rota C e salvar a menor; 10. Imprimir na tela a rota com menor tempo. Dessa maneira, independentemente da fórmula utilizada para o cálculo do tempo nas linhas 3 e 4 (que pode utilizar a distância e a velocidade média), o nosso algoritmo sempre irá realizar o cálculo para cada uma das rotas e comparar todas com todas. Dessa maneira, ao �nal, é possível garantir que a rota com menor tempo foi calculada. Observe que, como utilizamos a técnica de descrição narrativa, alguns detalhes não foram explicitados, como a própria fórmula de cálculo. Isso se deve ao fato de essa ser uma primeira aproximação ao problema, que nos permite pensar a solução sem perder tempo em alguns detalhes. Um próximo passo seria descrever utilizando pseudocódigo, o que deixaria mais claro quais estruturas e fórmulas seriam utilizadas. Assim, �cou demonstrado que o primeiro passo é representar a solução de modo ainda incipiente, o que já permite a toda a equipe envolvida no projeto ter uma noção mais ampla do tipo do problema e das estratégias de resolução. Resumo Visual Disciplina Algoritmos e Lógica de Programação Referências DASGUPTA, S.; PAPADIMITRIOU, C.; VAZIRANI, U. Algoritmos. Porto Alegre: AMGH Editora, 2009. Disciplina Algoritmos e Lógica de Programação ZIVIANI, N. et al. Projeto de algoritmos: com implementações em Pascal e C. Luton: Thomson, 2004. , Unidade 2 Elementos de algoritmos Aula 1 Representações de algoritmos Introdução Olá, estudante! Nesta aula você aprenderá a de�nição de algoritmos, sua aplicabilidade e conceito como peça fundamental para desenvolvimento de um programa de computador. Também irá estudar quais as principais propriedades de um algoritmo e como �uxogramas podem ser criados para representar algoritmos. Disciplina Algoritmos e Lógica de Programação Todo este conhecimento é a base fundamental para a construção de softwares, já que você exercitará a criação da lógica necessária para o processo de desenvolvimento de novas aplicações ou manutenção em aplicações já existentes. Lembre-se que o seu aprendizado só dependerá de você, então, não se limite apenas ao estudado em aula, mas busque, de forma proativa, ampliar seus conhecimentos. Bons estudos! O que são algoritmos e quais suas aplicabilidades Disciplina Algoritmos e Lógica de Programação Em seu cotidiano, todas as ações que você executa têm uma sequência lógica de passos para sua conclusão. Mesmo que, de forma inconsciente, você não precise �car raciocinando sobre a ordem de execução de cada passo, em algum momento, alguém te ensinou a sequência que você reproduz. A esta sequência lógica de passos para executar uma ação denominamos algoritmo. Os passos necessários para obter um resultado de uma ação, como, por exemplo, preparar uma receita culinária, devem seguir uma sequência lógica com o objetivo de estabelecer uma ordem no pensamento das etapas que deverão ser seguidas para que a refeição, ao �nal do processo, esteja pronta. Segundo o que apresenta Forbellone (1993), a sequência �nita e ordenada de passos necessária para se atingir um objetivo (como trocar um pneu, preparar uma receita culinária ou sair de casa para ir ao trabalho) é o que se conhece como um algoritmo. Um programa de computador (software) é a representação, por meio de uma linguagem de programação, de uma lógica que irá resultar em um comportamento esperado para o programa, como, por exemplo, o cadastro de dados de uma pessoa em uma clínica médica, marcação de consultas a partir de uma agenda disponível de um médico, dentre outros exemplos do nosso cotidiano. Então, antes da construção de qualquer programa de computador, é necessário entender o processo de raciocínio lógico e a de�nição dos passos necessários para a construção de um algoritmo. Como exemplo de um algoritmo simples para, por exemplo, abrir uma porta trancada, você pode listar os seguintes passos: 1. selecionar a chave correta para a fechadura que se deseja abrir; 2. inserir a chave na fechadura; 3. se a chave encaixou corretamente, então: 3.1 gire a chave no sentido anti-horário uma volta; 3.2 tente abrir a porta. Se a porta abriu, então: 3.2.1 porta aberta com sucesso. 3.3 Se a porta não abriu, então: 3.3.1 Volte ao passo 3.1 Quando os passos, em sua respectiva sequência lógica, são listados, é possível perceber, por exemplo, que cada tarefa tem um certo nível de complexidade e um determinado padrão de comportamento (uma porta que possua chaves mecânicas sempre seguirá a mesma lógica para sua abertura). É importante mencionar que, em muitos casos, será necessário que o usuário forneça algumas informações de entrada ao algoritmo (como nome, endereço e RG de uma pessoa que será cadastrada como aluna em uma instituição de ensino, por exemplo), que passará por um processamento (como uma validação, por exemplo), gerando um resultado (efetuar o cadastro do aluno com sucesso). Para que a lógica de um algoritmo possa ser representada de modo que �que claro para outras pessoas que conheçam lógica de programação e algoritmos, você poderá utilizar um �uxograma, ou seja, a representação grá�ca de um �uxo de passos sequenciais, por meio do uso de símbolos com signi�cados especí�cos. Disciplina Algoritmos e Lógica de Programação Conforme nos apresenta Pressman (1995), a construção de um �uxograma é um método bastante utilizado para representação da lógica de um algoritmo por ser simples, fazendo uso de losangos para representação de uma condição de controle e setas para mostrar qual o �uxo a seguir, conforme cada alternativa possível que parta do �uxo de condição. Uma sequência de passos pode ser representada por meio de retângulos. Detalharemos a representação utilizando �uxogramas em um momento posterior neste texto. Principais características de um algoritmo Toda lógica que se pretende transferir a um programa de computador poderá ter diferenças na forma como as etapas são ordenadas para se atingir o objetivo desejado, a depender da maneira pela qual quem está construindo o algoritmo ordene seu pensamento lógico. Porém, existem alguns pontos fundamentais para garantir que um algoritmo seja compreendido facilmente e, caso necessário, sofra alterações evolutivas (quando se deseja acrescentar novas funcionalidades a uma aplicação), adaptativas (quando se deseja ajustar funcionalidades já existentes para o que o usuário considera mais adequado para resolver seus problemas) ou corretivas (quando é feita correção de erros detectados durante a utilização do programa). A estes pontos damos o nome de propriedades de um algoritmo. Disciplina Algoritmos e Lógica de Programação Quando a construção de um algoritmo se preocupa em garantir que as principais propriedades serão respeitadas, o processo de representação deste algoritmo em �uxograma será facilitado, garantindo maior probabilidade de sucesso ao longo do processo de codi�cação (implementação) de sua lógica. Uma das propriedades dos algoritmos é a sequenciação, já que, para que se atinja um objetivo especí�co (como cadastrar os dados um usuário, extrair um relatório, etc.), é preciso que os passos necessáriospara a concretização da funcionalidade sejam de�nidos em uma ordem sequencialmente lógica. Por exemplo: caso o seu algoritmo seja de cadastro de dados de um paciente, é preciso que uma tela contendo os campos que serão informados pelo usuário possa aparecer, seguindo-se do preenchimento destes campos e do envio para que possam ser validados (conforme as regras de negócio) e cadastrados. Caso o envio aconteça antes da etapa de informação dos dados, a sequência lógica será quebrada, não sendo possível alcançar o propósito �nal (cadastramento dos dados). A complexidade é outra propriedade importante para um algoritmo. Quanto mais simples os passos e a sequência lógica destes passos aconteçam, mais simples será seu algoritmo, sendo mais fácil de ser construído e mantido posteriormente. Um fator que aumenta a complexidade, de forma considerável, conforme apresenta Forbellone (1993), é a relação entre o que deve ser feito e o como deve ser feito, que pode levar a respostas tão complexas que não cheguem a nenhuma solução. Quando você perguntar “O quê?”, terá uma resposta direta e objetiva. Por exemplo: na pergunta “O que é um relógio?”, uma resposta objetiva seria similar a “instrumento que apresenta a passagem do tempo, ao longo de um dia”. Já a pergunta “Como é um relógio?”, por outro lado, poderá ter diferentes e irrelevantes respostas, como “objeto esférico com ou sem ponteiros, com tamanhos variados, que pode ser de parede, bancada ou de pulso”. A legibilidade é uma propriedade importante para garantir que outras pessoas irão conseguir ler o seu algoritmo e ter um mesmo entendimento a respeito de seu objetivo. Quanto maior for a legibilidade de um algoritmo, mais facilmente ele será entendido e menor será sua complexidade. Outra propriedade importante de um algoritmo é a portabilidade. Construir um algoritmo que possa ser executado em diferentes sistemas operacionais e diferentes arquiteturas de máquina (hardware) é uma questão importante para englobar os mais diferentes per�s e tipos de usuários de uma aplicação. Um algoritmo, por ser apenas a representação de uma sequência lógica de passos que irão resolver um problema do mundo real do usuário, poderá ser escrito (implementado) utilizando diferentes linguagens de programação e para os mais diferentes ambientes de execução. Todas estas propriedades são importantes para garantir que, após a de�nição de quais passos serão necessários para se atingir um objetivo com um algoritmo, a sua representação em �uxogramas seja feita de forma fácil, contendo apenas os passos estritamente necessários, sem maiores complexidades e de fácil manutenibilidade (facilidade de manutenção futura). Utilizando �uxogramas para a representação de algoritmos Disciplina Algoritmos e Lógica de Programação Algoritmos podem ser representados por meio de �uxogramas, como já mencionado, já que esta ferramenta possui os elementos grá�cos necessários para representação de uma sequência de passos, com representação para tomada de decisões e �uxo de repetição de passos. Todo �uxograma tem um início e um �m, sendo o início representado pela primeira ação (ou passo) a ser executada para se atingir o objetivo da lógica estruturada. É importante que você de�na um “gatilho” para que a sua lógica seja iniciada, ou seja, uma ação que deverá ser feita pelo usuário (como o clique em um botão de menu, a abertura de uma tela contendo um formulário, dentre outras), para que a sequência de passos possa, então, seguir a partir desta ação inicial. Disciplina Algoritmos e Lógica de Programação Tabela 1 | Principais símbolos de um �uxograma. Fonte: elaborada pela autora. A Tabela 1 apresenta um resumo dos principais elementos que são utilizados para construção de um �uxograma. É possível, por exemplo, criar �uxos contendo apenas elementos sequenciais ou, em �uxos mais elaborados, contendo �uxos alternativos, que irão partir de tomada de decisões. A Figura 1 apresenta um exemplo de um �uxograma básico, sem estrutura de controle, apenas com um sequenciamento de passos do início ao �m. O início de todo �uxograma deve ser representado com um conector, que irá exibir qual será o primeiro passo para ser executado em busca do resultado esperado. Disciplina Algoritmos e Lógica de Programação Figura 1 | Representação de um �uxograma simples. Fonte: elaborada pela autora. Disciplina Algoritmos e Lógica de Programação A Figura 1 apresenta uma sequência de passos simples para o envio de um e-mail a um ou mais destinatários. O primeiro elemento do �uxo apresenta um conector, indicando que o processo será iniciado. Cada caixa retangular irá indicar um passo a ser executado, sendo ligadas por setas, que indicam a sequência que deverá ser seguida. Ao �nal do processo, um elemento que representa a conclusão do �uxo, sendo representado por um elemento ovalado, apresenta o objetivo concluído (que é o e-mail enviado). Para �uxos mais complexos, que incluem situações de tomadas de decisão ou �uxo de repetição de passos, elementos que representam os caminhos alternativos a serem seguidos podem ser inseridos no �uxo, conforme apresentado na Figura 2. Disciplina Algoritmos e Lógica de Programação Figura 2 | Fluxograma com tomada de decisão. Fonte: elaborada pela autora. A Figura 2 apresenta uma sequência de passos para a abertura de uma porta, conforme exemplo apresentado em momento anterior neste texto. Após o conector que representa o início do Disciplina Algoritmos e Lógica de Programação processo ter sido inserido, então o �uxo se inicia com uma pergunta condicional sobre a chave, se é compatível com a fechadura da porta a ser aberta ou não. Caso seja compatível, o �uxo será alternado para o ramo da esquerda, seguindo pelas etapas de girar a chave, veri�car se a porta se abriu e, caso a porta não abra, então, o �uxo retornará para a etapa de girar chave no sentido anti-horário, repetindo os passos abaixo deste. Caso a porta se abra, então o �uxo será �nalizado. Uma pessoa que não tenha elaborado este �uxograma, ao realizar a leitura deste, deverá ter o mesmo entendimento dos passos e �uxos condicionais, o que caracteriza a propriedade de legibilidade do algoritmo. A partir de um �uxograma, deverá ser possível implementar sua lógica em qualquer linguagem de programação desejada. Videoaula: Representações de algoritmos Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo você aprenderá os principais conceitos e aplicações de um algoritmo, a importância da sequência lógica de passos para construção de um algoritmo, suas principais propriedades e a importância de cada propriedade. Saiba mais Disciplina Algoritmos e Lógica de Programação Com a ferramenta gratuita diagrams.net (draw.io), é possível criar �uxogramas de uma forma simples, sem a necessidade de criar contas ou realizar login. A ferramenta gratuita Portugol Webstudio é voltada para o teste da lógica de programação, em linguagem natural, para iniciantes no aprendizado de algoritmos. Você poderá ver um exemplo clicando no link “Abrir Exemplo” e, ao clicar em “Novo Arquivo”, poderá criar a sua própria lógica. Inicie a partir do exemplo Entrada e Saída à Olá, mundo. É o mais simples e o que você poderá reproduzir de forma mais fácil. A partir daí, vá seguindo com os demais exemplos, sempre tentando aglutinar os exemplos aprendidos em um mesmo arquivo. Referências https://app.diagrams.net/ https://dgadelha.github.io/Portugol-Webstudio/ Disciplina Algoritmos e Lógica de Programação FORBELLONE, A. L. V.; EBERSPÄCHER, H. F. Lógica de programação – A construção de algoritmos e estrutura de dados. São Paulo: Makron Books, 1993. PRESSMAN, R. S. Engenharia de software. São Paulo: Makron Books, 1995. Aula 2 Execução sequencial e estruturas de decisão Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Nestaaula, você aprenderá a estrutura básica necessária para elaboração de um programa de computador, quais são as estruturas sequenciais que podem ser utilizadas e quais elementos podem ser utilizados como formas de decisão no seu código, que irão permitir que o �uxo principal seja alternado para outro �uxo, conforme o teste de uma condição especí�ca (que poderá dar verdadeiro ou falso como resultado). Ao �nal desta aula, você será capaz de criar um código simples, contendo estruturas sequenciais e de decisão. Lembre-se que você é responsável pelo seu aprendizado, então, não se limite apenas ao visto em aula, mas busque enriquecer seus conhecimentos por meio de outras fontes con�áveis. Bons estudos Estruturas sequenciais e condicionais de um algoritmo Disciplina Algoritmos e Lógica de Programação Um algoritmo, para que possa ser legível e interpretado por um computador ou outra pessoa, precisa seguir uma estrutura básica, mantendo sua organização lógica e seguindo um �uxo principal, que irá culminar no resultado (objetivo �nal) desejado. Então, é preciso que as estruturas sequenciais, como a declaração de variáveis (endereços de memória que irão receber valores que variam ao longo do tempo) e declaração de constantes (informações que são de�nidas uma única vez na lógica, não sofrendo alterações ao longo do tempo) precisam estar organizadas logo no início do seu algoritmo. É possível de�nir valores para as variáveis declaradas, por meio do processo de atribuição, que pode ser proveniente da execução de uma operação matemática ou um número já de�nido. Uma característica de uma variável é a sua tipi�cação, ou seja, ela irá armazenar valores de um mesmo tipo de dados, que pode ser inteiro, real (ponto �utuante), caractere (que armazena texto, podendo ser um ou mais caracteres) e lógico (também conhecido como booleano, por armazenar os valores verdadeiro ou falso). Então, se uma variável é declarada como inteiro, ela não poderá armazenar números com pontos �utuantes ou informações textuais, pois irá contra a sua tipi�cação. Disciplina Algoritmos e Lógica de Programação Figura 1 | Fluxo para declaração de variáveis. Fonte: adaptada de Forbellone (1995). A Figura 1 apresenta a forma como uma variável deve ser declarada. Primeiro, você deverá de�nir qual será o tipo de dado (ou tipo primitivo) que ela irá armazenar, seguindo-se do caractere “:” e do nome (identi�cador) que irá representar a sua variável. Para �nalizar a sua declaração, você deverá utilizar o caractere “;”, indicando a �nalização do comando. Um exemplo simples de declaração de variáveis. O exemplo mostra algumas variáveis sendo declaradas com seus respectivos tipos primários associados. Então, temos uma variável que irá armazenar texto, com identi�cador nomePaciente, uma variável que irá armazenar números inteiros, com identi�cador idade, uma variável que irá armazenar números com ponto �utuante, com identi�cador valorConsulta e uma variável que irá armazenar um valor lógico (verdadeiro ou falso), com identi�cador ehPrimeiraConsulta. Com estas variáveis declaradas, você poderá solicitar informações (entrada de dados) ao usuário que executará sua aplicação ou armazenar resultado de operações matemáticas (cálculos utilizando números simples ou outras variáveis). Estas operações irão seguir uma sequência lógica, que irá representar os passos do seu algoritmo. A seguir veja um exemplo de um algoritmo contendo uma estrutura sequencial simples para ler e escrever um número informado pelo usuário. Disciplina Algoritmos e Lógica de Programação O �uxograma que representa uma condicional simples se deve ser elaborado conforme apresentado na Figura 2. Figura 2 | Fluxograma para uma estrutura de decisão simples. Fonte: elaborada pela autora. A Figura 2 apresenta o �uxo para uma condicional simples se. A partir do teste de uma condição, caso a resposta seja verdadeira, então uma sequência especí�ca de comandos deverá ser executada. Caso o resultado lógico do teste seja falso, então um outro conjunto de comandos poderá ser executado. Após o término de execução da estrutura condicional, o algoritmo irá retomar seu �uxo principal de passos até a sua conclusão. Iremos apresentar um exemplo prático em momento posterior nesta aula. Também é possível fazermos uma condição mais complexa, que envolva diferentes opções de resultado, conhecida como escolha. Um comando do tipo escolha irá avaliar o valor de uma Disciplina Algoritmos e Lógica de Programação variável simples declarada conforme uma lista de diferentes opções. A lógica do seu algoritmo, então, poderá ser alterada para a opção que o valor for igual ao valor contido na variável. A seguir veja a estrutura condicional complexa escolha. Com a estrutura condicional complexa escolha, cujo formato de declaração está apresentado, você poderá testar o valor de uma variável dentre um conjunto de valores, construindo uma lógica diferente para cada possibilidade de valor. Caso nenhuma das possibilidades listadas seja atendida, o �uxo irá seguir a lógica do caso contrário. O �uxograma que representa uma condicional complexa escolha segue o modelo apresentado na Figura 3. Disciplina Algoritmos e Lógica de Programação Figura 3 | Fluxograma para a estrutura condicional complexa escolha. Fonte: elaborada pela autora. A Figura 3 apresenta como deverá �car um diagrama de �uxo para uma condicional do tipo escolha. A escolha se dará a partir do valor que uma variável poderá assumir, sendo executado o bloco de instruções que irá corresponder ao valor já conhecido e que a variável esteja assumindo no momento do teste. Caso nenhum dos valores possíveis seja igual ao valor atual da variável testada, então a cláusula caso contrário terá suas instruções executadas (comportamento padrão). Como e quando utilizar cada tipo de estrutura em um algoritmo Disciplina Algoritmos e Lógica de Programação Vamos iniciar com um exemplo de algoritmo simples, para que você possa entender em qual momento poderá utilizar cada tipo de estrutura apresentada anteriormente. Caso você precise construir uma lógica para testar se a idade informada pelo usuário é menor ou maior que 60 anos, você irá utilizar uma estrutura condicional simples da seguinte forma: Caso a idade informada seja menor que 60 anos, então você deverá apresentar a mensagem “Idade menor que 60”; Caso a idade informada seja maior ou igual a 60, a mensagem apresentada deverá ser “Idade igual ou superior a 60”. Para transcrever a lógica acima apresentada para um algoritmo, você deverá utilizar uma estrutura condicional se – senão simples, como mostrado a seguir. Disciplina Algoritmos e Lógica de Programação Porém, no exemplo apresentado, não é possível saber se a idade informada é igual a 60 ou maior, caso entre na condição senão. Então, vamos alterar a lógica para apresentar uma mensagem personalizada para cada faixa etária, da seguinte forma: Caso a idade do usuário esteja entre 16 e 18 anos, você irá apresentar a mensagem “Olá, adolescente!”; Caso a idade do usuário esteja entre 19 e 59 anos, você irá apresentar a mensagem “Olá, adulto!”; Caso a idade do usuário esteja acima de 60 anos, você irá apresentar a mensagem “Olá, idoso!”; Caso a idade não do usuário for abaixo de 16 anos, a mensagem deverá ser “Não permitido uso por pessoas com idade inferior a 16 anos.”. Existem formas diferentes de construir esta lógica. Caso você tenha listado os passos do algoritmo utilizando o operador condicional simples se, você deverá realizar um teste para cada condição, ou seja, um para cada faixa etária que se deseja veri�car a idade que o usuário informou. Isso irá encadear vários comandos condicionais se, para a resolução do algoritmo proposto. Perceba, conforme o apresentado, que o teste de cada se irá retornar um valor lógico verdadeiro ou falso. Além disso, a idade informada pelo usuário, antes que os testes sejam feitos, deverá ser lida pela sua lógica, caracterizando então a necessidade de armazenamento temporáriodesta informação em uma variável do tipo inteiro. Porém, estamos considerando que o usuário já irá informar a idade dele, não a data de nascimento para que o cálculo da idade seja feito, a partir do ano atual. Então, seguindo esta linha de raciocínio, você deverá listar os passos iniciais do seu algoritmo como: Disciplina Algoritmos e Lógica de Programação O comando condicional complexo escolha serve para que você possa simpli�car a sua lógica, em caso de muitas condicionais simples se aninhadas. Trocando o tipo de estrutura por uma escolha, você poderá testar, em uma única condição, todas as opções que desejar como possiblidades, possibilitando, ainda, a de�nição de uma mensagem padrão, caso nenhuma das opções sejam atendidas. Uma diferença, porém, entre os comandos condicionais simples se e complexo escolha, é o tipo de teste que deve ser feito para que o �uxo principal possa ser alternado. Enquanto o se poderá ter mais de uma condição em seu teste, como o exemplo se (idade > 18) e (nome = ‘João’ ou nome = ‘Maria’) então, o condicional escolha irá selecionar, dentre uma lista de valores, os que podem ser assumidos por uma determinada variável, sem, efetivamente, testar uma ou mais condições. Um exemplo de uso da estrutura condicional escolha pode ser visto a partir da alteração do algoritmo apresentado a seguir. No exemplo, �zemos um pequeno ajuste solicitando que o usuário informe números em uma faixa já esperada (1, 2 ou 3), indicando sua faixa etária. Qualquer outro número informado será considerado opção inválida. Utilizando estruturas sequenciais na criação de um algoritmo Disciplina Algoritmos e Lógica de Programação Para que você ponha em prática todo o conteúdo estudado nesta aula, iremos iniciar com um exemplo de um algoritmo básico, contendo uma estrutura condicional simples se. O exemplo inicial consiste na criação de um algoritmo para o cálculo de um desconto de 10% em cima de um valor inteiro positivo informado pelo usuário, apresentando, como resultado, o valor descontando (que irá representar os 10%). Se o valor descontado for igual ou superior a 20, então apresente a mensagem “Valor inicial acima de 200”. Caso o valor descontado seja inferior a 20, então apresente a mensagem “Valor inicial entre 0 e 199”. Conforme os passos apresentados para o algoritmo proposto, teremos, como primeira ação, que solicitar um valor de entrada ao usuário. Este valor, no entanto, deverá ser armazenado de forma temporária, até que uma nova solicitação seja feita. Também deverá armazenar o resultado do Disciplina Algoritmos e Lógica de Programação valor do desconto de 10% calculado, para que possa ser apresentada a mensagem coerente com o resultado, após a execução do teste condicional. Vimos um algoritmo em pseudocódigo. Note que, nas linhas 1 e 2, as variáveis que serão utilizadas no código estão sendo declaradas, sendo elas a variável valor, que será informada pelo usuário, e a variável resultadoDesconto, que armazenará o valor do desconto de 10% sobre o valor informado. A linha 5 realiza uma operação de atribuição do cálculo dos 10% sobre a variável valor à variável resultadoDesconto. As linhas 7 e 10 apresentam o operador condicional simples se sendo utilizado para testar o valor do resultado obtido com o cálculo dos 10%. O teste deverá sempre retornar um verdadeiro ou falso, sendo que, no exemplo apresentado, apenas o resultado verdadeiro irá apresentar a mensagem contida na ação escreva em cada teste. Note que, neste exemplo, podemos aperfeiçoar nossa lógica fazendo uma pequena modi�cação nas linhas 7 e 10. Você poderá utilizar a condição senão para o condicional se da linha 7, não sendo necessário fazer um novo teste se, como apresentado na linha 10. Então, veja o exemplo de alteração da lógica para uso do condicional senão. Disciplina Algoritmos e Lógica de Programação A troca do condicional se, apresentado pelo condicional senão, apresentado na linha 9 só é possível pois não existem outras opções, para o algoritmo apresentado, de valores que a variável resultadoDesconto poderá assumir. Para cada condicional se, você poderá utilizar um senão, que irá ser executado caso o teste no se dê negativo. Quando se utiliza o senão, qualquer outro valor que a variável resultadoDesconto assuma, inclusive menor que zero, irá apresentar a mensagem “Valor inicial entre 0 e 199”, o que não está de acordo com o nosso requisito inicial. Então, é possível que um teste, ao dar negativo, possa efetuar um novo teste, em sua cláusula senão, conforme o exemplo de alteração do algoritmo para inclusão de se aninhado. Na linha 9 do novo exemplo, em comparação com a linha 9 do exemplo anterior, foi alterada para realizar um novo teste condicional se, em cima da variável resultadoDesconto, para saber se seu valor é maior que zero (atendendo, portanto, ao requisito de número inteiro positivo). Caso não seja um inteiro positivo, o �uxo alternará para a linha 11, apresentando a mensagem de “Valor inicial menor que 0”. Disciplina Algoritmos e Lógica de Programação Videoaula: Execução sequencial e estruturas de decisão Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo, você irá aprender como um algoritmo deve ser estruturado, sendo composto por elementos sequenciais e condicionais. Irá aprender, também, um exemplo prático da estrutura condicional complexa escolha. Seu código, ao �nal do vídeo, poderá ser elaborado de modo a realizar tomada de decisões simples e complexa e alterar o �uxo principal para �uxos alternativos, dependendo da resposta a cada decisão. Saiba mais Por meio do projeto Portugol, escolhendo a opção “Abrir Exemplo” à Algoritmos sequenciais, você irá encontrar exemplos práticos para a de�nição de variáveis (exemplo “Troca Variáveis”), além da utilização de condicionais simples (exemplo “Maioridade penal”). Ao escolher o menu https://dgadelha.github.io/Portugol-Webstudio/ Disciplina Algoritmos e Lógica de Programação “Desvios condicionais”, ainda nos exemplos disponíveis, é possível ver um exemplo de uso do condicional complexo escolha em “Escolha – Caso”, além dos demais exemplos, que apresentam variações do uso do condicional se. Referências FORBELLONE, A. L. V.; EBERSPÄCHER, H. F. Lógica de programação – A construção de algoritmos e estrutura de dados. São Paulo: Makron Books, 1993. Aula 3 Estruturas de repetição Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Nesta aula, você aprenderá os conceitos e a utilização das principais estruturas de repetição de trechos de código em um algoritmo. Irá aprender em quais situações deverá aplicar cada uma das estruturas apresentadas, o que são condições de parada e como elaborá-las para cada tipo de laço de repetição. Também serão apresentados os principais símbolos para representação dos laços de repetição em �uxogramas. Desta forma, os diagramas de �uxo que você irá criar serão mais completos, podendo representar lógicas mais complexas. Lembre-se que você é responsável pelo seu aprendizado, então, não se limite apenas ao visto em aula, mas busque enriquecer seus conhecimentos por meio de outras fontes con�áveis. Bons estudos! O que são estruturas de repetição e como utilizá-las Disciplina Algoritmos e Lógica de Programação Em sua lógica para a resolução de uma determinada tarefa do dia a dia, você poderá precisar que um trecho desta tarefa se repita por uma quantidade limitada de vezes (até que uma condição de parada seja satisfeita). Um bom exemplo é quando implementamos um algoritmo para subir uma escada. Como você não sabe, logo no começo do processo, quantos degraus serão necessários subir para que se chegue ao topo da escada, seu algoritmo deverá fazer uma sequência de passos, subindo cada degrau individualmente, até que não existam mais degraus a subir e, consequentemente, se tenhachegado ao topo da escada (objetivo �nal). A ação de subir um degrau e realizar um teste (se chegou ou não ao topo) é listada uma única vez na sequência de passos lógica do seu algoritmo, porém, esta ação se repetirá até que uma Disciplina Algoritmos e Lógica de Programação condição de parada seja satisfeita (que é chegar ao topo da escada). Existem diferentes formas de implementar uma estrutura de repetição, como apresentado por Forbellone (1993), sendo que cada uma será utilizada conforme a lógica que se deseja construir e os dados disponíveis sobre o trecho que deverá ser repetido (que denominamos iteração). O primeiro laço de repetição que você aprenderá é o enquanto – faça. Neste caso, a lógica deve ser entendida como enquanto uma condição for verdadeira, então faça <sequência de comandos>. A partir do momento que o teste desta condição especi�cada tiver resultado lógico falso, então o laço não mais se repetirá, permitindo que as demais instruções declaradas após este laço sejam executadas. Um outro tipo de estrutura de repetição é o para – até – faça, no qual um número de repetições já conhecido é informado para que o trecho da lógica seja repetido. Então, voltando ao exemplo do algoritmo para subir uma escada, caso seja conhecida a quantidade de degraus que serão percorridos por quem desejar subir a escada, esse número exato poderá ser utilizado para que a iteração do trecho da lógica seja feita. Porém, nem sempre é possível conhecer, em um momento prévio, a quantidade de vezes que um determinado trecho da lógica será executado, mas sabe-se que ele deve ser executado ao menos uma vez, antes que uma condição de parada possa ser testada e, caso a condição seja dada como falsa, então o trecho será executado novamente e o teste será repetido até que dê verdadeiro, �nalizando a sequência de repetições. A esta estrutura, damos o nome de repita até. Quando construirmos um �uxograma, além de comandos sequenciais e estruturas condicionais, você poderá representar as estruturas de repetição apresentadas, utilizando uma combinação de símbolos de decisão, controle de �uxo e leitura de dados (caso necessário), além do símbolo de preparação, conforme apresentado na Tabela 1. Disciplina Algoritmos e Lógica de Programação Tabela 1 | Símbolos utilizados em �uxogramas com laços de repetição. Fonte: elaborado pela autora. A Tabela 1 apresenta símbolos que podem ser utilizados na elaboração de �uxogramas que utilizam laços de repetição. Muitas vezes, é necessário que o usuário forneça dados para que o algoritmo possa realizar um processamento ou fazer algum cálculo matemático para se obter um resultado. Desta forma, a leitura de dados deverá preceder laços que irão se repetir até que um objetivo seja alcançado. Quando se deseja subir uma escada, por exemplo, é possível que seja necessário percorrer vários degraus, sendo que cada escada terá um número �nito, porém diferente da quantidade de degraus de outras escadas existentes. Iremos utilizar este exemplo para apresentar as mais variadas formas de utilização dos laços de repetição, ainda nesta aula. Disciplina Algoritmos e Lógica de Programação Compreendendo as situações-problema mais adequadas para cada tipo de estrutura de repetição Para que você possa compreender a sintaxe de cada laço de repetição e em quais situações aplicar cada uma, vamos utilizar o exemplo já apresentado de algoritmo para subir uma escada. Para que sejam percorridos degrau a degrau, é necessário que um laço de repetição aconteça, já que não se sabe, ao certo, quantos degraus serão percorridos até que a escada chegue ao seu �m. Cada laço terá, por sua vez, uma condição de parada diferente, ou seja, um teste que deverá ser executado para saber se haverá ou não necessidade de subir mais um degrau. A seguir veja o exemplo da condição para se utilizar o laço enquanto – faça. A linha 1 indica o início do laço de repetição. Caso a condição seja verdadeira, então, os comandos da linha 2 serão executados, caso seja falsa, o �uxo terá sua execução interrompida. A Figura 1 apresenta uma comparação entre a estrutura de um �uxograma para o laço enquanto – faça e um exemplo de lógica real. Considerando o algoritmo da escada, a condição de parada é Disciplina Algoritmos e Lógica de Programação a pergunta “a quantidade de degraus já percorridos é menor ou igual à quantidade total de degraus?”. Caso a resposta seja sim, então mais um degrau será percorrido, repetindo o teste até que todos os degraus tenham sido percorridos. Figura 1 | Fluxograma para um laço enquanto – faça. Fonte: elaborada pela autora. Em outro laço de repetição, o repita – até, todo o ciclo é executado ao menos uma vez para que, após cada execução, a condição de parada possa ser testada e, caso falso, então uma nova iteração será feita, porém, caso verdadeiro, então a execução será interrompida. Veja a seguir a sintaxe do laço de repetição repita – até. Na linha 1, o início do laço de repetição com a palavra reservada repita. A linha 2 deverá englobar todas as instruções que serão executadas, pelo menos uma vez, até que o teste da condição de parada seja verdadeiro. Disciplina Algoritmos e Lógica de Programação Fazendo uma analogia com o exemplo da escada, a condição de parada deve ser “até que a quantidade de degraus percorrida seja igual à quantidade total de degraus informada”. Figura 2 | Fluxograma para o laço repita – até. Fonte: elaborada pela autora. A Figura 2 apresenta o �uxograma para o laço de repetição repita – até, fazendo uma comparação com o �uxograma para a lógica da escada. A condição de parada deverá ser testada apenas após ao menos uma iteração do ciclo. Perceba que, em comparação com a lógica utilizada para o laço enquanto – faça, a condição de parada é alterada para até que a Disciplina Algoritmos e Lógica de Programação quantidade de degraus percorridos seja igual ao máximo de degraus da escada. Além disso, como o laço deverá acontecer ao menos uma vez, a variável qtdDegraus irá iniciar em zero, não mais em um (como no enquanto – faça), sendo incrementada em uma unidade antes de cada teste. Utilizando o exemplo da escada, temos que uma escada é composta por um ou mais degraus, justi�cando a execução do laço ao menos uma vez. Um outro laço, conhecido como para – até – faça, irá fazer uma iteração crescente ou decrescente de uma variável, partindo de um valor inicial, até se atingir um valor �nal. Ao se chegar ao valor �nal, que é a condição de parada deste laço, o ciclo será interrompido. Veja a seguir a sintaxe do laço para – até – faça. A Figura 3 apresenta o �uxograma para um laço de repetição do tipo para – até – faça. Este �uxo utiliza o símbolo de preparação, que contém a con�guração inicial do �uxo, sendo uma variável e seus valores inicial e �nal. É possível de�nir, também, um incremento, ou seja, um valor que será somado ao inicial para se chegar ao �nal (também conhecido como passo), sendo necessário apenas caso o incremento não seja sequencial. Figura 3 | Fluxograma para o laço para – até – faça. Fonte: elaborada pela autora. Considerando ainda o exemplo da escada, a lógica do para – até – faça pode ser aplicada quando se pensa “para quantidade degraus percorridos de 1 até quantidade máxima degraus, Disciplina Algoritmos e Lógica de Programação incrementando em uma unidade, faça”. Perceba que, neste laço, não é necessário que você faça o incremento manual da variável qtdDegraus, que é feita de forma automática pelo laço. Além disso, não é necessário inicializar a variável qtdDegraus, já que ela irá receber um valor inicial no momento da declaração do laço. Aplicando estruturas de repetição em algoritmos A aplicação de cada tipo de laço de repetição será determinada pela necessidade de execução da lógica e pela posição do teste de parada. Caso o teste de parada necessite ser executado primeiro, é preciso utilizar o laço enquanto faça. Nesta situação, você não sabe quantas iterações serão executadas ao certo, mas deverá realizar o teste antes de cadanova execução. O laço enquanto faça irá repetir uma sequência lógica de passos até que uma determinada condição se torne verdadeira, percorrendo, por exemplo, uma coleção de dados em busca de um dado que satisfaça a condição de parada. Um exemplo poderá ser apresentado fazendo alusão ao nosso algoritmo para subir os degraus de uma escada. Como não se sabe, ao certo, quantos degraus a escada tem e você deseja utilizar o mesmo algoritmo (mesma lógica) para percorrer diferentes escadas (com mais ou menos degraus), então você poderá pensar conforme o algoritmo para subir uma escada com enquanto – faça, apresentado a seguir. Disciplina Algoritmos e Lógica de Programação No exemplo, será solicitado ao usuário que entre com a informação de quando se chegará ao topo da escada (linha 7), com a quantidade total de degraus para se subir. O algoritmo, então, irá testar se o degrau atual que o usuário está já é o topo e, caso ainda não se tenha chegado ao �nal da escada, irá subir para o próximo degrau, por meio do incremento de uma unidade ao total de degraus já percorridos (linha 8). Após se atingir o topo, ou seja, a quantidade de degraus já percorridos ser maior que o topo da escada informado, então o laço deixará de se repetir. Note que, na linha 5, atribuímos um valor inicial para a variável qtdDegraus, para que o laço se inicie a partir do primeiro degrau da escada. A seguir, veja um exemplo de utilização do laço repita – até. Neste exemplo, a quantidade de degraus a ser percorrida (variável qtdDegraus) será inicializada com valor zero, sendo incrementada em uma unidade até que se torne igual à quantidade total do topo, informada pelo usuário. Uma diferença para o laço enquanto faça é a forma de elaboração da condição de parada. Enquanto, no repita – até a condição de parada deverá ser verdadeira para que as repetições sejam interrompidas, no laço enquanto faça a condição de parada deverá ser falsa para que o �uxo seja interrompido. Quando se tem um número máximo de repetições para fazer a iteração de uma lógica, o laço de repetição para – até – faça pode ser utilizado. Enquanto os laços enquanto – faça e repita – até são utilizados quando não se sabe, exatamente, a quantidade de iterações que precisarão ser feitas, com o laço para esta quantidade é bem de�nido, já que será o trecho da lógica será Disciplina Algoritmos e Lógica de Programação percorrido uma quantidade N de vezes, de forma crescente ou decrescente, a partir de um contador inicial. A seguir veja um exemplo de aplicação da estrutura de repetição para – até – faça. A estrutura inicia na linha 6, o laço para – até – faça, de modo que a variável qtdDegraus terá seu início com o valor 1, sendo incrementada de uma unidade até que seu valor seja maior que a variável topoEscada, que é seu limite máximo, fazendo o ciclo interromper. Note que, na linha 7, o comando escreva irá apresentar qual o degrau atual que está sendo percorrido. Videoaula: Estruturas de repetição Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo você aprenderá como aplicar cada laço de iteração na construção de seus algoritmos, de modo a saber identi�car as principais situações que necessitam de laços de repetição e quais laços mais se adequam a quais situações. Também irá compreender a sintaxe correta de construção de cada tipo de laço e como construir as condições de parada para cada estrutura de repetição. Saiba mais Disciplina Algoritmos e Lógica de Programação Por meio do projeto Portugol, escolhendo a opção “Abrir Exemplo” à Laços de repetição, você irá encontrar exemplos práticos para cada tipo de estrutura de repetição apresentada. Se atente à forma de construção das condições de parada em cada tipo de laço. Referências https://dgadelha.github.io/Portugol-Webstudio/ Disciplina Algoritmos e Lógica de Programação FORBELLONE, A. L. V.; EBERSPÄCHER, H. F. Lógica de programação – A construção de algoritmos e estrutura de dados. São Paulo: Makron Books, 1993. Aula 4 Variáveis indexadas Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Nesta aula, você aprenderá o conceito e a aplicação de estruturas de armazenamento de dados mais complexas, como vetores, matrizes e registros. Você deverá, ao �nal desta aula, compreender o funcionamento de cada estrutura e a melhor situação para aplicar cada uma no processo de elaboração de seus algoritmos, tornando-os mais completos e com suporte a lógicas mais complexas. Com o aprendizado destas estruturas, você terá concluído o estudo das principais estruturas disponíveis para armazenamento e manipulação de dados em algoritmos. Lembre-se que você é responsável pelo seu aprendizado, então, não se limite apenas ao visto em aula, mas busque enriquecer seus conhecimentos por meio de outras fontes con�áveis. Bons estudos! O que são vetores, matrizes e registros Disciplina Algoritmos e Lógica de Programação Ao elaborar uma lógica para um algoritmo, muitas vezes, você poderá ter a necessidade de armazenar ou manipular um conjunto de dados do mesmo tipo ou até de tipos diferentes. Pense, por exemplo, como você faria para armazenar uma faixa de valores inteiros, como a idade de todas as pessoas de uma sala de aula, ou o nome de todas estas pessoas. Ao declarar uma variável de um tipo primitivo, como inteiro ou caractere, você estaria armazenando apenas um único valor por vez, o que não iria satisfazer a sua atual necessidade (de armazenar um conjunto de valores). Para que exista a possibilidade de armazenamento de um conjunto de valores de um mesmo tipo, temos o que se conhece como vetor ou variáveis compostas homogêneas, conforme nos Disciplina Algoritmos e Lógica de Programação explica Forbellone (1993). Um vetor unidimensional é uma estrutura que tem uma quantidade delimitada de posições, como caixas de correio que podem estar armazenando diferentes valores do mesmo tipo. Sendo assim, em analogia ao exemplo das pessoas, o vetor seria do tipo caractere e armazenaria uma quantidade de valores que corresponda ao total de pessoas da sala de aula, o que se de�ne como posições do vetor. Cada posição, então, irá armazenar um nome (ex.: posição 1 armazena o nome “Maria”, posição 2 armazena o nome “João” e assim sucessivamente). A denominação unidimensional é proveniente do conceito de existir uma única dimensão, ou seja, seguir uma única direção (como uma �la indiana). Figura 1 | Exemplo de vetor unidimensional. Fonte: elaborada pela autora. A Figura 1 ilustra um exemplo de representação de um vetor unidimensional, no qual as informações são armazenadas em sequência, sendo todas do mesmo tipo (caractere). Existem outras situações, no entanto, que necessitam de uma estrutura de armazenamento mais complexa que um vetor unidimensional, tendo mais de uma dimensão, ou seja, se comportando como uma tabela (com linhas e colunas). Neste caso, podemos fazer uma analogia com o endereço de uma casa, no qual o nome da rua deve ser procurado primeiro, seguindo-se do número da casa, encontrando, assim, o endereço desejado. Trazendo este conceito para a elaboração de algoritmos, temos o que se denomina variáveis compostas multidimensionais ou matrizes. Uma matriz é composta por mais de uma dimensão, o que implica que, caso uma informação seja adicionada ou pesquisada, será necessário percorrer todas as dimensões do vetor para que o objetivo (de armazenamento ou pesquisa) seja atingido. Um conceito em comum entre matrizes e os vetores unidimensionais, porém, é o armazenamento de um único tipo de dados, ou seja, todas as informações armazenadas deverão, obrigatoriamente, ser do mesmo tipo (inteiro, real, caractere, lógico). Disciplina Algoritmos e Lógica de Programação Figura 2 | Exemplo de uma matriz ou vetor multidimensional. Fonte: elaborada pela autora. A Figura 2 ilustra um exemplo de umvetor multidimensional, também conhecido como matriz. Neste caso, para que uma informação seja armazenada ou consultada, é preciso que todas as dimensões sejam percorridas, ou seja, caso você esteja interessado em acessar o nome “Nilo”, deverá ir até a linha 3, coluna 3 para que o objetivo seja alcançado. O tipo mais complexo de armazenamento de dados são os registros, nos quais você poderá armazenar diferentes tipos de dados que estejam correlacionados com um mesmo conceito, como o nome, a idade, o endereço, CPF e altura de uma pessoa, por exemplo. Cada um destes dados está atrelado a um tipo diferente de informação (inteiro, real e caractere), mas todos os dados estão correlacionados com a mesma pessoa. Cada informação armazenada por um registro é denominada campo deste registro. Então, pense no registro como uma �cha de cadastramento, na qual cada campo da �cha corresponderá a um campo do registro, conforme apresentado na Tabela 1. Disciplina Algoritmos e Lógica de Programação Tabela 1 | Exemplo de uma �cha com diferentes tipos de informação sobre uma pessoa. Fonte: elaborada pela autora Como aplicar variáveis indexadas em algoritmos Ao pensar na lógica para construção do seu algoritmo, você deve se deparar, em algum momento, com situações nas quais é necessário armazenar uma coleção de dados, como uma faixa de valores. Nestes casos, o tipo de estrutura que você vai utilizar dependerá de qual tipo de dados você deverá coletar. Caso sejam vários valores, porém todos de um mesmo tipo, o ideal é a utilização de um vetor linear, ou seja, uma estrutura homogênea unidirecional. Como exemplo, podemos citar o armazenamento de valores de uma determinada quantidade de mercadorias (como os produtos de uma lista de compras), todas as matrículas dos funcionários de um setor e assim por diante. Uma matriz, por outro lado, é composta por mais de uma dimensão, ou seja, mais de um vetor linear. Desta forma, você poderá utilizar esta estrutura em situações nas quais necessite encontrar uma informação dentro de uma determinada posição. Como exemplo, podemos citar os apartamentos de um prédio. Digamos que cada andar tenha três apartamentos. Então, para que você acesse o terceiro apartamento do quinto andar, por exemplo, você deverá se dirigir à quinta posição do vetor de andares (primeira dimensão) e terceira posição do vetor de Disciplina Algoritmos e Lógica de Programação apartamentos (segunda dimensão). Considerando que a matriz prédio seria representada como a junção de duas dimensões (vetor de andares e vetor de apartamentos) lineares, sua representação visual seria como apresentada na Figura 3. Figura 3 | Exemplo de uma matriz com duas dimensões. Fonte: elaborada pela autora. Os andares, na Figura 3, representam a primeira dimensão, já que deverá ser a primeira informação a ser percorrida para que você consiga chegar ao apartamento desejado. Em seguida, a numeração do apartamento, a qual representa a segunda dimensão da matriz, deverá ser procurada. Disciplina Algoritmos e Lógica de Programação Observe que, tanto em vetores lineares quanto em matrizes homogêneas, o tipo de dado que será armazenado deve ser do mesmo tipo em todas as posições. Sendo assim, a matriz prédio irá armazenar, para a posição três do quinto andar, o número 503 (que representa o número do apartamento), a posição dois do quinto andar irá armazenar o número 502 e assim sucessivamente. Já para situações heterogêneas, você deverá armazenar diferentes tipos de dados (como uma coleção de dados) que se referirão a uma determinada entidade (um objeto ou algo concreto do mundo real). Retornando ao exemplo do prédio, imagine que você queira armazenar os dados do proprietário de cada unidade (nome completo, CPF, telefone de contato, data de nascimento). Neste caso, você deverá utilizar uma matriz heterogênea, ou seja, que irá armazenar diferentes tipos de informações em suas posições. Para tanto, deverá utilizar um registro, que irá conter todos os dados necessários para serem armazenados, que poderá ser nomeado como proprietário. Então, você terá a representação apresentada na Figura 4. Figura 4 | Conjunto de dados heterogêneos em um registro. Fonte: elaborada pela autora. A Figura 4 apresenta o registro proprietário sendo armazenado em cada posição da matriz prédio. Desta forma, para cada posição de apartamento do prédio, um conjunto de dados referentes ao proprietário será armazenado, sendo estas informações de tipos primitivos diferentes (numérico, real, caractere ou lógico). Exemplos de utilização das estruturas indexadas Disciplina Algoritmos e Lógica de Programação Para utilizar uma estrutura indexada em sua lógica, você deverá, após escolher qual o tipo de estrutura que fará uso, declará-la como uma variável, de�nindo o valor de cada dimensão, ou seja, quantas posições seu vetor linear terá ou, caso seja uma matriz, qual a quantidade de linhas e colunas que ela terá. Já para o caso dos registros, será necessário declará-los e de�nir seus campos (com os respectivos tipos). Denominamos de índice a posição de uma informação em um vetor ou matriz. Então, caso você queira armazenar ou recuperar uma informação em uma estrutura unidimensional ou multidimensional, será necessário informar o(s) respectivo(s) índices para cada dimensão da estrutura, analogamente a um endereço. Veja a seguir, um exemplo de declaração de um vetor linear O exemplo apresenta duas formas de declaração de um vetor linear. Na linha 1, um vetor linear de 10 posições, que irá armazenar informações do tipo inteiro, é declarado. Já na linha 2, você encontra um vetor de caracteres que está, ao mesmo tempo, sendo declarado e inicializado, ou seja, tendo seus valores iniciais de�nidos. Ainda nesta linha 2, perceba que não é de�nida a quantidade de posições que o vetor irá armazenar dentro dos colchetes. Isso acontece devido à Disciplina Algoritmos e Lógica de Programação quantidade de posições que deverão ser armazenadas estar sendo de�nida pela quantidade de informações passadas na sua inicialização, ou seja, três posições. Após a declaração de um vetor, a sua utilização se dará por meio do acesso à posição que se deseja armazenar ou ler. Veja a seguir operações básicas de leitura e atribuição em vetores. As linhas 4 e 5 apresentam como uma informação pode ser armazenada em uma posição de um vetor. É preciso de�nir qual a posição válida do vetor que irá receber a informação, ou seja, qual o índice do vetor que receberá a informação, sendo que esta precisa ser do mesmo tipo de�nido para o vetor. A linha 7, por sua vez, apresenta como a informação previamente armazenada poderá ser lida (recuperada) e apresentada ao usuário. Note que apenas o índice 1 do vetor (posição 1) está sendo acessado e terá sua informação escrita na tela, enquanto as demais posições do vetor não terão suas respectivas informações exibidas ao usuário. Veja a seguir, um exemplo de utilização de um laço de repetição para preenchimento de um vetor. O exemplo apresenta uma combinação de um laço de repetição para – até – faça com vetores. A linha 5 de�ne um laço de repetição de uma variável do tipo inteiro que irá iterar pedindo que o usuário informe valores (por meio da operação de leitura da linha 6), que serão atribuídos a cada respectiva posição do vetor. Desta mesma forma, é possível realizar operações de escrita percorrendo cada posição de um vetor. Veja o exemplo de declaração de uma matriz. Disciplina Algoritmos e Lógica de Programação A linha 1 apresenta a declaração de uma matriz, que deve conter o tipo do dado que será armazenado, o nome da variável e as dimensões, com suas respectivas quantidades de posições. Então, teremos cinco linhas e três colunas para a variável matrizPredio. As linhas 3 a 8 apresentam como as posições da matriz poderão ser acessadas, sendo necessário informar um valor para todas as dimensões de�nidas, ou seja, indicar os índices que serão acessados para cada dimensão. Veja a seguir o exemplo de leitura e preenchimento de uma matrizcom laço de repetição para – até – faça. O exemplo apresenta um exemplo de como deve ser feito o preenchimento e a leitura de uma matriz. O bloco para – até – faça, de�nido na linha 6, deverá percorrer as linhas, sendo o mais externo, enquanto o bloco para – até – faça de�nido na linha 7, irá percorrer as colunas, executando até o �nal de sua quantidade de iterações. Desta forma, para cada linha (laço da linha 6), o laço da linha 7 irá executar três vezes consecutivas. Veja agora um exemplo de de�nição e utilização de um registro. Disciplina Algoritmos e Lógica de Programação No exemplo, em sua linha 1, de�ne o tipo de dados registro, que terá os campos CPF e dataNascimento como do tipo inteiro, enquanto os campos nomeCompleto e telefone como do tipo caractere. Para acessar cada campo, você deverá seguir os exemplos apresentados nas linhas 5 a 8. A linha 10 de�ne uma matriz, do tipo do registro proprietário de�nido, que irá armazenar, para cada posição, um registro com todas as informações do proprietário daquela unidade. Videoaula: Variáveis indexáveis Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo, você aprenderá as estruturas de armazenamento de dados homogêneas, como os vetores unidimensionais e as matrizes, além da estrutura de armazenamento de dados heterogênea (os registros). Irá aprender em quais situações deverá utilizar cada tipo de estrutura e verá exemplos práticos de como aplicar estes conceitos ao elaborar seus algoritmos. Saiba mais Disciplina Algoritmos e Lógica de Programação Por meio do projeto Portugol, escolhendo a opção “Abrir Exemplo” à Vetores e matrizes, você encontrará exemplos práticos para estruturas homogêneas unidimensionais (vetores) e multidimensionais (matrizes). O exemplo “Preenche e Exibe Vetor” apresentará a forma como a leitura de dados e o preenchimento do vetor deve ser feita, além da forma como o vetor pode ser percorrido para exibição de seus dados. Você também poderá acessar o exemplo “Exibe Matriz”, que irá apresentar um exemplo prático de como uma matriz poderá ser construída, preenchida e ter seus dados exibidos. Referências https://dgadelha.github.io/Portugol-Webstudio/ Disciplina Algoritmos e Lógica de Programação FORBELLONE, A. Luiz Villar; EBERSPÄCHER, Henri Frederico. Lógica de Programação – A construção de algoritmos e estrutura de dados. São Paulo:Makron Books, 1993. Aula 5 Revisão da unidade Construção de algoritmos com laços de repetição e estruturas condicionais Disciplina Algoritmos e Lógica de Programação Um algoritmo é de�nido como uma sequência lógica de passos para que uma tarefa seja realizada, de forma automatizada, ou seja, que você possa repetir a mesma tarefa, seguindo a mesma sequência de passos e chegando ao mesmo resultado. Em seu cotidiano, você se depara com atividades que são feitas, mesmo que de forma inconsciente, por meio de passos sequenciais repetitivos, de modo a se obter um padrão de comportamento para a realização destas atividades. Como exemplo, podemos citar as receitas culinárias, que têm uma lista de ingredientes, organizados previamente ao preparo do prato, e uma sequência de passos que, se repetidos, irão atingir o mesmo objetivo. Para estas tarefas, que podem seguir um padrão e ter os mesmos passos repetidos inúmeras vezes, com o mesmo resultado atingido, podemos elaborar um algoritmo. Para muitas situações que podem gerar lógicas sequenciais, é comum que surjam elementos condicionais que, a partir do teste em uma condição, possam seguir um caminho ou outro. Para lógicas simples, ou seja, aquelas em que você irá testar uma condição apenas, é possível utilizar o laço se – então – senão. Como exemplo, temos a declaração: “Se não chover hoje então vou à praia, senão vou ler um livro”, que terá um teste a ser validado ou não (não chover hoje). Caso você se depare com uma situação na qual uma variável poderá assumir uma faixa de valores pré-conhecidos, então, a melhor opção é utilizar o comando condicional complexo escolha. Neste caso, o laço irá escolher qual �uxo deverá ser seguido, a depender do valor que a variável testada irá assumir. Além dos valores possíveis, existe a possibilidade de seguir um �uxo alternativo, conhecido como caso contrário ou �uxo padrão. Além dos laços condicionais, também é possível utilizar laços de repetição para construção da sua lógica algorítmica. Com estes laços, você será capaz de repetir um trecho de comandos até que uma condição de parada seja satisfeita e as repetições cessadas. Para cada laço, o Disciplina Algoritmos e Lógica de Programação momento no qual o teste da condição de parada acontece é diferente, conforme o comportamento do laço. Caso o intuito seja testar a condição de parada e, a depender da resposta, executar as instruções, você deverá utilizar o laço enquanto – faça. Caso seja necessário realizar, ao menos uma vez, o laço de repetição, dê preferência para o laço repita – até. Se a quantidade de repetições já for conhecida antes da criação do laço e a repetição for feita de forma incremental, então você deverá utilizar o para – até – faça. Fluxogramas podem ser utilizados para representar uma lógica sequencial de um algoritmo, por meio da utilização de elementos grá�cos. Qualquer pessoa, ao ler um �uxograma, deverá compreender, com exatidão, qual a sequência de comandos a ser seguida e quais mudanças de �uxo que deverão acontecer, em caso de elementos condicionais. A partir da combinação de setas e elementos condicionais, é possível criar estruturas de repetição. Além de variáveis simples, você poderá utilizar estruturas mais complexas, como os vetores, matrizes e registros. Vetores e matrizes são estruturas homogêneas, ou seja, armazenam informações de um único tipo, enquanto registros são estruturas heterogêneas, ou seja, podem armazenar informações de tipos diferentes, mas que estejam relacionados a um mesmo conceito (como características de uma pessoa). Videoaula: Revisão da unidade Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Neste vídeo, você verá um resumo do que é um algoritmo, seu propósito, a estrutura sequencial de um algoritmo, com as declarações de variáveis e constantes, além dos laços condicionais e de repetição. Você também verá a representação de algoritmos utilizando �uxogramas e quais os principais elementos para realização desta representação. Estudo de caso Disciplina Algoritmos e Lógica de Programação Olá, estudante! A construção de algoritmos faz parte do dia a dia de um programador, analista de sistemas ou engenheiro de software. Então, neste estudo de caso, você irá desenvolver a habilidade de elaborar um algoritmo, por meio da sequência lógica de passos para a resolução de um problema real. Para contextualizar o cenário, imagine que você faz parte da equipe de desenvolvimento de uma grande organização e, juntamente com sua equipe, é responsável por elaborar uma lógica para um algoritmo que deverá cadastrar dados básicos sobre pacientes em uma clínica médica. A partir dos dados informados em uma �cha de cadastro, contendo nome completo, data de nascimento, telefone para contato e endereço, o algoritmo deverá calcular a idade do paciente, com base na data atual e na data de nascimento informada. É possível armazenar até três endereços cadastrais diferentes para cada paciente, sendo que a quantidade de endereços informados dependerá da informação de existir ou não outro endereço além do anterior que foi informado. Importante destacar que é obrigatória a informação de pelo menos um endereço. O algoritmo se encerra quando os dados forem armazenados com sucesso. Elabore um segundo algoritmo que possa ler osvalores armazenados para um paciente e possa listar estes dados (escrever na tela). Construa os �uxogramas para cada algoritmo (de cadastramento e listagem), utilizando os elementos grá�cos apresentados ao longo das aulas. Elabore um relatório técnico contendo os �uxogramas construídos e as lógicas dos algoritmos em formato de pseudocódigo. Destaque no relatório quais os tipos de dados que você utilizou para armazenar as informações que serão solicitadas pelo algoritmo e quais as estruturas de repetição e condicionais utilizadas, justi�cando o motivo da escolha de cada estrutura. Disciplina Algoritmos e Lógica de Programação Apresente ao menos uma estrutura de repetição alternativa à que foi adotada em cada algoritmo e indique quais as alterações necessárias na condição de parada do laço para esta estrutura de repetição alternativa. Como alteração para o primeiro algoritmo, de cadastramento, imagine que o usuário deverá informar a quantidade de endereços que serão cadastrados, antes que os dados para cadastramento sejam informados. Neste caso, indique qual estrutura de repetição será mais adequada em seu relatório técnico. _______ Re�ita Olá, estudante! Antes de resolver o estudo de caso, pense nos pontos principais para construção do seu algoritmo: Quais são os passos estritamente necessários para a resolução do problema proposto? Qual estrutura de armazenamento de dados você deverá utilizar para armazenar as informações sobre um paciente? Quais estruturas de repetição você irá utilizar em seu algoritmo? Como deverá ser elaborada a condição de parada destas estruturas? Após a elaboração dos passos sequenciais da sua lógica, construa o �uxograma que a irá representar e analise se os passos apresentados no diagrama de �uxo criado estão condizentes com os passos do seu algoritmo. Analise os �uxos alternativos, no caso das estruturas condicionais e de repetição, veri�cando se estão conforme a lógica para resolução do problema proposto. Busque fazer uma análise crítica da sua lógica e das estruturas realizadas, se, de fato, são as melhores opções para a resolução do problema apresentado. Tente criar uma forma alternativa para a resolução deste mesmo problema, já que não existe uma única solução correta para o desenvolvimento de um algoritmo. Quais estruturas de repetição você poderá utilizar nesta solução alternativa? Tente justi�car tecnicamente. Videoaula: Resolução do estudo de caso Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Para resolver este estudo de caso, você deverá, como primeira etapa, listar todos os passos necessários para elaborar a lógica do algoritmo, em linguagem natural. Tente ser detalhista e não pular as etapas para resolver o problema. Disciplina Algoritmos e Lógica de Programação Após esta fase inicial, converta os passos que você listou para pseudocódigo, utilizando as estruturas sequenciais, condicionais e de repetição aprendidas. Também será necessário que você pense na forma como os dados que deverão servir de entrada para o algoritmo deverão ser armazenados, utilizando as estruturas de armazenamento de dados. Para o problema proposto, você poderá utilizar o tipo registro para agrupar os dados necessários para cadastramento de um paciente. Um ponto de atenção, porém, é na forma como os endereços devem ser armazenados. Como existe um limite máximo de três endereços diferentes para cada paciente, você deverá utilizar um vetor de caracteres para armazenar esta informação. Após os dados serem informados, o cadastramento deverá ser a próxima etapa a ser executada, seguindo a �nalização da lógica. Se atente ao fato que, durante o processo de solicitação dos dados que serão cadastrados, sua lógica deverá perguntar “existe um novo endereço a ser cadastrado?” e, se a resposta for a�rmativa, então o �uxo para solicitar os dados de um novo endereço deverá ser repetido, caso contrário, apenas os endereços já informados serão cadastrados. Com a variação solicitada no �nal do estudo de caso, para que o usuário informe previamente quantos endereços serão cadastrados, você não precisará fazer a pergunta do parágrafo anterior, já que a execução dos passos para obter os dados de um novo endereço acontecerá um número já conhecido de vezes, indicando o uso do laço para – até – faça. Para sugerir um laço alternativo de repetição ao que você pensou em sua solução inicial, se atente apenas ao ajuste na condição de parada. Você poderá utilizar os laços repita – até ou enquanto – faça em sua solução, ajustando a condição de parada conforme o requisitado por cada tipo de laço. Elabore o �uxograma como última etapa do processo de construção do seu relatório técnico, utilizando os símbolos aprendidos e fazendo a ligação entre eles com a utilização das setas. Resumo visual Disciplina Algoritmos e Lógica de Programação Figura 1 | Resumo das estruturas condicionais. Fonte: elaborada pela autora. Disciplina Algoritmos e Lógica de Programação Figura 2 | Resumo das estruturas de repetição. Fonte: elaborada pela autora. Figura 3 | Resumo das estruturas de armazenamento. Fonte: elaborada pela autora. Disciplina Algoritmos e Lógica de Programação Figura 4 | Resumo dos símbolos para elaboração de �uxogramas. Fonte: elaborada pela autora Disciplina Algoritmos e Lógica de Programação Referências FORBELLONE, A. L. V.; EBERSPÄCHER, H. F. Lógica de programação – a construção de algoritmos e estrutura de dados. São Paulo: Makron Books, 1993. PRESSMAN, R. S. Engenharia de software. São Paulo: Makron Books, 1995. , Unidade 3 Conceitos de programação Aula 1 Introdução a conceitos de programação Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Chegamos à unidade em que estudaremos os conceitos de lógica de programação aplicados a uma linguagem especí�ca de programação: a linguagem C! Essa linguagem é o meio pelo qual os comandos que indicarmos serão realizados pelo computador para produzir a saída esperada para o programa. Você já aprendeu que a assertividade de um programa depende de sua construção, isto é, da escolha correta dos passos que o compõem, e de forma que os comandos sejam executados em uma sequência lógica. Nesta unidade, estudaremos como a linguagem de programação e um ambiente de desenvolvimento nos fornecem as estruturas necessárias para realizarmos o processamento lógico das informações. Te convido para vivenciar essa realidade que é a base de qualquer sistema ou produto digital, vamos lá? Conceitos básicos de linguagem de programação Disciplina Algoritmos e Lógica de Programação Todos os sistemas que utilizamos no nosso dia a dia foram desenvolvidos em alguma linguagem de programação! Do mais avançado software de engenharia ao jogo mais popular dos smartphones, todos eles são uma construção de comandos de programação organizados de forma lógica. As linguagens de programação foram evoluindo com o tempo, e para cada propósito de aplicação escolhemos a mais adequada. Uma analogia pode ser feita com a língua nativa, a língua estrangeira, ou ainda uma linguagem mais formal ou mais descolada, que deriva de uma língua. Ah, aqui também cabe uma observação interessante, um programa construído com uma linguagem de programação tem o mesmo signi�cado no mundo todo; outra informação importante é que praticamente todas as linguagens de programação têm seus comandos escritos em inglês. Nossa disciplina adota a linguagem C, uma linguagem amplamente utilizada e que é base para diversas outras linguagens comerciais atualmente, e por meio dos exemplos práticos você verá como ela realiza as operações necessárias no campo da programação. Em relação à linguagem adotada na nossa disciplina, saiba que a linguagem C é umas das mais populares, e por suas características de acesso e manipulação de recursos computacionais como a memória, émuito utilizada em áreas da engenharia, computação e especialmente na eletrônica, além de também ser utilizada para construir bibliotecas nativas de outras linguagens de programação. Disciplina Algoritmos e Lógica de Programação Como toda linguagem, a linguagem C possui uma quantidade �nita de palavras e símbolos, eles são chamados de tokens, isso quer dizer que para criarmos um código-fonte devemos escolher tokens que existam na linguagem. Cada token da linguagem tem um signi�cado no contexto da programação, que inclusive pode mudar conforme a ordem em que são organizados. Estes tokens podem ser um comando na linguagem, um operador (relacional, condição ou lógico) ou ainda uma palavra reservada para caracterizar algum identi�cador. Agora que você já conhece as características de linguagens de programação pode estar se perguntando como seus tokens são compreendidos pelo computador, certo? Aqui surge a necessidade de abordarmos o Compilador e o Interpretador, que são os sistemas computacionais capazes de receber um código escrito em uma linguagem de programação e tornar esse código um programa executável. Os programadores escrevem códigos-fonte com comandos da linguagem de programação, e o compilador é o responsável por criar um código de signi�cado equivalente ao código do programador, de forma que o computador processe esse código e execute os comandos adotados. Aqui cabe destacar que problemas de lógica não são identi�cados pelo compilador, ou seja, um programa que foi construído com os elementos corretos e respeitando as regras da linguagem pode, ainda assim, apresentar erros de lógica e possíveis erros de execução dependendo das entradas a que foi submetido. Tanto para elaborar quanto para editar o código-fonte é necessário um software, assim como o compilador e o interpretador também são um software executável. É possível que um mesmo sistema integre o software de editor e o compilador, a ele damos o nome de Ambiente Integrado de Desenvolvimento, também conhecido pela sigla IDE, do inglês Integrated Development Environment. Uma descrição dessa composição é apresentada pela Figura 1. Disciplina Algoritmos e Lógica de Programação Figura 1 | Composição de uma IDE. Fonte: elaborada pela autora. Até aqui você foi apresentado: À linguagem C. Ao compilador necessário para transformar o código escrito em C em um programa executável pelo computador. E à IDE, uma ferramenta de software que serve como um ambiente de trabalho. Compiladores e interpretadores Disciplina Algoritmos e Lógica de Programação Para aprofundar mais nossos conhecimentos sobre as linguagens vamos conhecer mais algumas de suas características: Podem ser de mais alto nível: como Python, java e php. Podem ser de mais baixo nível: como C e Assembly. E ainda existem linguagens que derivam de outras linguagens: como C# e C++. Dizemos que uma linguagem é de alto nível quando o usuário se distancia dos aspectos estruturais do código, utilizando um alto nível de abstração para executar comandos. Em uma comparação, é como se estivéssemos localizando um país no globo terrestre, obtendo sua localização, limites e fronteiras, porém sem maiores detalhes. Já uma linguagem de baixo nível é aquela em que o usuário tem total controle e conhecimento das estruturas e dados que estão sendo manipulados, o que também faz com que mais detalhes precisem ser adicionados para a construção do programa. Utilizando a mesma comparação anterior, é como se estivéssemos nos localizando em uma cidade com o GPS, observando as ruas e características das quadras. Assim como na comunicação que conhecemos na sociedade, em que utilizamos as palavras disponíveis na linguagem, e respeitamos as regras de construção das frases, no contexto de programação também há regras a serem respeitadas em todas as linguagens, independentemente do nível em que esteja inserida. Algumas linguagens como PHP e JavaScript normalmente não necessitam de compilador, e sim de interpretador, enquanto a linguagem Java costuma depender tanto de compilador quanto de Disciplina Algoritmos e Lógica de Programação interpretador e a linguagem C, utilizada na nossa disciplina, utiliza compilador (MANZANO, 2015), e mais adiante vamos detalhar seu funcionamento prático. Primeiramente, vamos entender o contexto e a necessidade de utilizar um compilador: o computador trabalha com estruturas e objetos binários, ou seja, independentemente se o computador está manipulando um texto, um número, uma imagem ou as instruções de um programa, na prática ele está processando 0s e 1s. Porém, você deve concordar que seria humanamente inviável para os programadores escreverem programas e instruções somente com a representação de 0s e 1s. Podemos então de�nir o compilador como um tradutor de linguagens, em que a linguagem de saída é sempre de um nível mais baixo que o nível de entrada. O programa de saída costuma ser construído em binário, linguagem simbólica ou linguagem de máquina, sempre constituído somente por cadeias de 0s e 1s. Em alguns casos, o erro apontado pelo compilador não o impede de gerar o programa em binário, porém, em alguns casos, o compilador não consegue gerar o programador executável, sendo preciso localizar o erro e corrigi-lo, para depois tentar compilar novamente. Essa é uma atuação importante do compilador, pois evita que um programa com uma construção falha seja executado, pelo contrário, o compilador muitas vezes aponta para o programador qual foi o erro encontrado. Cada IDE tem uma forma visual de representar esses possíveis erros, algumas delas até mostram os erros na construção do programa enquanto o programador digita, ou seja, ainda antes da análise do compilador. Essas e outras funcionalidades fazem com que as IDEs sejam vistas como ferramentas que melhoram a produtividade dos programadores. As IDEs evoluíram muito com o tempo, há uma grande variedade disponível para linguagens populares como o C, e algumas delas são: Visual Studio, CodeBlocks, DevC, Eclipse, NetBeans. E para outras linguagens também podem ser usadas as IDEs citadas acima ou ainda outras tantas existentes no mercado. Ambiente de Programação Disciplina Algoritmos e Lógica de Programação Estudante, chegamos ao momento em que aplicamos os conceitos aprendidos! Assim como na nossa língua, para o perfeito entendimento do código realizamos a análise léxica e a sintática, sendo a primeira sobre a gra�a correta ou existência de cada token presente no código-fonte, e a segunda sobre a forma e a ordem em que os tokens foram inseridos no código- fonte, se há uma concordância entre si. Ou seja, na prática, a atividade do compilador é similar à de um tradutor que realiza a dublagem ou a legenda de um �lme, quando a frase ou a palavra que está sendo traduzida se apresenta de maneira errônea, dúbia ou que não permita o entendimento, esse pro�ssional busca entender o contexto, realiza uma sugestão de adequação ou mesmo para a execução para elucidar a dúvida. No caso do compilador é muito parecido, pois quando o programador cria um código que apresenta erros ou falhas em sua construção, o compilador precisa reconhecer e apontar essa divergência, para que o programador proceda com a correção. Quando o código não apresenta erros, o compilador então cria um código de máquina “semanticamente equivalente”, ao código criado pelo programador na linguagem de programação. Neste aspecto novamente aparece a �gura do ambiente de programação como um aliado do programador! Pois algumas IDEs identi�cam em tela a estrutura física do código, a posição dos pares de parênteses, chaves e colchetes, podendo realizar o autopreenchimento do nome de variáveis e ainda outras facilidades como sugestão de melhoria e, consequentemente, menos erros no código. Um destaque de diferentes cores está apresentado na Figura 2. Disciplina Algoritmos e Lógica de Programação Figura 2 | Tela de um código sendo editado em uma IDE. Fonte: captura de tela de Code: Blocks elaborada pela autora. Assim como existemvariações entre ferramentas, existem IDEs mais amigáveis, mais robustas, mais pro�ssionais, mais leves e com mais ou menos recursos ao programadores, sendo que algumas são gratuitas e outras são pagas. A escolha da IDE também dependerá da linguagem de programação adotada e do compilador selecionado. Os programadores podem (e devem!) con�gurar e customizar a IDE que escolheram para trabalhar, pois além de realizar as atividades básicas de programação, ela acaba oferecendo outros recursos desejáveis para o programador. A grande maioria das IDEs oferecem identi�cador de erros por meio de uma análise léxica no próprio editor e no instante em que o programador digita, sem a necessidade de compilar o código. Esses e outros recursos são essenciais no dia a dia do programador para que ele ganhe em produtividade, principalmente quando o tamanho dos projetos cresce consideravelmente. Neste contexto, inicialmente a IDE parece ser muito complexa para programas simples, mas como ela é uma ferramenta pro�ssional, foi desenvolvida para organizar pacotes de software que precisam ter a referência de bibliotecas, classes, scripts e outros códigos. Importante destacar que a IDE é uma ferramenta, e embora seja certeza que você precisará de uma IDE para construir e compilar seus códigos, você deve se concentrar em aprender a programar em uma linguagem pelo menos, e então se adaptar à IDE será uma consequência! Nesta unidade serão apresentados os códigos-fonte para que você acompanhe a disciplina, entenda a composição do código e a construção de cada comando, para que, assim, você possa desenvolver seus próprios códigos. Essa disciplina requer a leitura do material e a resolução de exercícios do material, e é indicado que você programe “mão na massa” para também desenvolver seu raciocínio lógico e sua Disciplina Algoritmos e Lógica de Programação capacidade de resolver problemas computacionais. Videoaula: Introdução a conceitos de programação Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante! Conhecemos os conceitos de linguagem de programação, compiladores e ambientes de desenvolvimento, e como eles se relacionam. Agora vamos aprofundar mais na parte prática quanto à interface de desenvolvimento. Neste vídeo, você conhecerá o funcionamento da IDE CodeBlocks, e alguns dos principais passos para conferir se a instalação está 100%! Vamos lá? Saiba mais Disciplina Algoritmos e Lógica de Programação O que fazer quando se faz necessário utilizar um outro computador para as tarefas da disciplina? Bem, deixar de realizá-las não é uma opção!! Então eu trouxe para você uma opção de editor e compilador online, o JDoodle! Aproveite para salvar o link como uma opção a mais de estudo e ferramenta para praticar os exercícios da disciplina caso você não esteja com outro Ambiente Integrado de Desenvolvimento local devidamente instalado. Referências MANZANO, J. A. N. G. Linguagem C: Acompanhada de uma xícara de café. São Paulo: Érica, 2015. Aula 2 Introdução à linguagem C Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Agora que você já conhece a linguagem de programação da nossa disciplina e já sabe a necessidade de adotar um ambiente de desenvolvimento, nesta aula, vamos conhecer com detalhes cada estrutura do programa em linguagem C. Assim como uma receita seus ingredientes com unidades e ordens pré-de�nidas, os algoritmos também têm campos para declaração do que será necessário para aquele código-fonte, isso consiste em um padrão no qual o programa deve ser construído para que gere um código de máquina válido ao ser interpretado pelo compilador. Nesta aula você entenderá como manipular dados em C e realizar operações com eles, sempre respeitando os comandos da linguagem. Não deixe de realizar os exercícios propostos, eles são essenciais para seu aprendizado! Vamos juntos conhecer esses comandos? Construindo um programa em C Disciplina Algoritmos e Lógica de Programação Vamos começar identi�cando quais as estruturas básicas de um programa em linguagem C, começando com um exemplo na Figura 1. A linha 1 é o cabeçalho do programa, e entre as linhas 2 e 4 está o Programa principal, identi�cado como main. Figura 1 | Estrutura do Programa em Linguagem C. Fonte: elaborada pela autora. Nas primeiras linhas �cam localizados os comandos de pré-processamento, ou pré-compilação, sempre iniciando com o sinal # (hashtag), esses comandos servem para inclusão de bibliotecas e de�nições e formam o cabeçalho do programa. Dependendo do tipo de estrutura a ser manipulada são adicionadas as bibliotecas necessárias, no exemplo da Figura 1 foi necessário Disciplina Algoritmos e Lógica de Programação adicionar somente uma biblioteca, a stdio.h, uma biblioteca que manipula funções de entrada e saída, e adicionando-a o programador pode simplesmente chamar o comando scanf e printf dentro do programa principal, sem a necessidade de conhecer os detalhes internos de operação destes comandos no sistema operacional. Em seguida �ca localizado o programa principal, sempre identi�cado por main(), e tendo delimitando os comandos de seu trecho com os tokens { e }, que na Figura 1 estão entre as linhas 3 e 6. Observe que, ao ser executado, este programa sempre executa o comando printf(), que é um comando de saída para mostrar informações na tela, e a informação é sempre a mesma frase que está entre as aspas: “Meu primeiro programa!!”. Ele não recebe nenhuma entrada ou interação que dependa do usuário, mas as aplicações se tornam muito mais diversas quando permitimos que o usuário interaja com o programa! Essa interação é feita por meio de comandos de entrada, e o mais comum na linguagem C é o scanf(), que permite ler números ou letras do teclado. Quando o programa lê uma informação, ele precisa armazená-la em algum local apropriado da memória, e depois recuperá-la. Isso é possível se o programador previamente reservar uma região da memória e dar a ela um nome (identi�cador) para que possa ser acessada sempre que necessário. Então, no código, sempre que for preciso utilizar essa informação, chamamos o identi�cador dela. Imagine se na necessidade de alterar a informação a gente precisasse reservar uma outra região de memória, e tentar usar o mesmo identi�cador? Seria um desperdício de espaço e uma confusão, não é mesmo? É por isso que esse espaço reservado recebe o nome de variável, pois sempre que for necessário substituir seu conteúdo nós informamos o nome do identi�cador e o novo valor. Utilizando um raciocínio semelhante, chegamos à de�nição de constante, uma região de memória reservada, com um nome identi�cador, porém que não pode ter seu conteúdo alterado ao longo do programa. Assim, as informações manipuladas pelo computador que estão em uma região especí�ca de memória ou são uma variável ou uma constante. Ambas as con�gurações constituem o que chamamos de dados. Os dados têm um determinado tipo e tamanho, inclusive isso in�uencia no espaço ocupado na memória. Todas as ações que realizamos com os dados são por meio dos operadores, e na linguagem C os operadores podem ser: Aritméticos: para cálculos matemáticos, e estão apresentados na Figura 2. Relacionais: para comparar se dois valores são iguais, diferentes ou se um é maior que o outro. Lógicos: para combinar um ou mais operadores relacionais em uma lógica de multifatores de entrada. Disciplina Algoritmos e Lógica de Programação Figura 2 | Operadores aritméticos. Fonte: adaptado de Manzano (2015), p. 44. Isso quer dizer que tudo que o programa precisar processar será construído com base nos 3 tipos de operadores disponíveis na linguagem e respeitando as limitações quanto ao tipo de dados e as construções dos comandos. Programas para manipular dados Disciplina Algoritmos e Lógica de Programação Agora que você já conhece osrecursos que tornam o programa mais completo, vamos analisar um exemplo que utiliza uma variável e um comando de leitura e escrita para calcular e mostrar o dobro de um valor: 1.#include<stdio.h> 2.int x; 3.int y; 4.int main() { 5. scanf("%i", &x); 6. y = 2 * x; 7. printf("valor de y: %i", y); 8. } Neste programa, se a entrada for 3, a saída é 6, já se for 4, a saída é 8, e assim por diante, e percebemos isso ao analisar a linha de código (y = 2 * x), que contém os operadores aritméticos como conhecemos. Nas linhas 2 e 3 declaramos duas variáveis do tipo inteiro e sabemos que é do tipo inteiro pelo uso da palavra reservada int. Se precisássemos de outro tipo de variável, iríamos usar outra palavra reservada para declará-la. E x e y foram os nomes dados às variáveis, ou seja, seu identi�cador. Podemos (e devemos!) utilizar identi�cadores que contextualizem melhor seu papel no programa, como demonstrado no código a seguir: 1;#include<stdio.h> 2.int valor; Disciplina Algoritmos e Lógica de Programação 3.int dobro; 4.int main() { 5. scanf("%i", &valor); 6. dobro = 2 * valor; 7. printf("O dobro é: %i", dobro); 8. } Embora essa mudança melhore consideravelmente o entendimento e a legibilidade do programa, como regra, nem todas as combinações de letras e números são válidas como identi�cadores de variáveis e constantes (MANZANO, 2015): Máximo de 32 caracteres de letras e números, sem espaço. Iniciar com uma letra ou “_” (underline), nunca com um número. Não pode ser uma palavra reservada da linguagem C, ou seja, uma palavra que já tem uma funcionalidade atribuída na linguagem. Não pode utilizar outro caractere especial, o único permitido é “_”. Já que mencionamos as regras dos identi�cadores, vamos conhecer outros tipos de dados presentes na linguagem C, alguns deles estão descritos na Tabela 1. Tabela 1 | Tipos de dados na linguagem C. Fonte: adaptada de Manzano (2015). Disciplina Algoritmos e Lógica de Programação O comando scanf() da linha 5 tem duas regras de construção importantes: “%i” signi�ca que irá ler um número do tipo inteiro, para outros tipos é necessário usar outra construção. &valor signi�ca que irá armazenar o valor lido na variável valor. Já o comando printf() da linha 7 tem as seguintes regras: O conteúdo das aspas será mostrado na íntegra, exceto quando houver o símbolo %, que representa um código de escape. Para mostrar o conteúdo de uma variável do tipo inteiro utilizamos %i e %d, para outros tipos é necessário usar outra construção. Após o fechamento das aspas, deve vir uma vírgula e o nome da variável de interesse; Se for necessário mostrar mais uma variável, adiciona-se mais uma vírgula e a outra variável. Construindo programas mais robustos Disciplina Algoritmos e Lógica de Programação Nós já estudamos que um programa válido é aquele que respeita as regras da linguagem no quesito léxico e semântico, e que irá gerar um código de máquina que realize o processamento lógico desejado. Isso nos leva a 2 pontos importantes: 1. Assim como em toda operação matemática, o resultado obtido não necessariamente depende de como os operadores aparecem na linha do comando, e sim de acordo com a regra de precedência de operadores, que é a ordem em que são executados. Essa ordem está apresentada na Figura 5. Figura 5 | Ordem das operações matemáticas. Fonte: elaborada pela autora. As construções dos comandos dependem do tipo de dado que será manipulado, então, para utilizar os comandos scanf() e printf() em dados do tipo não inteiros, utilizamos após o sinal % as seguintes construções sintáticas: 1.#include<stdio.h> 2.float pi; 3.int main() { 4. pi = 3.14159265359; 5. printf("PI: %5.2f", pi); 6. } Agora vamos conhecer os operadores relacionais da linguagem C, em que dois termos são comparados por meio do operador, sendo que os termos podem ser variáveis, constantes ou números �xados no código. Os operadores relacionais estão apresentados na Tabela 2, com seu respectivo signi�cado de teste. Disciplina Algoritmos e Lógica de Programação Tabela 2 | Operadores relacionais na linguagem C. Fonte: adaptada de Microsoft (2022). A saída de uma relação testada pode ser falsa ou verdadeira, na linguagem C usa-se o valor “0” (zero) como indicativo falso deste teste, e 1 ou qualquer outro valor diferente de zero é considerado verdadeiro. Duas comparações estão sendo apresentadas no código a seguir, sendo a primeira comparando se doze é igual a zero, com resultado falso (como esperado, mostrando 0 na tela!), e a segunda em que comparamos se a variável chamada número é menor que o número 12, e como seu conteúdo é 10, o resultado é verdadeiro, mostrando 1 na tela. 1.#include <stdio.h> 2.#include <stdlib.h> 3.int numero; 4.int resultado1, resultado2; 5.int main() 6.{ 7. numero = 10; 8. resultado1 = (12 == 0); 9. printf("Resultado 1: %i \n", resultado1); 10. resultado2 = (numero < 12); 11. printf("Resultado 2: %i \n", resultado2); 12. return 0; Disciplina Algoritmos e Lógica de Programação 13.} Esses operadores relacionais que produzem como saída “falso” ou “verdadeiro” �cam ainda mais interessantes quando usados de forma combinada, por meio dos operadores lógicos! Assim como na matemática esses operadores relacionam 2 condições em sua tabela verdade, e tanto sua entrada como sua saída são valores lógicos, ou seja, verdadeiro ou falso. Os operadores lógicos estão apresentados na Tabela 3, com seu respectivo signi�cado na lógica booleana. Tabela 3 | Operadores lógicos na linguagem C. Fonte: adaptada de Manzano (2015). Com esses recursos, nós conseguimos construir programas para diversas aplicações matemáticas! Videoaula: Introdução à linguagem C Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Estudante, nesta aula, conhecemos como manipular dados em linguagem C, por meio de variáveis e constantes, também estudamos como funcionam os comandos de entrada e saída de dados e sua importância para tornar o programa mais dinâmico. Estudamos também os Disciplina Algoritmos e Lógica de Programação operadores aritméticos, relacionais e lógicos, que são estruturas essenciais para construirmos programas mais pro�ssionais. Venha comigo no próximo vídeo para executarmos um programa que abrange todos estes conteúdos! Saiba mais Para melhor entendimento dos operadores lógicos é importante que você conheça a tabela verdade dos operadores, um conceito matemático e de muita aplicação na computação. Você pode desenvolver a tabela verdade conforme a necessidade do programa em desenvolvimento, e se precisar validar ou tirar a prova real de algum operador você pode acessá- la online! Acesse a Calculadora Online (Tabela-Verdade) para treinar seus conhecimentos em lógica booleana. Referências https://www.calculadoraonline.com.br/tabela-verdade Disciplina Algoritmos e Lógica de Programação MANZANO, J. A. N. G. Linguagem C: Acompanhada de uma xícara de café. São Paulo: Érica, 2015. MICROSOFT. Operadores relacionais e de igualdade C. Disponível em: https://learn.microsoft.com/pt-br/cpp/c-language/c-relational-and-equality-operators? view=msvc-170. Acesso em: 22 nov. 2022. Aula 3 Estruturas condicionais em linguagem C Introdução https://learn.microsoft.com/pt-br/cpp/c-language/c-relational-and-equality-operators?view=msvc-170 https://learn.microsoft.com/pt-br/cpp/c-language/c-relational-and-equality-operators?view=msvc-170 Disciplina Algoritmos e Lógica de Programação Olá, estudante! Nesta aula, você deverá observar os sistemas que utiliza, como o gerenciador de e-mails, o editor de texto e o aplicativo do banco. Esses sistemas interagem com você e respondem de acordo com as suas ações, por meio de condições que foram previamente implementadas. Isso só é possível porque, a cada opção que vocêpode acionar no sistema, há uma programação que determina qual caminho o programa deve seguir ou o que ele deve fazer. Neste contexto, você está convidado a conhecer como construímos essas opções e os possíveis caminhos do programa. Vamos nessa? Lembre-se de reforçar os conceitos estudados com os exercícios da aula! Programas com opções Disciplina Algoritmos e Lógica de Programação A linguagem C é executada linha a linha, assim como você acompanha este material – e, se necessário, desvia a sua leitura para uma linha diferente, ou para outra área especí�ca do programa. Na linguagem de programação, os possíveis caminhos que um programa pode tomar são organizados nas estruturas condicionais, mais precisamente nos desvios condicionais. À primeira vista, o código tem seu mesmo aspecto textual e em sequência tradicional, mas ele pode, a cada comando, ter seu curso alterado de acordo com a interação do usuário. Quando pensamos em programas que interagem de acordo com nossas entradas, estamos lidando com o contexto dessas estruturas condicionais, e como o próprio nome diz, a forma de sua execução depende de uma condicional. Na prática, essas estruturas organizam o código de forma que as entradas fornecidas pelo usuário sirvam como decisores lógicos quanto aos próximos passos de execução do programa. A lógica das estruturas condicionais é muito parecida com o nosso raciocínio ao resolver desa�os do dia a dia. Por exemplo: se abrimos um e-mail para lê-lo, o gerenciador remove a noti�cação de nova mensagem, assim como ele exibirá uma mensagem de erro se for identi�cado que estamos sem internet. O comando para essa lógica é o if(), pois if, em inglês, signi�ca “se”. Esse conjunto de veri�cação e reação é chamado de estrutura condicional e é composto por uma veri�cação acerca de uma condição e uma reação a ser executada se essa condição for satisfeita. Tal condição pode ser a relação de um ou mais eventos, e a reação pode ser a execução de um conjunto de comandos ou de um único comando. Inclusive, a reação a ser executada pode ser outra estrutura condicional, consistindo em uma estrutura dentro de outra, chamada de estrutura condicional encadeada. Por serem muito versáteis, essas estruturas permitem inúmeras combinações. Disciplina Algoritmos e Lógica de Programação Adicionalmente, pode haver um senão acompanhando a lógica do se. Por exemplo: se a bateria estiver com a carga abaixo de 15%, mostre o ícone em vermelho; senão, mostre o valor da carga. Na linguagem C, o comando equivalente ao senão é o else, e veremos mais adiante os exemplos de sua implementação. Muitas vezes, são tantas as possibilidades do programa que uma estrutura condicional poderia tornar confusa sua legibilidade. Nessas circunstâncias, utilizamos a seleção de casos, a qual é muito útil quando o usuário tem diversas opções, sendo por isso também chamada de estrutura de controle com múltipla escolha. Na linguagem C, o comando para essa seleção é o switch. Assim como as estruturas condicionais são a base para organizar desvios no programa, elas também servem como estruturas de controle de repetição, devido ao mesmo princípio. A linguagem C tem dois recursos diferentes para essa �nalidade: o for e o while, sendo que ambos também avaliam condições para controlar as repetições. Conhecendo as estruturas condicionais Um ponto relevante para detalharmos as estruturas condicionais é a sua base de veri�cação: uma lógica constituída por operadores lógicos e relacionais. Os operadores relacionais sempre retornam verdadeiro ou falso, e os operadores lógicos atuam combinando esses retornos de acordo com a tabela verdade de cada operador. Sendo assim, a condição será testada na execução do comando, e somente se ela for verdadeira o programa acessará o trecho especial do código. Em uma linguagem bem desprendida, podemos dizer que o programa “entrou” no if. A demonstração da sintaxe e da construção do comando da estrutura condicional simples if pode ser vista no código a seguir: Disciplina Algoritmos e Lógica de Programação 1.#include<stdio.h> 2.int main() { 3. float temperatura; 4. printf("Digite a temperatura da sua cidade no dia de hoje: \n"); 5. scanf("%f", &temperatura); 6. if (temperatura < 5) 7. { 8. printf("Teste verdadeiro \n"); 9. printf("Prepare o agasalho!! \n"); 10. } 11. printf("A temperatura digitada foi: %f", temperatura); 12. } Na instrução if, a condição testada �ca entre parênteses. No exemplo, temos um único teste sendo executado no programa, e quando ele é verdadeiro o programa entra no bloco de código e mostra na tela as duas frases: “Teste verdadeiro” e “Prepare o agasalho!!”. Quando a condição é falsa, o programa sai da linha de veri�cação do comando if e vai para o �nal do código, que exibe na tela: “A temperatura digitada foi:”, ou seja, a linha localizada imediatamente após a estrutura condicional do if. Já no código a seguir está apresentada uma estrutura condicional composta. Neste caso, o programa tem somente duas opções de execução: o bloco referente ao if, quando a condição testada é verdadeira, ou o bloco referente ao else, quando a condição testada é falsa. Ou seja, ele mostrará “saldo negativo” somente se o teste do comando if der verdadeiro, ou saltará, ignorando o bloco do if, e entrará no bloco do else, mostrando “saldo positivo”. Após executar o bloco do if ou do else, ele sempre irá para a linha que mostra “Fim do programa”. Veja o código com instrução if e else a seguir: 1.#include<stdio.h> 2.int main() { 3. float saldo = 12.00; 4. if (saldo < 0) 5. printf("Saldo negativo \n"); 6. else 7. printf("Saldo positivo \n"); 8. printf("Fim do programa."); 9.} E se quisermos deixar o programa ainda mais elaborado, podemos utilizar a estrutura condicional composta, a qual é apresentada no código a seguir. Observe que o if que testa se o Disciplina Algoritmos e Lógica de Programação saldo é igual a zero só é acessado pelo programa quando a condição do primeiro teste for falsa, ou seja, quando não é um número negativo. Observe também que a segunda estrutura condicional, dentro do primeiro else, representa um único comando, e embora tenha sido escrita em quatro linhas, ela não precisa de delimitadores de chaves { } em sua sintaxe. Veja o código com instrução if encadeada, a seguir: 1. #include<stdio.h> 2. int main() { 3. float saldo = -12.00; 4. if (saldo < 0) 5. printf("Saldo negativo \n"); 6. else 7. if (saldo == 0) 8. Printf("Saldo zerado \n"); 9. else 10. printf("Saldo positivo \n"); 11. printf("Fim do programa."); 12.} Observe nesse código com a instrução if encadeada que temos um ótimo exemplo de como utilizar recursos de indentação, que consiste no deslocamento padrão do início do código na linha para caracterizar em que nível ele está. Embora a indentação auxilie na leitura humana do código, quando se faz necessário utilizar muitas estruturas condicionais encadeadas é recomendado empregar seleção de casos, como no código a seguir. Veja o código com seleção de casos, a seguir: 1. #include<stdio.h> 2. int main() { 3. int opcaoDigitada; 4. printf("Digite um numero:"); 5. scanf("%d", &opcaoDigitada); 6. switch (opcaoDigitada) 7. { 8. case 1: printf("Um"); break; 9. case 2: printf("Dois"); break; 10. case 3: printf("Tres"); break; 11. case 4: printf("Quatro"); break; 12. case 5: printf("Cinco"); break; 13. case 6: printf("Seis"); break; 14. default: printf("Invalido"); break; Disciplina Algoritmos e Lógica de Programação 15. } 16. } Observe que dentro de cada “case” há uma única instrução “printf;” entretanto, também poderia haver um bloco de comandos, e ele seria delimitado por chaves. É importante observar que qualquer outra tecla ou valor digitado e lido no “scanf”, que não estivesse nas opções, cairia no caso da linha 14: Invalido. Se este último código tivesse sido escrito somente com condicionais, certamente o programa�caria bem menos elegante. Antes que você pense que isso pode ser bobagem, imagine realizar a manutenção em um código escrito por outra pessoa (ou por você mesmo) há um tempo. A forma de elaborar o código facilitará ou di�cultará o trabalho e o entendimento no futuro. Programas com laços Muito do propósito dos sistemas computacionais é realizar tarefas e ações repetitivas, e para isso a linguagem C tem comandos especí�cos. Em português, chamamos essa circunstância de laço (loop, em inglês). Na prática, o programa �ca executando um comando ou um conjunto de comandos de forma repetida, em looping, enquanto uma condição for verdadeira. Na linguagem C, utilizamos o comando while() – o termo while signi�ca “enquanto”, em inglês –, e sua construção é muito similar à do comando if, mas com algumas diferenças. A principal delas é que, quando a condição é verdadeira, além de o programa entrar naquele trecho de Disciplina Algoritmos e Lógica de Programação código, ele continuamente repete o ciclo de executar os comandos e checar novamente essa condição, parando de executar os comandos desse trecho quando a condição for falsa. Um exemplo prático é o de veri�car a autenticação de um usuário pela digitação correta da senha. Se usássemos só o comando if, realizaríamos a veri�cação e retornaríamos indicando se a senha estava correta ou não, porém ainda não teríamos um mecanismo que repetisse essa veri�cação até que o usuário digitasse a senha correta. O código-fonte a seguir resolve o problema da senha. Veja o código com while, a seguir: 1. #include<stdio.h> 2. int main() { 3. int senhaDigitada; 4. int senhaCadastrada = 1923; 5. printf("Digite a sua senha: \n"); 6. scanf("%d", &senhaDigitada); 7. while (senhaCadastrada != senhaDigitada) 8. { 9. printf("\nSenha incorreta, por favor digite a sua senha: \n"); 10. scanf("%d", &senhaDigitada); 11. } 12. printf("Fim do programa! \n\n"); Observe o comando de leitura da senha: se quisermos deixar o programa mais compacto, poderemos utilizar o comando do { } while. Neste tipo de comando, a instrução (ou o conjunto de instruções) é executada e depois se realiza a veri�cação da condição. O código a seguir apresenta essa construção. Veja o código com do while, a seguir: 1. #include<stdio.h> 2. int main() { 3. int senhaDigitada; 4. int senhaCadastrada = 1923; 5. do 6. { 7. printf("\nPor favor digite a sua senha: \n"); 8. scanf("%d", &senhaDigitada); 9. } 10. while (senhaCadastrada != senhaDigitada); 11. printf("Fim do programa! \n\n"); 12. } Quando você estiver construindo seus programas, identi�cará quais são o comando e a construção mais adequados para o problema a ser resolvido. Em resumo (MANZANO, 2015): Disciplina Algoritmos e Lógica de Programação O comando while é chamado de laço pré-teste, pois realiza o teste lógico no início do laço, veri�cando se é possível executar o trecho de instruções subordinadas a ele. O comando do while é chamado de laço pós-teste. Ele sempre executa o bloco subordinado ao laço pelo menos uma vez, e então realiza o teste lógico para decidir se continua no looping ou se sai dele. Tanto o comando while quanto o do while permitem que sejam criados laços iterativos e interativos: Iterativo: que se repete. Interativo: que interage com o usuário. Como a condição de parada é o teste lógico dar falso, ao construir os comandos o programador precisa estabelecer o controle dessa parada, ou seja, quando o programa deve sair do loop. Porém, há casos em que há a necessidade de manter o programa em um loop in�nito, como um código que monitora constantemente um processo industrial ou uma cancela de pedágio, por exemplo. Para casos assim, é comum encontrar a seguinte construção: while (1), pois 1 é sempre verdadeiro e o programa �cará permanentemente neste loop. A linguagem C ainda oferece uma terceira opção para execuções sequenciais: o comando for (para, em português). Podemos ler o comando da seguinte maneira: “para i variando de 0 a 10, de um em um, faça tal ação”. Uma característica dessa construção é que, normalmente, ela é utilizada para laços com um número �nito e conhecido de execuções, como processar dados de uma lista ou um conjunto de números. Um exemplo da utilização do comando for é apresentado no código a seguir. 1.#include<stdio.h> 2.int main() { 3. int i, resultado; 4. for (i = 0; i <= 10; i++) 5. { 6. resultado = i * 2; 7. printf("2 x %d = %d \n", i, resultado); 8. } 9.} Videoaula: Estruturas condicionais em linguagem C Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo Disciplina Algoritmos e Lógica de Programação para assistir mesmo sem conexão à internet. Estudante, nesta aula conhecemos como utilizar condições para controlar os desvios e as repetições dos nossos programas. Você viu como o uso dos operadores lógicos e relacionais é a base para toda a construção das lógicas e o controle da execução do programa. A partir de estruturas condicionais como if e else, podemos criar desvios, e com os comandos while, do while e for conseguimos estruturar repetições de trechos especí�cos do código, sujeitos à parada por intervenção do usuário ou não, a depender da forma que são construídos. Vamos agora estudar mais alguns aspectos de implementação do nosso conteúdo? Saiba mais Como saber se seu programa está executando passo a passo de forma correta? Ou então, quando ele apresenta uma resposta incorreta, como saber em que momento o algoritmo se perdeu, para que possa ser estudada uma estratégia de correção? Na nossa aula, que aborda os desvios e os laços, vimos que é essencial poder “entrar” na execução do programa e acompanhar passo a passo cada linha executada. A melhor alternativa para isso é debugar seu código. A maioria dos ambientes de desenvolvimento integrado (IDEs) possui esse recurso. Disciplina Algoritmos e Lógica de Programação Como você sabe, cada IDE tem sua interface e seu posicionamento de botões. Então, para conseguir acessar o recurso na sua versão instalada, você deve realizar uma pesquisa no Google contendo o nome do IDE que você está utilizando, além dos termos “debugar” e “watches”. Na maioria dos IDEs instalados localmente, você deve posicionar o mouse em linhas estratégicas, que contenham as operações de interesse, e dar um clique duplo na linha ou clique com botão direito. O objetivo é inserir um ponto de interrupção (ou breakpoint), simbolizado por um círculo colorido, naquela linha. Ao executar o programa, ele parará em todos os pontos criados e mostrará os conteúdos de memória e os últimos cálculos realizados. Para excluir estes pontos, o processo é o mesmo. Outra possibilidade é utilizar o IDE OnlineGBD, que também permite o debug online. Neste caso, basta clicar uma vez ao lado esquerdo do número da linha para adicionar o breakpoint, e realizar um click duplo para removê-lo. Figura 1 | Tela do OnlineGBD com breakpoint na linha 17. Fonte: elaborada pela autora. Referências https://www.onlinegdb.com/ Disciplina Algoritmos e Lógica de Programação MANZANO, J. A. N. G. Linguagem C: acompanhada de uma xícara de café. São Paulo: Érica, 2015. Aula 4 Operadores na linguagem C Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante! Nesta aula, veremos como as operações de atribuição podem ser versáteis e nos fornecer mais opções de implementação quando complementadas com os operadores aritméticos. Você deve ter percebido que quanto mais recursos uma linguagem possui, melhores �cam o entendimento e a legibilidade do código-fonte, mais opções de comando o programador possui à sua disposição e há mais o que aprender. Muitas vezes, uma sutil alteração no sinal ou na escolha dos tipos e operadores pode produzir resultados totalmente diferentes, e consequentemente impactar a execução do programa. Venha conosco nesta aula para aprenderas variações desses comandos e não ter problemas em seu código-fonte! Atribuições e tipos de dados na execução Disciplina Algoritmos e Lógica de Programação Estudante, você tem visto na criação de programas com a linguagem C que é necessário realizar uma série de prede�nições já no início da construção do código-fonte, como a de�nição dos tipos de variáveis. Ao longo do código, uma escolha que também impactará em como será o funcionamento do programa é a forma com que construímos os comandos para realizar operações matemáticas, por meio dos operadores aritméticos, já que a linguagem permite variações com o mesmo símbolo. Isso quer dizer que, caso não conheçamos as particularidades da linguagem, podemos correr o risco de escrever um programa que apresente uma execução diferente daquela que esperávamos. Essas particularidades são decisões internas que o compilador está programado para tomar e que nem sempre estão explícitas no código ou no nosso pensamento lógico. Vamos tomar como ponto de partida a atribuição simples e, então, seguiremos estudando suas variações. O operador de atribuição, que tem seu símbolo representado por um único sinal de igual (=), é utilizado para inserir no termo à sua esquerda o resultado processado da operação à sua direita. Por exemplo: “resultado = 2 * valor”. Embora essa construção seja a mais simples que existe quando se trata de atribuição, pode ocorrer de o programador de�nir as variáveis “resultado” e “valor” em tipos diferentes, e o compilador precisar decidir sobre como processar o resultado, se apresenta um erro, se aceita a construção ou se realiza uma conversão durante essa atribuição. A conversão em tempo de execução junto com a atribuição é chamada de conversão de tipos em atribuições, e estudaremos suas variedades ao longo desta aula. Além desse tipo básico de atribuição, a linguagem C também permite outros, como as atribuições múltiplas, em que é possível atribuir o mesmo valor para múltiplas variáveis em um mesmo comando, como mostrado no código a seguir: Disciplina Algoritmos e Lógica de Programação 1. #include <stdio.h> 2.int main() 3.{ 4. int x, y, z; 5. x = y = z = 0; 6.} Devido a outro recurso interessante e bastante utilizado nos programas pro�ssionais, as operações de atribuição também podem conter elementos aritméticos na sua construção, os quais são chamados de operadores aritméticos, como o incremento e o decremento, ambos apresentados no código a seguir: 1. #include <stdio.h> 2.int main() 3.{ 4. int x, y; 5. x = y = 10; 6. x++; // o resultado dessa linha é x = 11 7. y--; // o resultado dessa linha é y = 9 8. 9. printf("x = %d, e y = %d", x, y); 10.} Observe que, ao utilizar “x++”, o programador consegue o mesmo resultado que teria se usasse “x = x+1”, porém com uma escrita mais compacta. E quando usadas em conjunto com um comando de atribuição, tanto a operação de incremento quando a de decremento possuem dois tipos de construção, como pode ser visto no exemplo do código a seguir: 1. #include <stdio.h> 2.int main() 3.{ 4. int x, A, B; 5. x = 10; 6. A = ++x; // incrementa antes de atribuir 7. printf("x = %d, e A = %d \n", x, A); 8. 9. x = 10; 10. B = x++; // atribui e depois incrementa 11. printf("x = %d, e B = %d", x, B); 12.} Disciplina Algoritmos e Lógica de Programação Existe uma diferença sutil entre as sintaxes “++x” e “x++”, e como estão sendo utilizadas junto com uma atribuição, a forma com que são construídos os comandos interfere muito em seu signi�cado para o programa. No primeiro caso, é realizado o incremento na variável x, e ao atribuir esse valor para a variável A, seu conteúdo já está incrementado, ou seja, ambas passam a valer 11. Já no segundo caso, o conteúdo de x, que é 10, primeiro é atribuído a B, e depois a variável x é incrementada para 11. Assim, B tem conteúdo igual a 10 e x é igual a 11. Estudante, você percebeu que a linguagem C permite uma ampla variedade nessas construções? Isso proporciona a você mais opções e recursos, mas ao mesmo tempo exige maior entendimento de suas regras. Conhecendo as variações das atribuições Os operadores em C podem ser unários, binários e ternários, e essa classi�cação está relacionada a quantos operandos constituem uma sentença correta para o operador. Vamos conhecer cada um deles com um exemplo: Unários: realizam uma modi�cação (ou não) em relação a apenas uma variável, como o sinal de menos. Exemplo: -x; -10. Binários: relacionam-se com os conteúdos de dois valores para retornar um terceiro valor como resultado, como o operador soma ou, ainda, o de atribuição. Exemplo: a + b; x = 10. Disciplina Algoritmos e Lógica de Programação Ternários: relacionam-se com três conteúdos, sendo usados para substituir as sentenças “if then else”. Assim como existe a notação de incremento e decremento nessa construção mais compacta, também existem opções compactas para implementar outras operações na linguagem C. Vamos conhecer as principais delas na Tabela 1. Tabela 1 | Operadores de atribuição. Um exemplo desses operadores sendo implementados em um código-fonte é apresentado a seguir: 1. #include <stdio.h> 2.int main() 3.{ 4. int saida; 5. saida = 6; 6. printf("saida multiplicacao = %d \n", saida *= 2); 7. 8. saida = 6; 9. printf("saida divisao = %d \n", saida /= 2); 10. 11. saida = 6; 12. printf("saida restante = %d \n", saida %= 2); 13. 14. saida = 6; 15. printf("saida adicao = %d \n", saida += 2); 16. 17. saida = 6; 18. printf("saida subtracao = %d \n", saida -= 2); 19.} Disciplina Algoritmos e Lógica de Programação Observe que a cada comando precisamos atribuir novamente o valor inicial 6 na variável saida, pois o comando de atribuição aritmética realiza tanto a operação aritmética quanto a atribuição na variável, atualizando seu valor. Por manipular dois operandos, os operadores da Tabela 1 são considerados binários. Outra classe interessante dos operadores é sua aplicação com valores binários. Para demonstrá- los, considere: Uma variável X, de valor 18, em binário 0001 0010. Uma variável Y, de valor 98, em binário 0110 0010. A operação AND bit a bit entre X e Y se refere a realizar a operação AND (operador lógico) entre todos os bits do número, um a um, e escrever o valor correspondente. Para o exemplo, X & Y resulta em: 0000 0010, ou seja, 2. Cabe destacar que a operação lógica && realizada em valores decimais produz um resultado diferente da operação AND bit a bit, representada pelo símbolo unitário &. O operador &= realiza o AND bit a bit entre as variáveis que compõem o comando e atribui esse valor ao operando da esquerda. Seguindo o mesmo raciocínio, considere também os outros operadores especí�cos para representações em binário, apresentados na Tabela 2. Tabela 2 | Operadores de atribuição para binários. Fonte: adaptada de Microsoft (2022, [s. p.]). E uma aplicação em código-fonte resulta no código a seguir: 1. #include <stdio.h> 2.int main() 3.{ 4. // 3 = 0b0111; 5. int x; 6. x = 0b1001; //valor 9 em decimal 7. x &= 3; // será 0b0001, ou seja, 1. Disciplina Algoritmos e Lógica de Programação 8. printf("saida AND bit a bit = %d \n", x); 9. 10. x = 0b00001001; //valor 9 em decimal 11. x <<= 3; // será 0b01001000, ou seja, 72. 12. printf("saida shift esquerda = %d \n", x); 13.} O operador de deslocamento atua deslocando todos os bits do número à esquerda ou à direita, sendo que, conforme os bits são deslocados para um dado sentido, zeros são usados para preencher as lacunas. No exemplo apresentado no código, a variável binária x teve seus bits deslocados em três posições para a esquerda, e como esse novo número foi atribuído a ela, deixou de ser o número 0b00001001 (9 em decimal) para ser 0b01001000 (72 em decimal). Uma curiosidade a respeito de números binários é que cada deslocamento para a esquerda é equivalente a multiplicar o númeropor 2. Sua aplicação se dá principalmente na programação de microcontroladores ou drivers que necessitam de controle do hardware. O maior desa�o na utilização desses operadores é que a escrita deles é muito similar às operações matemáticas tradicionais. Ao analisá-la, o programador precisa ter o mesmo entendimento que o compilador terá ao realizar o build do código, pois muitas vezes podemos cair em ambiguidades permitidas pela linguagem. Na dúvida, devemos fazer o debug do código, a �m de veri�car por meio dos testes de mesa se a execução do nosso programa está ocorrendo conforme esperado. Aplicando conceitos de conversões de tipos Disciplina Algoritmos e Lógica de Programação Outro aspecto que também requer a atenção do programador diz respeito ao tipo das variáveis manipuladas e aos desdobramentos lógicos que podem ocorrer ao longo da execução do programa. Esse tipo de situação ocorre com a utilização dos operadores multiplicação (*), divisão (/) e restante (%), pois essas operações costumam interferir no tipo do operando. Considere que temos os números 13 e 5 para realizar uma divisão. Sabemos que 13 dividido por 5 é igual a 2,6. Ao mesmo tempo, quando lidamos com problemas do dia a dia, podemos ter a necessidade de construir raciocínios mais especí�cos. Por exemplo: recebemos 13 camisetas para serem distribuídas para 5 pessoas. Como não faria sentido cortar as camisetas, teríamos que 13 (int) dividido por 5 (int) é igual a 2 (int) com resto 3 (int). Com os operadores, essas sentenças seriam escritas como: 13 / 5 = 2 para a divisão com inteiros e 13 % 5 = 3 para o cálculo da operação resto, também chamada de restante ou módulo. 1. #include <stdio.h> 2.int main() 3.{ 4. float resultado; 5. int x, y; 6. 7. x = 13; y = 5; 8. printf("resultado = %f \n", resultado = x/y); 9. Disciplina Algoritmos e Lógica de Programação 10. x = 13.0; y = 5.0; 11. printf("resultado = %f \n", resultado = x/y); 12. 13. x = 13.0; y = 5.0; 14. printf("resultado = %f \n", resultado = x%y); 15.} Observe que, mesmo tentando inserir um valor do tipo real nas variáveis x e y, o resultado apresentado na divisão não é 2.6, pois x e y foram declarados como inteiros e nas linhas de atribuição eles já perdem a precisão de 13.0 e 5.0, sendo tratados como inteiros 13 e 5. Avaliando o mesmo código-fonte, porém com x e y do tipo �oat, percebemos que a divisão é feita como esperado, mas o código apresenta um erro de compilação na linha do último printf, pois o operador % não pode ser utilizado com variáveis de tipo �oat, já que o compilador tentaria realizar a divisão com diversas casas após a vírgula, tantas quantas fossem necessárias, conforme a quantidade de dígitos do tipo da variável escolhida, e, portanto, a divisão não apresentaria resto. Tipos diferentes podem incorrer em truncamento ou perda de precisão, como detalhado a seguir: O truncamento consiste em salvar a parte inteira de um número, ignorando as casas decimais. A perda de precisão é a representação de um número com menos casas decimais do que ele possui, o que também ignora parte dos dígitos. Ao mesmo tempo, a linguagem C permite que o programador “adeque” tipos de variáveis para contornar problemas de tipos que poderiam ocorrer em tempo de execução, como o truncamento ou a perda de precisão. A realização dessa modi�cação pelo programador recebe o nome de casting. Damas (2016) descreve que o casting se dá quando queremos modi�car o tipo de uma variável ou expressão, alterando-o para um tipo maior ou para um tipo mais baixo, e que podemos indicar o tipo ao qual queremos “promover” esse valor colocando o tipo pretendido entre parênteses antes do valor. Um exemplo dessa modi�cação é apresentado no código a seguir: 1. #include <stdio.h> 2.int main() 3.{ 4. float result; 5. int valor, div; 6. 7. valor = 10; 8. div = 4; 9. Disciplina Algoritmos e Lógica de Programação 10. result = valor / div; 11. printf("Resultado: %f \n", result); // resultado truncado 12. 13. result = 1.0 * valor / div; 14. printf("Resultado: %f \n", result); // resultado forçado pelo 1.0 * 15. 16. result = (float) valor / div; 18. printf("Resultado: %f \n", result); // valor convertido em float (casting) 19. 20. result = valor / (float) div; 21. printf("Resultado: %f \n", result); // div convertido em float (casting) } Observe que esse código indica a solução para o problema do código anterior, que não apresentava a saída em número real. Neste último código também vemos outro recurso interessante, que é o comentário no código. Tudo o que está escrito na mesma linha após o // é ignorado pelo compilador. Então, tal recurso é usado para que o programador possa registrar comentários que auxiliem na leitura e no entendimento do código, embora as boas práticas de programação digam que um código bem escrito, com padrão na nomenclatura de variáveis, não necessita de comentários. Videoaula: Operadores na linguagem C Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Estudante, aprendemos nesta aula como o programa pode apresentar respostas inesperadas ou incompletas se não de�nirmos os tipos de variáveis corretamente. Vimos que o compilador segue à risca os tipos que de�nimos, mas também permite alguns recursos que alteram o tipo da variável mesmo em tempo de execução, realizando uma conversão explícita. Quanto aos exemplos, eles não acabaram, então acompanhe o vídeo para estudarmos como funciona a conversão de tipos implícita. Saiba mais Disciplina Algoritmos e Lógica de Programação A manipulação de caracteres e inteiros pode ocasionar di�culdades na legibilidade do código, principalmente pelas conversões implícitas que a linguagem C permite na execução dos programas. Para essas construções especí�cas, Luís Damas organizou uma subseção em sua obra, com alguns exemplos detalhadamente descritos. O livro Linguagem C está na nossa biblioteca virtual, e o capítulo que aborda esse assunto está na subseção Situações em que inteiros e caracteres não se devem misturar, na página 43. Referências Disciplina Algoritmos e Lógica de Programação DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2016. MANZANO, J. A. N. G. Linguagem C: acompanhada de uma xícara de café. São Paulo: Érica, 2015. MICROSOFT. Operadores de atribuição C. 2022. Disponível em: https://learn.microsoft.com/pt- br/cpp/c-language/c-assignment-operators?view=msvc-170. Acesso em: 27 nov. 2022. Aula 5 Revisão da unidade Conceitos de programação https://learn.microsoft.com/pt-br/cpp/c-language/c-assignment-operators?view=msvc-170 https://learn.microsoft.com/pt-br/cpp/c-language/c-assignment-operators?view=msvc-170 Disciplina Algoritmos e Lógica de Programação Olá, estudante! Chegamos ao �nal de mais uma unidade. Neste nosso estudo, tivemos a oportunidade de conhecer muitos comandos e, assim, construir os programas na linguagem C. Nós vimos que os comandos possuem uma construção um pouco mais complexa do que a construção em pseudocódigo, por exemplo, sendo consequentemente bem mais detalhada que a descrição narrativa. Enquanto a descrição narrativa e o pseudocódigo são uma representação lógica do propósito do algoritmo, com certa �exibilidade na escrita, pois normalmente são feitos para outros humanos os interpretarem, os códigos escritos em linguagens de programação são produzidos para serem interpretados e/ou compilados por máquinas. Então, tudo o que compõe o código escrito pelo programador será transformado pelo compilador em um comando equivalente em linguagem de máquina, e nessa transformação não pode haver ambiguidade ou erros. Por isso, o compilador também se antecipa em apontar erros na construção do programa, que podem ou não impedir sua execução. Um software que agrega o editor especializado de código e o compiladoré o IDE (Integrated Development Environment). Algumas das veri�cações que o compilador realiza são em relação aos dados que o programa manipulará, pois como variáveis ou constantes, seus identi�cadores e tipos escolhidos devem ter comportamento coerente em todo o código. Por exemplo, se houver algum identi�cador no código que não seja uma palavra reservada da linguagem nem uma variável declarada pelo programador, o compilador apresentará um erro referente a esse termo desconhecido. Da mesma forma, e com o objetivo de construir adequadamente o código de máquina, os compiladores também veri�cam os comandos que foram inseridos no programa, tais como comandos de entrada e saída, operadores de atribuição, aritméticos e lógicos, além dos outros termos que interagem com os comandos, como as variáveis, as constantes e os valores Disciplina Algoritmos e Lógica de Programação inseridos diretamente no código. Nós estudamos os operadores existentes na linguagem C e como devem ser construídos para cada caso de interesse. Outros comandos bem importantes na linguagem C são as estruturas condicionais e de repetição, sendo que ambas são recursos que o programador possui para controlar os caminhos que o programa pode tomar e que diferem da execução sequencial, linha após linha. Todos esses recursos são importantes para a construção de programas versáteis. Videoaula: Revisão da unidade Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. As especi�cidades que existem na linguagem C e em outras linguagens exigem que o programador conheça as regras, a sintaxe e o signi�cado dos comandos. Nossa unidade foi toda dedicada a essas regras, e nesta revisão precisamos nos certi�car de que você está por dentro delas. Vamos lá? Estudo de caso Disciplina Algoritmos e Lógica de Programação Estudante, você está desenvolvendo um plugin que está inserido em um site de comércio eletrônico. Ele deve atuar da seguinte maneira: Deve informar ao cliente que as compras à vista possuem 5% de desconto, e isso se refere à modalidade de pagamento em PIX, débito e dinheiro. Também deve informar ao cliente que as compras de valor acima de R$ 100 podem ser parceladas em até 6 vezes. O programa deve pedir como entrada o valor da compra, simulando um sistema em que o total da compra poderia vir do carrinho de compras ou similar. A saída esperada é o programa mostrar na tela as opções de pagamento e seus respectivos valores à vista e em até 6 parcelas no crédito. ______ Re�ita Considere a seguir alguns pontos para direcioná-lo: O programa deve apresentar como saída as informações expressas na Figura 1. Disciplina Algoritmos e Lógica de Programação Figura 1 | Saída do programa. Fonte: captura de tela elaborada pela autora. É importante sempre validar a entrada do usuário, não permitir que ele insira valores negativos e exigir nova digitação em caso de entrada inválida. Pense também na validação de entrada zero. A�nal, se o cliente digitar 0, será que ele terá direito a desconto? Outra observação: se a loja mudar de 6 para 60 vezes o parcelamento, isso deveria promover alteração somente em um comando do código? Atente para essa questão e mãos à obra! Videoaula: Resolução do estudo de caso Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. O código pode ser construído de formas diferentes da que está proposta a seguir, desde que a saída seja equivalente e que os comandos de desvio e repetição sejam utilizados de forma coerente. O código sugerido para a resolução é: Disciplina Algoritmos e Lógica de Programação 1.#include<stdio.h> 2. 3.int main() { 4. 5. float valorCompra, valorAvista, valorParcelas = 0; 6. int parcelas, i = 0; 7. 8. printf("Compra a vista 5%% de desconto: pix, debito e dinheiro \n"); 9. printf("As compras a partir de R$ 100,00 podem ser parceladas em ate 6x \n \n \n"); 10. 11. do { 12. printf("Digite o valor da compra: \n"); 13. scanf("%f", &valorCompra); 14. } while(valorCompra <= 0.1); 15. 16. printf("\n"); 17. valorAvista = valorCompra - 0.05 * valorCompra; 18. 19. printf("Pagamento a vista: R$ %4.2f \n", valorAvista); 20. printf("1 parcela de R$ %4.2f \n", valorCompra); 21. 22. if(valorCompra >= 100) 23. for (i = 2; i<=6; i++) { 24. valorParcelas = valorCompra/i; 25. printf("%i parcelas de R$ %4.2f \n", i, valorParcelas); 26. }; 27. 28. printf("\n"); 29. 30.} Resumo visual Disciplina Algoritmos e Lógica de Programação Quando usar cada comando? Disciplina Algoritmos e Lógica de Programação Referências Disciplina Algoritmos e Lógica de Programação MANZANO, J. A. N. G. Linguagem C: acompanhada de uma xícara de café. São Paulo: Érica, 2015. , Unidade 4 Aplicações de programação Aula 1 Programação e funções com vetores Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante, hoje vamos iniciar uma nova unidade da disciplina de algoritmos e lógica de programação, em que você verá na prática a programação de uma estrutura de dados baseada em vetores, que é um recurso muito utilizado na engenharia. Na programação, o vetor é usado para manipular um conjunto de dados de um mesmo tipo primitivo (inteiro, real, caracter). Estes �carão em posições contiguas da memória do computador, permitindo o seu acesso de uma forma mais fácil e rápida. Nesta unidade estudaremos a sintaxe e a codi�cação destes vetores, usando a linguagem de programação C. Vamos ver que os conceitos de declaração de variáveis, estrutura de repetição e de vetores estudados nas unidades anteriores serão importantes e muito bem aplicados nesta unidade. Então, estudantes, vamos em frente. Programação de vetores em uma pseudolinguagem: programação e funções com vetores Disciplina Algoritmos e Lógica de Programação Caro estudante, o vetor é uma estrutura que permite armazenar vários dados do mesmo tipo em uma mesma variável. Por exemplo: se quisermos armazenar em um programa as notas que 40 alunos tiveram em uma determinada prova de uma disciplina e não tivéssemos o vetor, precisaríamos usar no programa 40 variáveis com nomes distintos, sendo armazenada em cada variável a nota de um aluno. Com o uso de vetor, vamos conseguir armazenar em uma única variável as notas dos 40 alunos. Esta variável terá dentro dela 40 posições, sendo que, em cada posição, vamos incluir a nota de um aluno. O vetor também é chamado de estrutura composta homogênea unidimensional, em que: Estrutura composta consiste nas várias posições que teremos na variável. Homogênea porque estas posições são do mesmo tipo de dado (inteiro, real, caracter). Unidimensional porque tem uma única dimensão; o multidimensional é uma matriz. O vetor passa a existir a partir da sua declaração, quando, então, lhe são associados um nome ou identi�cador e a respectiva posição de memória por ela representada. Qualquer referência ao seu identi�cador signi�ca o acesso ao conteúdo de uma única posição de memória (FARRER, 1999). As posições do vetor são guardadas em uma sequência contínua de memória, ou seja, uma posição seguida da outra. A diferença da declaração de um vetor e de uma variável normal do programa está na parte que vem após o nome, em que, na declaração do vetor, tem-se a quantidade de posições do vetor entre colchetes. Exemplo de nome do vetor: Vnota[40]; Exemplo de declaração do vetor: Real Vnota[40]; Disciplina Algoritmos e Lógica de Programação No qual temos: Real: tipo primitivo de dados do vetor, indicando que em cada posição do vetor, será inserido um número do tipo real da matemática; Vnota: nome da variável do tipo vetor. Neste exemplo, será a nota dos alunos;40: quantidade de posições do vetor. Neste exemplo, cada posição conterá a nota de um aluno. Percebam que na declaração do vetor, ele é de�nido com 40 posições. Estas posições são numeradas sequencialmente, iniciando com a posição 0 até a posição 39. Chamamos estas posições de índice do vetor. Figura 1 | Vetor Vnota. Fonte: elaborada pelo autor.. Agora vamos trabalhar com este vetor, usando uma pseudolinguagem, inserindo nas posições do vetor as notas dos alunos. A posição que desejamos inserir a nota, colocamos entre os colchetes: Vnota [ 6 ] = 6,5; // será inserido o valor 6,5 na posição 6 do vetor Vnota [ 1 ] = 7,8; Vnota [ 3 ] = 5,3; Figura 2 | Vetor Vnota. Fonte: elaborada pelo autor. Conseguimos acessar as posições de forma aleatória, ou seja, fomos para a 6ª posição, depois para a 1ª posição e depois para a 3ª posição do vetor. Vamos incluir novos elementos no vetor, mas usando uma nova variável A, que terá a posição em que será incluído o elemento no vetor. Disciplina Algoritmos e Lógica de Programação Inteiro A; Leia (A); // supondo que foi informado 5 Vnota[ A ] = 9,8; Vnota [ A-1 ] = 9,1; Leia (Vnota [ A+2 ] ); // supondo que foi informado 4,7 No �nal da execução, o vetor �cará da seguinte forma: Figura 3 | Vetor Vnota. Fonte: elaborada pelo autor. Programação de vetores na linguagem C Disciplina Algoritmos e Lógica de Programação Vamos agora aprofundar nossos conhecimentos referentes à codi�cação de vetores, trabalhando em um exemplo da codi�cação do vetor na linguagem de programação C. Vamos usar o mesmo vetor Vnota que codi�camos anteriormente uma pseudolinguagem, mas agora, vamos implementá-lo na linguagem de programação C. Para facilitar a aprendizagem, será mostrado o código em C, numerando as linhas do programa e, em seguida, será comentada cada uma das linhas. 1 #include <stdio.h> 2 main() 3 { 4 float Vnota[40]; 5 int A; 6 Vnota [6]=6.5; 7 Vnota [1]=7.8; 8 Vnota [3]=5.3; Inicialmente, foi declarada na linha 1 do programa, a biblioteca stdio.h da linguagem C, para usarmos os comandos de entrada e saída de dados printf e scanf. A linha 2 tem a declaração do programa principal e na linha 3 o início do seu bloco. Na linha 4, foi criado o vetor Vnota, com 40 posições e nas linhas 6, 7 e 8 foram incluídas as notas 6,5, 7,8 e 5,3 nas posições 6, 1 e 3 do vetor. Dando sequência na codi�cação do programa do vetor, temos: 9 printf ("Digite o valor de A: "); 10 scanf("%d",&A); 11 Vnota[A]=9.8; 12 Vnota[A-1]=9.1; 13 printf("Digite o valor de Vnota[A+3]: "); 14 scanf("%d",&Vnota[A+3]); 15 printf ("Valores do vetor:"); 16 for (int x=0;x<10;x++) 17 printf ("\nVnota[%d] = %.1f",x,Vnota[x]) ; 18 } Nas linhas 9 e 10, foi solicitada a entrada de um dado do tipo inteiro que será armazenado na variável A. O valor desta variável está sendo usado como posição de memória para a inclusão da nota 9,8. Se for digitado o valor 5, a nota 9,8 será inserida na posição 5 do vetor, conforme mostrado na linha 11. Na linha 12, foi subtraído 1 do valor digitado, ou seja, se foi digitado o valor 5, a nota 9,1 será incluída na posição 4 do vetor. Na linha 13 e 14, foi solicitada a digitação de uma nota, sendo esta inserida na posição A+3, ou seja, a nota digitada será inserida na posição 8, se o valor digitado para A foi 5. Disciplina Algoritmos e Lógica de Programação Para acessar todas as posições do vetor, precisamos usar uma estrutura de repetição. Dentro desta estrutura de repetição conseguimos acessar todos os elementos do vetor. A estrutura de repetição mais indicada para a manipulação do vetor é o Para (valor inicial do índice, condição de repetição, incremento do índice). A codi�cação desta estrutura de repetição está nas linhas 16 e 17 deste código. Como pode ser observado, a estrutura de repetição se inicia com o valor 0 no índice, para acessar a 1ª posição do vetor, incrementando de 1 em 1 para cada execução dos comandos que fazem do bloco da estrutura de repetição, até a última posição do vetor. Com a execução do programa, a saída que será mostrada será a seguinte: Figura 4 | Tela do DEV C++ com a saída da execução do programa. Fonte: captura de tela do DEV C++ elaborada pelo autor. Manipulação das variáveis do vetor Disciplina Algoritmos e Lógica de Programação Um algoritmo clássico em que precisamos usar vetor é quando precisamos ler determinados valores, fazer algum tipo de cálculo com os dados e depois comparar o que foi calculado com os valores lidos. Por exemplo: lançar as notas dos alunos de uma determinada disciplina e depois mostrar a quantidade de notas maiores que a média. Para resolver, é necessário ler todas as notas e armazená-las em um vetor. Com os valores armazenados, será possível manipulá-los. Então vamos resolver da seguinte forma: (1) ler as notas dos alunos, (2) calcular a média aritmética, (3) comparar cada nota com a média calculada (4) contar as notas maiores que a média (5) mostrar a quantidade. O algoritmo que implementa este exemplo segue abaixo: 1 #include <stdio.h> 2 main() 3 { 4 float Vnota[10], somanota=0, media; 5 int somamaior=0; 6 for (int x=0;x<10;x++) 7 { 8 printf ("Digite a nota %d :",x+1); Disciplina Algoritmos e Lógica de Programação 9 scanf("%f",&Vnota[x]); 10 somanota = somanota + Vnota[x]; 11 fflush(stdin); 12 } 13 media = somanota / 10; 14 printf (" Media das notas: %.1f",media); 15 for (int x=0;x<4;x++) 16 { 17 if (Vnota[x]>media) 18 somamaior ++; 19 } 20 printf ("Quantidade de notas maiores que a media: %d",somamaior); 21 } Vamos fazer um outro exercício com vetor, mas agora os elementos do vetor serão inicializados quando forem declarados. Depois vamos somar os elementos do vetor e mostrar o resultado da soma. 1 #include <stdio.h> 2 #include <stdio.h> 3 main() 4 { 5 int vetor[5]={1,3,5,7,9},soma=0; 6 for (int cont=0;cont<5;cont++) 7 soma = soma + vetor[cont]; 8 printf("Soma dos elementos do vetor: %d",soma); 9 } Continuando este mesmo programa, agora vamos mostrar o vetor que foi declarado e inicializado na linha 4, de trás para frente, ou seja, o último elemento do vetor será o último mostrado, o penúltimo será o segundo e assim sucessivamente. 9 #include <stdio.h> 10 for (int cont=4;cont>=0;cont--) 11 printf("\nElemento %d do vetor: %d",cont,vetor[cont]); 12 } Veja que, para mostrar o vetor de trás para frente, foi codi�cada uma estrutura de repetição, iniciando com o valor do maior índice do vetor e decrementando de 1 até a primeira posição do vetor. Disciplina Algoritmos e Lógica de Programação Videoaula: Programação e funções com vetores Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, vamos agora ao vídeo, em que você verá uma explicação como se programam vetores na linguagem de programação C. No vídeo, usaremos este recurso da programação e explicaremos como você deve fazer para codi�cá-lo, considerando a sua sintaxe e a sua lógica. Vamos ver também que os conceitos de lógica, estrutura de repetição e de vetores estudados são muito bem usadas nesta unidade. Saiba mais Para codi�car programas na linguagem de programação C, você deverá usar um aplicativo que tenha as ferramentas necessárias para programar em C/C++. Disciplina Algoritmos e Lógica de Programação Recomendamos o uso do Bloodshed Dev C++. Este pacote compõe um ambiente completo de desenvolvimento para a criação, debug e compilação do código de programação em C, e pode ser analisado e ser feito download em seu site. Referências FARRER, H. et al. Algoritmos estruturados. Rio de Janeiro: LTC Editora, 1999. MIZRAHI, V. V. Treinamento em Linguagem C: módulo 1 e 2. São Paulo: Pearson Prentice Hall, 2007. Aula 2 Programação com matrizes Introduçãohttps://www.bloodshed.net/ Disciplina Algoritmos e Lógica de Programação Olá, estudante, hoje vamos para um novo tópico da disciplina Algoritmos e Lógica de Programação, em que você verá na prática a programação de uma estrutura de dados baseada em matrizes. Nesta aula, estudaremos a sintaxe e a codi�cação de matrizes, usando a linguagem de programação C. Vamos ver que a aprendizagem do funcionamento de um vetor estudado anterioriormente é muito importante para o entendimento de matrizes, por ser uma estrutura composta homogênea que traz uma maior complexidade na sua codi�cação. Vamos ver também que a matriz é um instrumento muito usado pelos programadores para resolver vários problemas do dia a dia na programação. Então, estudantes, vamos em frente. De�nição, características e sintaxe de matrizes Disciplina Algoritmos e Lógica de Programação Caro estudante, vamos estudar outra forma de organizar os dados dentro de uma estrutura baseada em matrizes da matemática. Enquanto um vetor é uma estrutura de dados homogênea unidimensional, pelo motivo de crescer os dados de estrutura apenas em uma direção, que é para o lado direito, na forma de linha, a matriz é uma estrutura de dados homogênea multidimensional, por permitir crescer os dados da estrutura em mais de uma direção, que é para o lado direito (linha) e para baixo (coluna). Vamos ver isto no exemplo abaixo: Exemplo de um vetor com 8 elementos, uma letra em cada posição do vetor: Figura 1 | Vetor Letras[8]. Fonte: elaborada pelo autor. Se quisermos inserir novos elementos no vetor, estes deverão ser incluídos em novas posições, que �carão do lado direito, na mesma linha. Agora vamos para um exemplo de uma matriz, com 8 elementos divididos em linhas e colunas. Disciplina Algoritmos e Lógica de Programação Figura 2 | Matriz Letras[2,4]. Fonte: elaborada pelo autor. Veja que organizamos os mesmos dados representados no vetor, mas agora em 2 linhas e 4 colunas. Esta forma de organização de estrutura de dados foi feita em uma matriz [2,4]. Se quisermos incluir novos elementos na matriz, podemos inclui-los em uma nova coluna no lado direito, mas também podemos incluí-los em uma nova linha, abaixo da existente. Da mesma forma que o vetor, as matrizes precisam ter um nome e precisam ter índices para identi�car a posição dos seus elementos. Como a matriz que estamos representando possui 2 dimensões, baseada na linha e na coluna, precisamos de 2 índices para identi�car uma posição de um elemento na matriz, o primeiro identi�ca a linha e o segundo identi�ca a coluna. Por exemplo: Elemento da posição da matriz Letra [0,2] = C. Elemento da posição da matriz Letra [1,3] = H. A matriz também é uma estrutura composta homogênea, com isto, todos os seus elementos devem ter o mesmo tipo primitivo de dado (inteiro, real, caracter). Com isto, quando declaramos uma matriz, precisamos identi�car qual é o tipo de dados que serão inseridos nas suas posições. Por exemplo: Caracter Letra[2,4] => é uma matriz em que poderão ser inseridos até 8 elementos do tipo caracter. Em que temos: Caracter: tipo primitivo de dados do vetor, indicando que em cada posição do vetor, será inserido um caracter. Disciplina Algoritmos e Lógica de Programação Letra: nome da variável do tipo matriz. 2: quantidade de linhas da matriz 4: quantidade de colunas da matriz. Percebam que na declaração da matriz, ela é de�nida com 8 posições divididas em 2 linhas e 4 colunas. O índice para a linha é numerado sequencialmente, iniciando com 0, da mesma forma para a coluna, que também tem um índice iniciando com 0. Outro exemplo: Real Nota[3,4] => é uma matriz em que poderão ser inseridos até 12 elementos do tipo real. Programação de matrizes na linguagem C Vamos agora aprofundar nossos conhecimentos na codi�cação de matrizes na linguagem de programação C. Vamos usar como exemplo o mesmo Vnota que usamos para codi�cá-lo na forma de vetor, mas, agora, vamos trabalhar com o Vnota na forma de uma estrutura de dados homogênea bidimensional, que é uma matriz. Para facilitar a aprendizagem, será mostrado o código em C, numerando as linhas do programa e, em seguida, será comentada cada uma das linhas. 1 #include <stdio.h> 2 main() Disciplina Algoritmos e Lógica de Programação 3 { 4 float Vnota[4][10]; 5 int x,y; 6 Vnota [0][0]=8.1; 7 Vnota [0][2]=6.5; 8 Vnota [1][4]=7.8; 9 Vnota [2][6]=9.4; 10 printf ("Digite o valor de X: "); 11 scanf("%d",&X); // Será digitado o valor 2 12 printf ("Digite o valor de Y: "); 13 scanf("%d",&Y); // Será digitado o valor 1 14 Vnota[x][y]=6.0; 15 Vnota[x][y+1]=3.9; 16 Vnota[x+1][y+2]=7.0; 17 printf("Digite o valor de Vnota[9.9]: "); 18 scanf("%d",&Vnota[9][9]; // Será digitado o valor 8.4 22 } Com a inserção destes elementos na matriz, ela �ca desta forma: Figura 3 | Matriz �oat Vnota[4,10]. Fonte: elaborada pelo autor. Na linha 4, foi declarada uma matriz com nome Vnota, com 40 posições, organizada na forma de 4 linhas e 10 colunas, sendo os elementos da matriz do tipo de dados �oat (Real). Nas linhas 6 a 9, foram inseridos elementos na matriz nas posições [0,0], [0,2],[1,4] e [2,6]. Disciplina Algoritmos e Lógica de Programação Nas linhas 11 e 13 foram solicitadas a entrada de dois dados do tipo inteiro que serão armazenados respectivamente nas variáveis x e y. Supondo neste exemplo que foram digitados os valores 2 para x e 1 para y. Na linha 14 os valores da variáveis x e y foram usados para a inclusão do elemento 6.0 na posição [2,1] da matriz. Na linha 15 a variável y que é usada para indicar a coluna, foi incrementada de 1, com isto, o elemento 3.9 foi incluído na posição [2,2] da matriz. Na linha 16, a variável x que é usada para indicar a linha, foi incrementada de 1 e a variável y que é usada para indicar a coluna, foi incrementada de 2, com isto, o elemento 7.0 foi incluído na posição [3,3] da matriz. Na linha 17 e 18, foi solicitado a digitação de uma nota, sendo está inserida na posição [9,9] da matriz. Para acessar todos os elementos de uma matriz, precisamos usar uma estrutura de repetição dentro de outra estrutura de repetição, em que a estrutura de repetição externa vai passar por todas as linhas e a estrutura de repetição interna vai passar pelas colunas da matriz. Vamos ver este exemplo: 1 for (x=0;x<4;x++) 2 { 3 for (y=0;y<10;y++) 4 printf ("\n Nota: %.2f,",Vnota[x][y]); 5 } A variável x é para a linha e a variável y é para a coluna. Iniciamos a variável x com o valor 0 na estrutura de repetição que está na linha 1. A estrutura de repetição que está na linha 3 inicia com a variável y com valor 0, então será mostrado o elemento de Vnota[0,0], que é o comando da linha 4. A estrutura de repetição de linha 3 incrementa 1 em y, mostrando o elemento de Vnota[0,1] e �ca neste looping até que y tenha o valor 10, ou seja, serão mostrados todos os elementos da linha 0 da matriz. Depois, o programa volta para e estrutura de repetição da linha 1, incrementando 1 em x e executa novamente a estrutura de repetição da linha 3, voltando y com o valor 0. Com isto, é percorrida toda a linha 1 da matriz. Este processamento �ca até que x tenha o valor 5, saindo da estrutura de repetição da linha 1. Como pode ser observado, a estrutura de repetição se inicia com o valor 0 no índice, para acessar a 1ª posição do vetor, incrementando de 1 em 1 para cada execução dos comandos que fazem do bloco da estrutura de repetição, até a última posição do vetor. Implementação de matrizes Disciplina Algoritmos e Lógica de Programação Agora vamos codi�car uma matriz para atender o seguinte enunciado: Faça um programa em C que tenha uma matriz M[3,4] e insira os valores 1 a 12 nos elementos da matriz, conforme �gura abaixo. Depois some os elementos da matriz que estão marcados em vermelho. Disciplina Algoritmos e Lógica de Programação Figura 4 | Matriz int M[3,4]. Fonte: elaborada pelo autor. Podemos perceber que a matriz tem valores sequenciais para os elementos e queos elementos que estão marcados em vermelho são os que estão na posição em que o valor da coluna é maior que o valor da linha. Desta forma, podemos codi�car o programa da seguinte forma: 1 #include <stdio.h> 2 main() 3 { 4 int M[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12},soma=0; 5 for (int x=0;x<3;x++) 6 { 7 for (int y=0;y<4;y++) 8 { 9 if ( y > x) 10 soma= soma + M[x][y]; 11 } 12 } 13 printf("Soma dos elementos:%d",soma); 14 } Disciplina Algoritmos e Lógica de Programação Na linha 4 do programa, inicializamos a matriz no mesmo momento da sua declaração, como uma matriz [3][4] tem 12 elementos, �zemos uma de�nição sequencial de 1 a 12 entre chaves logo após a declaração de matriz. Como é solicitado que sejam somados somente os elementos em vermelho e estes elementos são os que a coluna é maior que a linha, consideramos no programa que a variável x para a linha, declarado na estrutura de repetição externa e y para a coluna, declarado na estrutura de repetição interna. Na linha 9, foi codi�cada uma condicional, considerando somente os elementos nos quais o valor de y (coluna) for maior que x(linha). Como resultado da execução do programa, teremos: Soma dos elementos: 36 Vamos para um segundo enunciado em que se faz necessário o uso de matriz: Faça um algoritmo que leia uma matriz M[3,3] e um valor X. A seguir, multiplique cada elemento da matriz pelo valor X, colocando o resultado da multiplicação de cada elemento da matriz em um vetor V[9]. No �nal, o algoritmo deve listar todos os elementos do vetor. Veja que para a codi�cação deste programa, vamos usar os conhecimentos de matrizes e vetores. 1 #include <stdio.h> 2 main() 3 { 4 int M[3][3],V[9],cont=0; 5 for (int x=0;x<3;x++) 6 { 7 for (int y=0;y<3;y++) 8 { 9 printf (" Valor: "); 10 scanf("%d",&M[x][y]); 11 V[cont]=M[x][y]; 12 cont++; 13 } 14 } 15 for (cont=0;cont<9;cont++) 16 printf (" %d ",V[cont]); 17 } Na linha 4 do programa, declaramos uma matriz [3][3] e um vetor [9]. Na linha 10, �zemos a codi�cação para a leitura dos elementos da matriz M[3][3]. Na linha 11, atribuímos o valor de cada elemento da matriz para uma posição do vetor V[9]. Na linha 15 declaramos uma nova estrutura de repetição para percorrer todo do vetor V[9], mostrando os elementos do vetor (linha 16]. A saída para a execução deste programa será a seguinte: Disciplina Algoritmos e Lógica de Programação Figura 5 | Tela do DEV C++ com a saída da execução do programa. Fonte: captura de tela do DEV C++ elaborada pelo autor. Videoaula: Programação com matrizes Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, neste vídeo vamos estudar formas de organização dos dados em uma estrutura baseada em matrizes da matemática. Vamos ver como ela deve ser usada, a sintaxe e a codi�cação destas matrizes, usando a linguagem de programação C. Saiba mais Disciplina Algoritmos e Lógica de Programação Veja os conceitos e dicas para codi�cação de matrizes no site Learn da Microsoft. Aprofunde os seus conhecimentos sobre matrizes aplicadas na matemática e na ciência da computação, no site do Khanacademy. Referências https://learn.microsoft.com/pt-br/cpp/c-language/array-declarations https://pt.khanacademy.org/math/algebra-home/alg-matrices Disciplina Algoritmos e Lógica de Programação FARRER, H. et al. Algoritmos estruturados. Rio de Janeiro: LTC Editora, 1999. MIZRAHI, V. V. Treinamento em linguagem C: módulo 1 e 2. São Paulo: Pearson Prentice Hall, 2007. Aula 3 Introdução à função e recursividade Introdução Disciplina Algoritmos e Lógica de Programação Olá, estudante, hoje vamos para um novo tópico da disciplina de Algoritmos e Lógica de Programação, em que será abordado o recurso de funções na programação de computadores. Vamos ver que podemos criar as nossas próprias funções no programa e podemos usar as funções pré-de�nidas, as quais ajudam, e muito, na organização dos programas. Também vamos estudar um tipo especial de função que permite a codi�cação de recursividade, em que a função é chamada para si mesma. Vamos ver que as funções são soluções elegantes e simples nos programas, mas esta elegância e simplicidade têm um preço que requer muita atenção em sua implementação. Então estudantes, vamos em frente. De�nição e exemplo de Funções Disciplina Algoritmos e Lógica de Programação Caro estudante, quando precisamos resolver um problema na programação e tentamos dividi-lo em subproblemas independentes, resolvendo o problema “em pedaços”, de forma mais simples, podemos usar o recurso chamado de função. A função cria uma forma de encapsulamento da sua lógica interna, expondo como se fosse um serviço, na qual um bloco de comandos será executado, recebendo alguns parâmetros de entrada e retornando um resultado como saída da função. O principal benefício de usar funções na programação é que podemos evitar repetição de linhas de código, pois, se o programador quiser executar uma operação mais de uma vez, ele pode simplesmente escrever a função uma vez e utilizá-la diversas vezes, ao invés de escrever o mesmo código várias vezes. Outro benefício é que se você desejar alterar ou corrigir alguma coisa mais tarde, é mais fácil alterar em um único lugar. Toda função precisa ser invocada para ser executada. Desta forma, quando uma função que já foi usada anteriormente é invocada, o programador não vai mais precisar se preocupar como a lógica deve ser realizada na função e também não vai precisar se preocupar com os testes da função. Funções são codi�cadas independentemente umas das outras e as variáveis usadas dentro de funções não são compartilhadas, ou seja, as variáveis são locais a uma função. As funções se comunicam por meio de parâmetros passados como entrada e os valores retornados como saída, com isto, a comunicação entre as funções é totalmente controlada. A função poderá também chamar a si própria, criando-se uma função recursiva. Este tipo de função torna-se uma implementação elegante e simples, por serem executadas tarefas repetitivas sem utilizar nenhuma estrutura de repetição. Disciplina Algoritmos e Lógica de Programação Para declarar uma função no programa, a seguinte sintaxe deve ser utilizada: <tipo> nome_da_função (<tipo> parâmetro1, <tipo> parâmetro2, ..., <tipo> parâmetroN) { <corpo da função> return valor_de_retorno; } Toda função deve ter um tipo de dados. Esse tipo determina qual será o tipo de seu valor de retorno, podendo ser inteiro, real, caractere, etc. Quando a função não tem um tipo (void), então ela não pode retornar um valor, ou seja, passa a ser um procedimento. Os parâmetros são os valores passados para a função que vão sofrer algum tipo de modi�cação durante a execução dos comandos da função como se fosse uma função matemática, em que o parâmetro é o valor de entrada função. As funções devem ser declaradas antes do programa principal (main). Exemplo de função: 1 #include <stdio.h> 2 int soma(int a, int b) 3 int soma; 4 soma = a + b; 5 return soma; 6 } 7 main() { 8 printf("Soma de 2 numeros: %d",soma(5,10)); 9 } Neste exemplo, foi codi�cada a função soma, que recebe 2 números inteiros como parâmetro de entrada, faz a soma dos 2 números e retorna o resultado; A função soma foi invocada no programa principal. Existem algumas funções na linguagem C que já estão prontas, ou seja, estão codi�cadas e testadas. Elas recebem o nome de funções pré-de�nidas. Pará usá-las, precisamos somente declarar no programa o nome da biblioteca onde está a função. Por exemplo: para calcular a potenciação de um número, podemos usar a função pré-de�nida pow(base, potência), da seguinte forma: 1 #include <stdio.h> 2 #include <math.h> 3 main() {Disciplina Algoritmos e Lógica de Programação 4 printf("Potenciação de 2 elevado a 3: %d",pow(2,3)); 5 } Veja que incluímos a biblioteca <math.h> no programa. Dentro desta biblioteca há a função chamada pow, que calcula a potenciação. No programa principal, invocamos a função pow, passando como parâmetro o valor 2 como base e 3 como potência. O resultado que será mostrado neste programa será 8. Programação de funções e recursividade a linguagem C Disciplina Algoritmos e Lógica de Programação Vamos agora aprofundar nossos conhecimentos de funções pré-de�nidas, dando ênfase às funções matemáticas, devido a sua importância para a área de engenharia. Veja abaixo exemplos de funções pré-de�nidas que estão prontas na biblioteca math.h da linguagem C. Disciplina Algoritmos e Lógica de Programação Tabela 1 | Funções pré-de�nidas da biblioteca math.h. Fonte: elaborada pelo autor. Considerando a existência da função sqrt(numero) para calcular a raiz quadrada de um número, veja como �ca fácil realizar o cálculo resolver a raiz quadrada de 9: 1 #include <stdio.h> 2 #include <math.h> 3 main() { 4 printf("Raiz Quadrada de 9: %d",sqrt(9)); 5 } Temos outras bibliotecas, com outros tipos de funções pré-de�nidas, tais como: 1. <stdio.h> Contém funções para entrada e saída de dados. 2. <time.h> Contém funções para manipular horários e datas. 3. <strings.h> Contém funções para manipulação de strings. 4. <conio.h> Contém funções para manipulação de vídeo. 5. <stdlib.h> Contém funções para conversão de números em texto e vice-versa, locação de memória, números aleatórios, busca e ordenação. �. <ctype.h> Contém funções para classi�car caracteres pelo tipo ou para converter entre caixa alta e baixa independentemente da codi�cação. Por exemplo: já estamos acostumados em usar as funções pré-de�nidas printf() e scanf() da biblioteca <stdio.h>, não sabemos como elas foram escritas, mas sabemos como utilizá-las, ou seja, sabemos o nome das funções e quais informações precisamos fornecer como parâmetros para que a função produza os resultados esperados. Implementação de funções recursivas Vamos ver agora a codi�cação de funções recursivas, em que a função chama a si própria ou chama outras funções que, em algum momento, chama a primeira, tornando-se um processo recursivo. Cada chamada da função recursiva é inserida numa espécie de pilha, sendo o limite de vezes para a sua chamada limitada ao tamanho desta pilha. Se o valor correspondente ao tamanho Disciplina Algoritmos e Lógica de Programação máximo da pilha for atingido, haverá um estouro da pilha ou Stack Over�ow, por este motivo, a sua codi�cação requer muita atenção. Trazendo a recursividade para a nossa realidade, vamos considerar como exemplo a ação contar o valor em dinheiro que temos em um saco de moedas. Cada ato de retirar uma moeda do saco, ver o valor e somá-lo ao valor das moedas já retiradas é um processo recursivo. Este processo de retirar uma moeda, identi�car seu valor e somar com o restante do saco se repete até que o saco esteja vazio, quando atingiremos o ponto de parada e a função retornará o valor zero, indicando que não há mais moedas no saco. Nesse ponto a função contar dinheiro foi chamada um número de vezes igual a quantidade de moedas no saco, e a última chamada começa a devolver os valores de retorno de cada instância da função, iniciando por zero (saco vazio), somado ao valor da última moeda, da penúltima etc., até retornar à primeira chamada referente a primeira moeda, e nesse momento a função inicial se encerra trazendo como valor de retorno a soma dos valores de todas as moedas que estavam no saco. Exemplos práticos de recursividade Estudante, vamos agora aplicar a recursividade nas linguagens de programação, lembrando que, é um recurso de programação que pode ser usado nas linguagens C, C++, Java, Visual Basic, Python, entre outras. Aqui continuaremos usando a linguagem de programação C. As funções recursivas contêm duas partes fundamentais: 1. Ponto de Parada ou Condição de Parada: é o ponto onde a função será encerrada. Disciplina Algoritmos e Lógica de Programação 2. Regra Geral: é o método que reduz a resolução do problema através da invocação recursiva de casos menores, que por sua vez são resolvidos pela resolução de casos ainda menores pela própria função, assim sucessivamente até atingir o “ponto de parada” que �naliza a função. Cada vez que uma função é chamada de forma recursiva, são alojados e armazenados uma cópia dos seus parâmetros, de modo a não perder os valores dos parâmetros das chamadas anteriores. A chamada a uma função recursiva é igual à chamada de uma função não recursiva, na qual é necessário guardar uma “estrutura de invocação”, sendo esta estrutura liberada depois do �m da execução da função e atualização do valor de retorno. Vamos então ver um exemplo de programa com recursividade, onde será criada uma função que faça a soma dos números e �ca chamando a si próprio até que a condição de parada aconteça. Neste exemplo, será somado os números no intervalo de 5 até o número 0. 1 #include <stdio.h> 2 int soma(int x) 3 { 4 int y; 5 if( x == 0 ) 6 return 0; 7 else 8 { 9 y = x + soma(x -1); 10 return y; 11 } 12 } 13 main() 14 { 15 int num; 16 printf("\nA soma de 0 ate 5 = %d ",soma(5)); 17 } Na linha 2 do programa, temos a declaração da função soma. Na linha 9, temos a chamada recursiva da função soma, onde será somado o valor do número, acumulando a soma na variável y. Na linha 5 temos a condição de parada, que é quando o número chega no valor 0, ou seja, está iniciando em 5, que é o parâmetro recebido na função e vai até o valor 0. Na linha 16 temos a chamada da função soma, passando o valor 5 como parâmetro. Os valores que estão sendo somados �carão em uma pilha até a condição de parada. De uma forma ilustrativa, �cará da seguinte forma: Disciplina Algoritmos e Lógica de Programação Figura 1 | Função Recursiva. Fonte: elaborada pelo autor Vamos para um segundo exemplo de recursividade, codi�cando-se agora uma função recursiva para somar a quantidade de dígitos de um número. Será usada na função recursiva, a função pré- de�nida abs(num) para teste da condição de parada e será contado na função recursiva conta, a quantidade de dígitos do número 10.000, sendo este passado como parâmetro para a função recursiva conta. Disciplina Algoritmos e Lógica de Programação 1 #include <math.h> 2 #include <stdio.h> 3 int conta(int x) 4 { 5 int y; 6 if(abs(x) < 10 ) 7 return 1; 8 else 9 y = 1 + conta(x/10); 10 } 11 main() 12 { 13 int num = 10000; 14 printf("Total: %d",conta(num)); 15 } De uma forma ilustrativa, este programa funcionará da seguinte forma: Disciplina Algoritmos e Lógica de Programação Figura 2 | Função recursiva para contar dígitos de um número. Fonte: elaborada pelo autor Disciplina Algoritmos e Lógica de Programação Videoaula: Introdução à função e recursividade Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. A maior motivação que temos para estudar a codi�cação de funções nas linguagens de programações contemporâneas é a redução da complexidade e a melhoria da modularidade dos programas. Então vamos ver neste vídeo, como implementamos estas funções e também exemplos práticos com a sua aplicabilidade. Saiba mais Você poderá criar o seu programa recursivo, usando um site Paiza.io para compilar e executar o programa de forma on-line. Agora faça um teste usando este site, copiando e colando o programa recursivo abaixo, que faz a soma dos números que estão no intervalo de 0 a 5. https://paiza.io/projects/eLk7pkGinhQcwFgf0UDv4g?language=c DisciplinaAlgoritmos e Lógica de Programação #include <stdio.h> int soma(int x) { int y; if( x == 0 ) return 0; else { y = x + soma(x -1); return y; } } int main() { int num; printf("\nA soma de 0 ate 5 = %d ",soma(5)); Referências FARRER, Harry; et al. Algoritmos Estruturados. Rio de Janeiro: LTC Editora, 1999. Disciplina Algoritmos e Lógica de Programação KERNIGHAN, B.W. ;RITCH, D. M. C. A Linguagem de Programação. Rio de Janeiro: Campus, 1986. MIZRAHI, V. V. Treinamento em Linguagem C: Módulo 1 e 2. São Paulo: Pearson Prentice Hall, 2007; ISBN 9788576051350. Aula 4 Registros e arquivos Introdução Olá, estudante, vamos para um novo tópico da disciplina de Algoritmos e Lógica de Programação, em que será abordada a programação de registros e manipulação de arquivos, usando a linguagem de programação C. Vamos ver que o registro é um recurso importante para a organização dos dados utilizados nos programas, pois permite tratar os dados na visão de um conjunto de dados heterogêneos. Vamos ver também como podemos manipular arquivos nos programas em C, gravando e recuperando os conjuntos de dados a serem tratados nos programas. Então, os registros serão tratados como um conjunto de campos e os arquivos como um conjunto de registros. Então, estudantes, vamos em frente. Disciplina Algoritmos e Lógica de Programação De�nição de registros e arquivos Caro estudante, ao manusearmos dados nos programas, muitas vezes, nos deparamos com informações que não são simples de armazenar em variáveis homogêneas, como são os tipos inteiros, reais e caracteres, mas, na verdade, eles são um conjunto de vários dados. Este conjunto de dados passa a ser então composto com várias variáveis do tipo inteiro, real e caractere que, de alguma forma, são interligadas, formando um registro. Segundo Farrer (1999), os registros são um conjunto de dados logicamente relacionados, mas de tipos diferentes, que facilita o agrupamento de variáveis que não são do mesmo tipo e que têm estreita relação lógica entre eles. Por exemplo: vamos de�nir um registro para representar um determinado produto. Figura 1 | Registro Produto. Fonte: elaborada pelo autor. Disciplina Algoritmos e Lógica de Programação Este registro produto está de�nido com as variáveis Codigo, Descricao, Unidade e Preco, sendo que cada variável precisa agora ser associada um determinado tipo de dados, �cando então da seguinte forma: Inteiro Codigo, Caracter Descricao, Caracter Unidade Real Preco Agora vamos atribuir valores para eles: Figura 2 | Registro Produto. Fonte: elaborada pelo autor. Neste exemplo, temos um registro de�nido para o produto de código 0001, sendo ele formado por variáveis de tipos diferentes. Os registros são classi�cados como variáveis compostas heterogêneas, pois permitem agrupar variáveis de tipos diferentes, como mostrado no exemplo acima. Dependendo do volume de registros que deverá ser tratado no programa, não será possível mantê-los em memória, por falta de espaço ou pela necessidade de armazená-lo por um período de tempo longo. A alternativa para isto é armazenar os registros em um arquivo. O arquivo é então um conjunto de registros armazenados em algum dispositivo secundário, como por exemplo, um disco HD. As operações básicas que podem ser feitas neste arquivo, por meio de um programa em C são: obtenção de um registro do arquivo, inserção de um novo registro, modi�cação ou exclusão de um registro. A disposição dos registros no arquivo pode favorecer determinadas operações em detrimento de outras. O conhecimento das possibilidades de organização dos registros nos arquivos permite ao programador escolher aquela que seja mais adequada à solução do seu problema em termos de e�ciência e e�cácia. Existem 2 possibilidades de organização dos arquivos: 1.Sequencial: os registros são inseridos ou consultados no arquivo na ordem sequencial. 2. Direta: o acesso ao registro é feito em ordem aleatória. Os arquivos podem assumir 2 formatos: 1. Texto: armazena caracteres que podem ser mostrados diretamente na tela ou modi�cados por editores de texto simples. Exemplos: lista de dados, código C, texto simples, páginas HTML. Disciplina Algoritmos e Lógica de Programação 2. Binário: arquivo tem uma sequência de bits sujeita às convenções dos programas que o geraram, não sendo legíveis diretamente. Exemplos: arquivos executáveis ou compactados. Os registros, combinados com o seu armazenamento em arquivos, propiciam a gravação dos dados de forma permanente, possibilitando a recuperação destes dados toda vez que se �zer necessário tratá-los nos programas. Programação de registros na linguagem C Vamos agora aprofundar nossos conhecimentos de registros e arquivos, dando ênfase na programação destes recursos na linguagem de programação C. Os registros são declarados como sendo uma estrutura na linguagem C, por meio do comando struct, sendo uma coleção de um ou mais variáveis, possivelmente de tipos diferentes, agrupadas sob um único nome. Exemplo de uma declaração de registro: Disciplina Algoritmos e Lógica de Programação struct data { int dia; int mes; int ano; }; Onde: a palavra-chave struct informa ao compilador que um modelo de estrutura está sendo de�nido; “data” é uma etiqueta que dá nome à de�nição da estrutura; os nomes dia, mes e ano declarados entre as chaves são as variáveis da estrutura; uma de�nição de estrutura é um comando, por isso deve terminar com ponto-e-vírgula. As variáveis de uma mesma estrutura devem ter nomes diferentes, porém, estruturas diferentes podem conter campos com o mesmo nome. A de�nição de uma estrutura não reserva qualquer espaço na memória. No exemplo dado, nenhuma variável foi declarada de fato, apenas a forma dos dados foi de�nida. Essa de�nição, porém, cria um tipo de dados, que pode ser usado para declarar variáveis. Temos 2 formas de declarar uma variável x como sendo do tipo data: struct data { int dia; int mes; int ano; }; ... data x; Nesta forma, usamos o comando struct para de�nir a estrutura como novo tipo de dados e um segundo comando para declarar a variável x associada ao tipo de dados data. struct data { int dia; int mes; int ano; } x; Disciplina Algoritmos e Lógica de Programação Nesta forma, de�nimos a estrutura e declaramos a variável x do novo tipo de�nido em um único comando. Os campos de uma estrutura podem ser de qualquer tipo, inclusive uma estrutura previamente de�nida e a declaração do formato de uma estrutura pode ser feita dentro da função principal (main) ou fora dela. Vamos agora estudar um programa em C em que declaramos uma estrutura Reg_Produto, com variáveis de tipos diferentes, que representam um registro para um produto, conforme mostrado anteriormente, nas Figuras 1 e 2 deste material. 1 #include <stdio.h> 2 main () 3 { 4 struct Reg_Produto { 5 char codigo[10]; 6 char descricao[30]; 7 char unidade[5]; 8 float preco; 9 }; 10 Reg_Produto Prod; 11 printf("Digite o codigo:"); 12 scanf("%s", &Prod.codigo); 13 printf("Digite a descricao:"); 14 scanf("%s",&Prod.descricao); 15 printf("Digite a unidade:"); 16 scanf("%s", &Prod.unidade); 17 printf("Digite o preco:"); 18 scanf("%.2f",&Prod.preco); 19 } Na linha 4 deste programa, declaramos a estrutura que chamamos de Reg_Produto, contendo as variáveis código, descrição, unidade e preco, declaradas nas linhas 5, 6, 7 e 8. Na linha 10, declaramos a variável Prod, como sendo do tipo da estrutura Reg_Produto, com isto, teremos dentro da variável Prod, os campos codigo, descricao, unidade e preco. Na linha 12, estamos lendo um valor do teclado e inserindo este valor na variável código que está dentro da variável Prod. Veja então que este comando de leitura tem o nome da variável associada à estrutura e depois o nomeda variável código, separados por um ponto (.). Esta é a forma de acessar individualmente os campos de uma determinada estrutura como se fossem variáveis comuns. Disciplina Algoritmos e Lógica de Programação Nas linhas 14, 16 e 18, estamos lendo os valores para as variáveis Prod.descricao, Prod.unidade e Prod.preco. Programação de arquivos na linguagem C Agora vamos complementar os nossos estudos com a codi�cação para manipular os arquivos na linguagem de programação C. Para tratar arquivos, a linguagem C fornece um nível de abstração entre o programa e o dispositivo a ser usado. Esta abstração é chamada �la de bytes e o dispositivo normalmente é o arquivo. A biblioteca <stdio.h> tem um identi�cador FILE, que é uma estrutura que de�ne vários aspectos do arquivo, como nome, status, posição corrente no arquivo, além de ter uma �la associada. Para manipular o arquivo será necessário então criar no programa este ponteiro, associado a esta estrutura FILE. Exemplo: FILE *arq; Onde arq será o ponteiro para um arquivo. É usando este tipo de ponteiro que vamos poder manipular os arquivos na linguagem C. Abertura de arquivos Toda vez que for necessário trabalhar com arquivo, primeiramente precisamos ABRIR o arquivo. Abrir o arquivo signi�ca alocar o periférico em que o arquivo se encontra e deixá-lo disponível para leitura/gravação. Exemplo: arq = fopen(nome_arquivo, “modo”); Disciplina Algoritmos e Lógica de Programação Onde arq é o ponteiro para o arquivo e modo é a forma como arquivo será acessado, podendo ser das seguintes formas: w: para escrita (cria novo arquivo ou sobrepõe se arquivo já existir); r: para leitura (arquivo deve existir); a: para escrita no �nal do arquivo, e se não existir cria novo arquivo; w+: para leitura e gravação (cria novo arquivo ou sobrepõe se já existir); r+: para leitura e gravação (arquivo deve existir); a+: para leitura ou escrita no �m do arquivo, e se não existir cria novo arquivo; b: modo binário; t: modo texto. Fechamento de arquivos Da mesma maneira que precisamos abrir um arquivo antes do processamento, também se faz necessário o fechamento dele, para que suas informações não possam ser violadas ou dani�cadas. Fechar um arquivo signi�ca liberar o periférico que estava sendo utilizado. Exemplo: fclose(arq); Onde arq é o ponteiro para o arquivo. Leitura de arquivos Após abrir um arquivo é necessário LER os dados que estão em disco e transferi-los para memória. Essa transferência é feita por registro. Esse procedimento é gerenciado pelo próprio sistema operacional. Exemplo: fscanf (arq, "%s", string); Onde arq é o ponteiro para o arquivo e string é a variável que receberá a linha apontada pelo ponteiro dentro do arquivo. Gravação de arquivos Da mesma maneira que os registros são lidos de um arquivo, também devemos gravar registros em um arquivo. A gravação consiste na transferência de um registro da memória, para um periférico. Exemplo: fprintf (arq, "%s", string); Toda vez que abrimos um arquivo ele posiciona o ponteiro no primeiro registro, ou seja, no início do arquivo. Para que possamos trabalhar com os dados se torna necessário saber onde está o ponteiro do registro. Isso poderemos fazer testando se o ponteiro está no início (BOF – Bottom Of File) ou no �nal do arquivo (EOF – End Of File). Esse é sempre executado após a leitura do registro (mudança da posição do ponteiro). Simbolicamente podemos representar esse passo da seguinte maneira: Disciplina Algoritmos e Lógica de Programação Figura 3 | Representação dos registros em arquivos. Fonte: elaborada pelo autor. Movimentação de registros Quando um arquivo é aberto, o ponteiro está apontando para o primeiro registro do arquivo. A cada leitura do arquivo o ponteiro se movimenta para o próximo registro e assim por diante. Exemplo de trecho do programa para fazer esta movimentação no arquivo: 1 while (feof(arq)==0) { 2 fscanf(arq, "%s", string); 3 printf("%s %d\n",string,num); 4 } Este trecho do programa está lendo todos os registros de um arquivo, em que a função feof(arq) retorna 1 quando o ponteiro arq está apontando para o último registro do arquivo, senão retorna 0. Agora vamos analisar um programa que abre o arquivo exemplo.txt, lê e exibe em tela todos os registros deste arquivo. 1 #include <stdio.h> 2 #include <stdlib.h> 3 main () 4 { 5 FILE *arq; 6 char texto[256]; 7 arq =fopen ("exemplo.txt","rt"); 8 if (arq == NULL) 9 { 10 printf ("Erro na abertura do arquivo. Fim de programa."); 11 exit (1) Disciplina Algoritmos e Lógica de Programação 12 } 13 fscanf(arq,"%s", texto); /* Lê a primeira linha */ 14 while(!feof(arq)) 15 { 16 printf(" %s",texto); /* Exibe a linha na tela */ 17 fscanf(arq,"%s", texto); /* Lê a "próxima" linha */ 18 } 19 fclose(arq); 20 } Na linha 5 deste programa, está sendo criado um ponteiro chamado *arq que é usado para navegar no arquivo exemplo.txt, que está sendo aberto na linha 7 deste programa. Na linha 13 do programa, está sendo lida a 1ª linha do arquivo. Na linha 14 tem-se uma estrutura de repetição, em que é testado se o ponteiro do arquivo *arq chegou na última linha do arquivo. Enquanto a condição for verdadeira, ou seja, não chegou na última linha, o programa mostra a linha e lê a próxima linha. Videoaula: Registros e arquivos Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Olá, estudante, neste vídeo vamos ver como tratamos a gravação e leitura de dados em arquivos, manipulando estes arquivos na linguagem de programação C. Vamos ver que este recurso de programação vai nos ajudar a salvar os dados que precisamos usar nos programas, de forma permanente, em arquivos txt, fazendo com que a lógica dos nossos programas se aprimore cada vez mais Saiba mais Disciplina Algoritmos e Lógica de Programação Crie o seu programa de registros e arquivos, usando o site Paiza.io em que você poderá codi�car, compilar e rodar deforma on-line. Referências https://paiza.io/projects/eLk7pkGinhQcwFgf0UDv4g?language=c Disciplina Algoritmos e Lógica de Programação FARRER, H. et al. Algoritmos estruturados. Rio de Janeiro: LTC Editora, 1999. KERNIGHAN, B. W.; RITCH, D. M. C: A linguagem de programação, Rio de Janeiro: Campus, 1986. MIZRAHI, V. V. Treinamento em linguagem C: módulo 1 e 2. São Paulo: Pearson Prentice Hall, 2007. Aula 5 Revisão da unidade Estruturas para os dados Disciplina Algoritmos e Lógica de Programação Nesta unidade, estudamos formas de manusear dados por meio de estruturas que permitem a manipulação de conjuntos de dados de mesmo tipo primitivo (inteiro, real, caractere) e tipos primitivos diferentes. Estas estruturas propiciam a solução de algoritmos com lógicas complexas, enriquecendo a implementação com recursos computacionais que facilitam a manipulação de dados com maior qualidade e performance. Vimos que temos os seguintes tipos de dados básicos: numéricos (inteiros e reais), lógicos e caracteres e, baseando-se nestes tipos básicos podemos construir os tipos compostos de dados, que são divididos em homogêneos (vetores e matrizes) e heterogêneos (registros). Os tipos homogêneos são conjuntos do mesmo tipo primitivo de dados, os quais podem ter uma única dimensão (vetor), na qual os dados de estrutura são inseridos em uma única linha, ou ter mais de uma dimensão (matriz), em que os dados são inseridos em mais de uma linha. O tipo heterogêneo (registro) é formado por um conjunto de dados de tipos diferentes, que são logicamente organizados. Este tipo facilita o agrupamento de variáveis que têm uma estreita relação lógica entre eles. Estes registros podem ser armazenados em arquivos esalvos em um dispositivo secundário, como o disco HD. O conhecimento das possibilidades de organização dos registros em arquivos permite ao programador escolher a forma mais adequada para solucionar problemas em termos de e�ciência e e�cácia. Disciplina Algoritmos e Lógica de Programação Foi apresentada também nesta unidade uma forma de resolver problemas na programação por meio da divisão em subproblemas independentes, de forma simples e elegante, usando o recurso de função, que cria um encapsulamento de uma lógica interna, expondo como se fosse um serviço, no qual um bloco de comandos é executado, recebendo alguns parâmetros de entrada e retornando um resultado como saída da função. Vimos que usar funções na programação evita repetição de linhas de código, no qual codi�camos os comandos de uma função uma única vez e podemos utilizá-lo diversas vezes, ao invés de escrever o mesmo código várias vezes. Um ponto importante no uso de funções é que elas podem ser usadas de forma recursiva, ou seja, a função chama a si mesma. Vimos também que podemos usar funções pré-de�nidas, que são organizadas em bibliotecas codi�cadas especi�camente para cada linguagem de programação, como por exemplo: biblioteca para funções matemáticas e biblioteca com funções para manipulação de caracteres (strings). Videoaula: Revisão da unidade Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. Resolver problemas com certa complexidade na programação requer conhecimentos de estrutura de dados. Estas estruturas permitem a codi�cação de programas com recursos que facilitam a manipulação de dados de forma massiva, com uma lógica e�ciente e que traz qualidade e performance nos programas. Este vídeo apresenta um resumo dos conceitos e da aplicabilidade destas estruturas de dados formadas pelos vetores, matrizes e registros, bem como a implementação de funções e recursividade para as funções. Estudo de caso Disciplina Algoritmos e Lógica de Programação Para contextualizar sua aprendizagem desta unidade, imagine que você trabalha para uma empresa de construção civil e você será o engenheiro responsável pelo orçamento da construção de um prédio. Você será responsável pela gestão dos custos da obra, deverá fazer o controle dos gastos com os materiais básicos, equipamentos, mão de obra operacional e de terceiros prestados e considerar um memorial descritivo de obra, que traz os detalhes de tudo o que foi executado. A obra será executada em várias etapas e os gastos da construção serão atualizados na medida que cada apartamento for �nalizado. Você deverá considerar que os custos são variáveis para cada apartamento, devido a fatores como o tempo da construção, a variação dos preços dos materiais e da mão de obra. O prédio terá 6 andares e cada andar terá 4 apartamentos, conforme representado na �gura abaixo. Disciplina Algoritmos e Lógica de Programação Figura 1 | Exemplo hipotético para estudo de caso. Fonte: elaborada pelo autor. Veja que a melhor lógica para o desenvolvimento deste controle de custos é considerar o uso de uma matriz. Nesta matriz, deve ser considerado cada andar como uma linha e cada tipo de apartamento como uma coluna da matriz. Como temos o andar térreo e mais 6 andares no prédio, a matriz correspondente terá 7 linhas e como temos 4 tipos de apartamentos em cada andar, teremos 4 colunas. Para o registro dos gastos de cada apartamento, a melhor alternativa, considerando os recursos estudados nesta unidade, é implementar a declaração de um registro (comando struct da linguagem C), que deverá manipular as variáveis que serão tratadas para cada apartamento: número do apartamento, custo dos materiais básicos, custo dos equipamentos, custo da mão de obra e o memorial descritivo. Veja que você terá que construir um programa em C para ler estas variáveis, que serão informadas no �nal da construção de cada apartamento. Como serão informados os dados na �nalização de cada apartamento, deverá sempre ser informado o andar e o tipo do apartamento para depois informar os valores das variáveis tratadas no programa. Após a inclusão dos valores, vamos somar e mostrar o valor total gasto no apartamento. _______ Re�ita Para desenvolver o programa solicitado, você poderá usar os recursos de matrizes e de registros, da programação estruturada. O uso destes recursos no programa propiciará uma melhor organização no tratamento e manipulação dos dados, para fazer a gestão dos custos da obra e na qualidade do código do Disciplina Algoritmos e Lógica de Programação programa em função de se ter um grande conjunto de variáveis a serem tratadas pelo programa. Veja como o registro se encaixa perfeitamente na solução deste caso de uso, pelo motivo de estarmos tratando um conjunto de dados que estão logicamente relacionados, de tipos diferentes e que podemos tratá-los como um agrupamento de variáveis que têm uma estreita relação lógica entre si Videoaula: Resolução do estudo de caso Este conteúdo é um vídeo! Para assistir este conteúdo é necessário que você acesse o AVA pelo computador ou pelo aplicativo. Você pode baixar os vídeos direto no aplicativo para assistir mesmo sem conexão à internet. 1 #include <stdio.h> 2 #include <string.h> 3 main () 4 { 5 struct CustosObra { 6 int nro_apto; 7 float materiais_basicos; 8 float equipamentos; 9 float mao_obra; 10 char memorial[200]; 11 }; 12 13 CustosObra Vcusto[7][4]; 14 int andar, tipo; 15 float custo_total; 16 printf ("Digite o andar (de 0 a 6):"); 17 scanf("%d",&andar); 18 printf ("Digite o tipo do apartamento (de 0 a 3):"); 19 scanf("%d",&tipo); 20 printf ("Digite o numero do apartamento:"); 21 scanf("%d",&Vcusto[andar][tipo].nro_apto); Disciplina Algoritmos e Lógica de Programação 22 printf ("Digite o custo com materiais basicos:"); 23 scanf("%f",&Vcusto[andar][tipo].materiais_basicos); 24 printf ("Digite o custo com equipamentos:"); 25 scanf("%f",&Vcusto[andar][tipo].equipamentos); 26 printf ("Digite o custo com mao de obra:"); 27 scanf("%f",&Vcusto[andar][tipo].mao_obra); 28 printf ("Digite o memorial descritivo:"); 29 scanf("%s",&Vcusto[andar][tipo].memorial); 30 custo_total = Vcusto[andar][tipo].materiais_basicos + Vcusto[andar][tipo].equipamentos + Vcusto[andar][tipo].mao_obra; 31 printf ("\nValor total gasto no apartamento: %.2f",custo_total); 32 } Na linha 5 deste programa, declaramos a estrutura que chamamos de CustosObra, contendo as variáveis nro_apto, materiais_basicos, equipamentos, mao_obra e memorial. Na linha 13, declaramos o vetor Vcusto, como sendo do tipo de dados da estrutura CustosObra, com isto, teremos dentro de cada elemento deste vetor de 7 linhas e 4 colunas, os campos nro_apto, materiais_basicos, equipamentos, mao_obra e memorial. Na linha 17 e 19, estamos lendo os valores que de�nirão o andar e o apartamento em que serão inseridos os valores referentes aos custos a serem lançados. Da linha 20 a 29 do programa, está sendo solicitada a entrada dos valores da obra. Veja que estes comandos de leitura têm o nome da variável associada à estrutura e depois o nome da variável código separados por um ponto (.). Esta é a forma de acessar individualmente os campos de uma determinada estrutura como se fossem variáveis comuns. Nas linhas 30 está sendo calculado o custo total do apartamento e na linha 31 está sendo mostrado este valor. Olá, estudante! Clique aqui e acesse o roteiro de aula prática da U1, aula 1. Clique aqui e acesse o roteiro de aula prática da U2, aula 4. Clique aqui e acesse o roteiro de aula prática da U3, aula 2. Clique aqui e acesse o roteiro de aula prática da U4, aula 2. Resumo visual https://cm-kls-content.s3.amazonaws.com/AMPLI/RAP/ALGORITMOS_E_LOGICA_DE_PROGRAMACAO/RAP_U1.1.pdfhttps://cm-kls-content.s3.amazonaws.com/AMPLI/RAP/ALGORITMOS_E_LOGICA_DE_PROGRAMACAO/RAP_U2.4.pdf https://cm-kls-content.s3.amazonaws.com/AMPLI/RAP/ALGORITMOS_E_LOGICA_DE_PROGRAMACAO/RAP_U3.2.pdf https://cm-kls-content.s3.amazonaws.com/AMPLI/RAP/ALGORITMOS_E_LOGICA_DE_PROGRAMACAO/RAP_U4.2.pdf Disciplina Algoritmos e Lógica de Programação Disciplina Algoritmos e Lógica de Programação Referências Disciplina Algoritmos e Lógica de Programação FARRER, H. et al. Algoritmos estruturados. Rio de Janeiro: LTC Editora, 1999. KERNIGHAN, B. W. e RITCH, D. M.. C: A Linguagem de programação. Rio de Janeiro: Campus, 1986. MIZRAHI, V. V. Treinamento em linguagem C: módulo 1 e 2. São Paulo: Pearson Prentice Hall, 2007.