Baixe o app para aproveitar ainda mais
Prévia do material em texto
Algoritmos Prof. Hilton Cardoso Marins Junior. IF Sudeste MG - Campus Juiz de Fora Núcleo de Informática 2014 Algoritmos Prof. Hilton Cardoso Marins Junior Página 2 de 45 1. Introdução Para termos sucesso em nosso curso será necessário entender alguns termos relacionados à programação de computadores. O primeiro termo a ser abordado será Processamento de dados. Você já deve ter uma ideia do que venha a ser processamento de dados. Processamento, isoladamente, indica transformação, a obtenção de um resultado a partir da transformação de algo fornecido inicialmente. Pode-se falar em processamento de laranja em suco, de sucata em placas metálicas, dentre outros. Estamos interessados somente no processamento de dados, ou seja, na transformação de dados. Para que o processamento de dados ocorra é necessário haver dados de entrada e a transformação destes em outros dados, chamados de dados de saída ou resultado. Processar dados é produzir novas informações através de dados iniciais. Em nosso curso iremos nos concentrar especificamente em processamento de dados automático. Para que o processamento de dados seja classificado como automático, não deve haver interferência do homem durante o processamento. Mas como processar dados sem a interferência humana? Existe alguma máquina capaz de realizar isso? Sim, existe e essa máquina é o computador. O computador realiza o processamento de dados automático e isso só é possível porque ele consegue executar as instruções que lhe são dadas. O computador é uma máquina capaz de processar dados de forma automática através de instruções que lhe são fornecidas. Podemos utilizar o computador para realizar uma tarefa, desde que ele seja instruído de forma adequada. Agora surge uma nova questão: como instruir o computador a executar uma tarefa para resolver um determinado problema? Para resolver um problema através do computador é necessário encontrar em primeiro lugar uma maneira de descrevê-lo de uma forma clara e precisa. Se você não consegue descrever a solução de um problema não conseguirá instruir o computador a resolvê-lo. Devemos encontrar uma sequência de passos que conduzam à solução. Chamamos esta sequência de passos de algoritmo. Algoritmo é a descrição de uma sequência de ações para realizar alguma tarefa. São exemplos de algoritmos: receita de um bolo, manual de montagem de um móvel, instruções de como chegar a um determinado local, dentre outros. Em nossos estudos só nos interessa os algoritmos computacionais, que descrevem sequência de ações que podem ser implementadas no computador. Tais algoritmos devem passar por um processo de adequação para que o computador possa executá-los. Um algoritmo em um formato adequado para execução pelo computador é chamado de programa. Entrada de Dados Saída de Dados Processament o de Dados Processamento de Dados Algoritmos Prof. Hilton Cardoso Marins Junior Página 3 de 45 Um programa de computador, nada mais é do que um algoritmo em determinado formato que o computador consegue executá-lo. A elaboração de um programa consiste na codificação precisa de um algoritmo, segundo uma linguagem de programação específica. Uma linguagem de programação é uma forma de padronizar a comunicação de instruções para um computador. Assim como há muitos idiomas, há muitas linguagens de programação (C, Java, PHP, etc). Mas como o computador entenderá as instruções escritas em uma determinada linguagem de programação? Os circuitos eletrônicos de cada computador podem reconhecer um conjunto limitado de instruções primitivas. Estas instruções formam uma linguagem que torna possível às pessoas se comunicarem com o computador. Tal linguagem é denominada linguagem de máquina. Programar em linguagem de máquina é difícil e tedioso. Infelizmente, todos os programas, para serem executados pelo computador, devem ser escritos em linguagem de máquina. Para resolver este problema, criamos programas utilizando o conjunto de instruções disponibilizadas pela linguagem de programação escolhida. Isso é bem mais conveniente para as pessoas do que usar o conjunto de instruções em linguagem de máquina. Criar programas utilizando instruções de uma linguagem de programação é conveniente apenas para nós e não para o computador, visto que este só conseguirá executar um programa em linguagem de máquina. Uma vez escrito o programa em C (por exemplo), o mesmo precisa ser traduzido para a linguagem do computador para ser executado. Um dos métodos de tradução de um programa escrito em uma linguagem de programação para o correspondente em linguagem de máquina chama-se compilação. O arquivo gerado, resultante do processo de compilação, é conhecido como programa objeto. O Compilador é um programa que converte o programa fonte, escrito em uma linguagem de alto nível, em programa objeto escrito em linguagem de máquina. Cada linguagem de programação possui seu próprio compilador. É muito comum que um programa faça referência a instruções localizadas em outro programa. Dizemos que um programa “chama” ou invoca outro programa. Devido a este fato, um programa objeto não é executável. Precisamos unir todos os programas objetos de todos os programas fontes em um único programa, este sim é chamado de programa executável e como o próprio nome indica, pode ser executado pelo computador. Este processo de conexão de um programa objeto, com outro programa objeto denomina-se ligação. Um linkeditor/ligador é um programa que reúne módulos compilados e arquivos (de dados ou de bibliotecas) para criar um programa executável. Bibliotecas são arquivos que disponibilizam determinadas funcionalidades aos programas. Geralmente as bibliotecas agrupam funções específicas, tais como para entrada e saída de dados, matemáticas e diversas outras. As bibliotecas disponibilizam funcionalidades que não fazem parte diretamente do problema a resolver, elas apenas prestam um serviço auxiliar. Para ilustrar o conceito de bibliotecas no desenvolvimento de programas, imagine a situação em que você precisa desenvolver um programa para calcular a medida de uma escada para a situação abaixo. Algoritmos Prof. Hilton Cardoso Marins Junior Página 4 de 45 Sabendo que ࢙ࢋ ࢻ = ࢋࢊࢊࢇ ࢇ࢘ࢋࢊࢋ ࢋࢊࢊࢇ ࢋ࢙ࢉࢇࢊࢇ então ࢋࢊࢊࢇ ࢋ࢙ࢉࢇࢊࢇ = ࢋࢊࢊࢇ ࢇ࢘ࢋࢊࢋ ࢙ࢋ ࢻ Você percebeu que o nosso problema é calcular a medida da escada, entretanto será necessário o cálculo do Sen α, que não é o cálculo principal, mas importante para a solução do problema inicial. Precisamos de uma função, localizada em uma biblioteca, para calcular o seno do ângulo. A vantagem do uso de bibliotecas é não nos preocuparmos com as funcionalidades que não estão diretamente relacionadas à solução do problema. No caso acima, o cálculo do seno pode ser realizado por alguma função de uma determinada biblioteca. A implementação da função que realiza o cálculo do seno fica na biblioteca e não no nosso programa. Ao realizar a link-edição todos os programas fontes serão ligados às bibliotecas, gerando finalmente o programa executável. A figura abaixo ilustra os conceitos relacionados às etapas necessárias para a geração de um programa executável. α chão parede escada α Algoritmos Prof. Hilton Cardoso Marins Junior Página 5 de 45 Criação de um programa executável na linguagem C Uma vez que o arquivo executável tenha sido gerado, o programa está pronto para ser executado. Depois que o programa executável é carregado na memória, a CPU executa o programa instrução por instrução. Existe outro método de tradução para linguagem de máquina.Pelo método de interpretação, cada comando do código fonte é lido pelo interpretador, é convertido em código executável e imediatamente executado, antes que o comando seguinte seja lido. Prática 1: Conhecendo o ambiente de programação sim sim não não INÍCIO Programa fonte em C *.c Compilador Programa Objeto *.o Erro ? LinkEditor Erro ? Programa Excutável FIM Bibliotecas Algoritmos Prof. Hilton Cardoso Marins Junior Página 6 de 45 2. Tipos de dados primitivos Sabemos que um programa é constituído de um conjunto de instruções que manipulam dados e tem como objetivo solucionar um problema através do computador. Os dados são os valores que serão utilizados na solução do problema. Esses valores podem ser fornecidos por algum dispositivo de entrada (teclado, mouse, disco rígido, dentre outros) ou originados de algum cálculo. Para que um programa possa processar os dados fornecidos como entrada ou aqueles resultantes de algum cálculo, tais dados devem estar armazenados na memória. E como fazemos isso? A solução está no uso de variáveis de memória. Variáveis de memória são locais na memória do computador que possuem a capacidade de armazenar os valores a serem processados por um programa. Os valores são armazenados na memória em “compartimentos” identificados por um endereço único. O conteúdo armazenado nesses endereços pode variar, entretanto armazenará um valor de cada vez, ou seja, se colocarmos um segundo valor em uma variável de memória o valor anterior é perdido. Para facilitar a referência a um endereço de memória, as linguagens de programação permitem nomear cada endereço utilizado em um programa. Ao implementar programas devemos declarar os dados manipulados por este programa. Esta declaração corresponde a rotular um local de memória com um nome e determinar o tipo de valores que este local pode armazenar e por consequência as operações que pode efetuar. A este local chamamos de variável de memória. Uma variável é composta por dois elementos básicos: o valor da variável e seu identificador. O identificador da variável é o seu nome (rótulo) e é através dele que será possível fazer referência à variável dentro do programa. Ao implementar um programa devemos solicitar a alocação de espaço na memória para todas as variáveis que serão utilizadas. Essa ação é chamada de declaração de variável. As operações a serem realizadas com estas variáveis devem levar em conta seus respectivos tipos. A liberação deste espaço da memória alocado só irá acontecer quando o programa finalizado. Exemplo de declaração de variáveis int telefone; 1 double salario; 2 float taxa = 0.5; 3 char turma = ‘A’ 4 Linha Comentário 1 Foi alocado um espaço na memória para armazenar valores inteiros e este local foi rotulado de telefone. Dentro do nosso programa, se desejarmos manipular o valor que está armazenado neste endereço de memória, utilizaremos o identificador da variável, que nesse caso é telefone. 2 Foi alocado um espaço na memória para armazenar valores reais e este local foi rotulado de salário. 3 Foi alocado um espaço na memória para armazenar valores reais e este local foi rotulado de taxa. Simultaneamente à declaração da variável foi dado um valor inicial de 0.5. Opcionalmente o programador pode, ao declarar uma variável, iniciá- la com um valor desejado. Algoritmos Prof. Hilton Cardoso Marins Junior Página 7 de 45 4 Foi alocado um espaço na memória para armazenar caractere (letra, algarismo e símbolo). E este local foi rotulado de turma. Simultaneamente à declaração da variável foi atribuído o caractere ‘A’. Para que o compilador entenda o A como um caractere e não como o nome de outra variável, por exemplo, devemos delimitar com aspas simples. Chamamos de tipos de dados primitivos aqueles tipos de dados pré-definidos na linguagem de programação. Os tipos de dados vistos acima são exemplo de tipos de dados primitivos da linguagem C. Você percebeu no exemplo acima o uso de dois tipos primitivos reais, o double e o float. A diferença fica por conta da capacidade e precisão dos valores armazenados. Algoritmos Prof. Hilton Cardoso Marins Junior Página 8 de 45 3. Operadores Em nosso curso criaremos programas que realizarão operações com as variáveis. Precisamos conhecer alguns operadores da Linguagem C. Operadores Aritméticos Comentário * Multiplicação / Divisão % Módulo ou resto da divisão + Adição - Subtração Operadores Relacionais Comentário > Maior >= Maior ou igual < Menor <= Menor ou igual == Igualdade != Diferente Operadores Lógicos Comentário && E || OU Obs.: Os operadores lógicos são usados para concatenar expressões que estabelecem uma relação entre valores. Condição A Condição B A ou B (A ||B) V V V V F V F V V F F F A expressão toda será verdadeira se e somente se, pelo menos, uma das condições for verdadeira. Proposição A Proposição B A e B (A && B) V V V V F F F V F F F F A expressão toda será verdadeira se e somente se todas as condições forem verdadeiras. Algoritmos Prof. Hilton Cardoso Marins Junior Página 9 de 45 E por fim temos o operador de atribuição. Como próprio nome diz, tem a função de atribuir valores às variáveis. Exemplo do uso do operador de atribuição salario = 3600.80; 1 faltas = 5; 2 nome = “José da Silva”; 3 turma = 'A'; 4 faltas = faltas + 1; 5 Linha Comentário 1 Atenção para o separador de decimal (.) 3,4 Na linguagem C toda cadeia de caracteres (string) deve ser delimitada por aspas duplas e todo caractere deve ser delimitado por aspas simples. 5 O símbolo de atribuição (=) não tem o mesmo significado que o usual da matemática que representa a igualdade de valores. Em C, representa a atribuição do valor ou expressão localizada à direita do operador de atribuição à variável localizada à esquerda do operador de atribuição. No caso desta linha, não se lê que faltas é igual a faltas + 1. Diz-se que o valor da variável faltas acrescido de 1 unidade será atribuído à própria variável faltas, neste caso a variável faltas passará a ter o valor 6. Algoritmos Prof. Hilton Cardoso Marins Junior Página 10 de 45 4. Conceitos Iniciais em C Estamos perto de criar programas mais interessantes do que o alomundo.c. Para nos preparar continuaremos a apresentação de alguns conceitos básicos da linguagem C. Começaremos com o conceito de função. Uma função é um trecho de código já pronto que pode ser utilizado dentro do seu programa. Para usar uma função pronta, basta escrever o nome dela no seu código. Dizemos que estamos chamando (ou invocando) a função. Como estas funções não estão implementadas em nosso código e sim em outros programas (bibliotecas), precisamos avisar ao compilador C o nome desta biblioteca. Bibliotecas são conjuntos de funções prontas. O comando em C para incluir bibliotecas em um programa é: O conceito de função é muito importante e no futuro aprenderemos a criar nossas próprias funções. Por enquanto, invocaremos funções já prontas e disponibilizadas nas bibliotecas da linguagem C. Outro aspecto importante relacionado à função é o fato de que toda aplicação precisa ter um ponto de partida, a partir do qual ela será iniciada. Imagina uma aplicação com centenas de programas. Quando esta aplicação for executada, começará por onde? No caso da linguagem C, o programa começa pela função principal, chamada main. A forma de escrevê-la é a seguinte: Formato simplificado de um programa em C #include <stdio.h> 1 2 main ( ) { 3 . . . 4 . . . 5 . . . 6 } 7 8 Linha Comentário 1 Indicaa biblioteca necessária para a criação do executável. Provavelmente neste programa há uma chamada de uma função implementada na biblioteca stdio.h 3 Nome da função principal de um programa em C. A chave { indica início da função. 4 a 6 Corpo da função. 7 A chave } indica fim da função. #include <nome da biblioteca> Algoritmos Prof. Hilton Cardoso Marins Junior Página 11 de 45 Bibliotecas e funções O nosso objetivo agora é compreendermos melhor o papel das bibliotecas no desenvolvimento de programas e como uma função é chamada (invocada). Analise o código abaixo. Programa raiz.c #include <stdio.h> 1 #include <math.h> 2 3 main(){ 4 double x = 9; 5 printf(“Raiz Quadrada de %f: %f“, x, sqrt(x)); 6 }7 Linha Comentário 1 A biblioteca stdio.h foi declarada devido a presença da função printf. A biblioteca stdio.h (standard input output) reúne funções padrões para entrada e saída de dados , incluindo a função printf. 2 A biblioteca math.h reúne diversas funções matemáticas, incluindo a sqrt. 6 Há uma referência a função (sqrt) que calcula a raiz quadrada de um número. Invocamos a função sqrt, que é responsável pelo cálculo, passando a variável x, cujo valor é 9. Neste momento o fluxo de execução é desviado para função sqrt localizada na biblioteca math.h. O cálculo é feito e o resultado (3) é devolvido e o fluxo de execução retorna para o nosso programa. Finalmente o resultado devolvido é impresso na tela pela função printf. Reparem que as implementações das funções printf e sqrt não constam no nosso código fonte. As implementações estão nas respectivas bibliotecas. Lembre-se de que quando solicitar a criação do executável, tudo será ligado em um único programa executável. Execute o programa e verifique se está tudo funcionando corretamente. ** Biblioteca math ** Aqui está a Implementação da função sqrt Algoritmos Prof. Hilton Cardoso Marins Junior Página 12 de 45 5. Saída de Dados Vamos nos dedicar agora a uma instrução muito simples, mas de grande importância em um programa. Trata-se da visualização dos resultados do processamento realizado. Este procedimento é conhecido como saída de dados. Os dados de saída podem ser apresentados em qualquer dispositivo de saída ligado ao computador (vídeo, impressora, discos, dentre outros). Em nosso curso utilizaremos o vídeo como dispositivo padrão para saída de dados. Na linguagem C a função responsável por esta tarefa é a printf. Segue abaixo sua sintaxe. Exemplos com a função printf int idade = 15; 1 char nome[40] = “Jose da Silva”; 2 char turma = 'A'; 3 float media = 8.5; 4 5 printf(“\nA idade é %d”, idade); 6 printf(“\nA idade do %s é %d”, nome, idade); 7 printf(“\nA média da Turma %c foi de %f”, turma, media);8 O primeiro argumento da função printf é chamado de string de controle. Contém caracteres a serem impressos e códigos de formatação (%). O código de formatação é seguido de uma letra conforme abaixo. Caractere de Formatação Comentário %c Caractere simples %d Decimal %f Ponto flutuante %s Cadeia de caracteres (string) %u Decimal sem sinal %e Notação científica Apresentamos no exemplo acima dois códigos de formatação. Código de Formatação Comentário /n Força a mudança de linha do cursor. /t Força o avanço de tabulação do cursor. printf(“string de controle”, lista de variáveis) Algoritmos Prof. Hilton Cardoso Marins Junior Página 13 de 45 O segundo argumento apresenta o valor a ser exibido. Deve haver tantos argumentos após a string de controle quantos forem os códigos de formatação. Vejamos o efeito das instruções do exemplo acima. Instrução da Linha Efeito na Tela 6 A idade é 15 7 A idade do Jose da Silva é 15 8 A média da Turma A foi de 8.5 Algoritmos Prof. Hilton Cardoso Marins Junior Página 14 de 45 6. Entrada de Dados Tão importante quanto proceder a saída de dados é obter informações necessárias ao processamento. Este procedimento é conhecido como Entrada de Dados. Os dados de entrada podem ser enviados de qualquer dispositivo de entrada ligado ao computador (teclado, discos, mouse, dentre outros). Em nosso curso utilizaremos o teclado como dispositivo padrão de entrada. Na linguagem C a função responsável por esta tarefa é a scanf. Ela permite operações de entrada de dados, ou seja, a leitura de dados formatados do teclado, após pressionar a tecla enter. Segue abaixo sua sintaxe. Exemplo de entrada de dados através do uso da função scanf printf("Digite a distancia:"); 1 scanf("%d",¢imetro); 2 Linha Comentário 1 Uma ação muito comum em programas é a de orientar o usuário a tomar alguma atitude. Nesse caso a função printf está sendo usada apenas para mostrar uma mensagem ao usuário de como proceder. 2 A função scanf causa uma pausa no programa, ficando em estado de espera. O Usuário digita a informação desejada e tecla enter para que a informação digitada seja atribuída à variável utilizada na operação de entrada, que no nosso exemplo é centimetro. Em seguida o fluxo de execução continua e a próxima instrução será executada. Observações: O comando scanf exige que seja informado o endereço da variável. Utilizamos o & para referenciar o endereço de uma variável. Lembre-se: quando uma variável é declarada, é alocado um espaço na memória correspondente ao seu tipo. Este espaço, que a variável ocupa, possui um endereço que pode ser acessado usando o operador &. A string de controle presente na função scanf tem o mesmo comportamento que já conhecemos da função printf. Existem outras funções, na linguagem C, que permitem a entrada de dados. A função getche, lê e retorna um caractere do teclado sem esperar enter e permite que o mesmo seja impresso na tela. A outra função, getch, tem o mesmo comportamento, entretanto não permite que o caractere lido seja impresso na tela. Essas funções somente poderão ser usadas para a leitura de caractere. scanf (“string de controle”, lista-argumentos) Algoritmos Prof. Hilton Cardoso Marins Junior Página 15 de 45 Exemplo de entrada de dados através do uso das funções getche e getch printf(“Digite a turma:”); 1 char turma = getche(); 2 printf(“Tecle algo para continuar ...”); 3 getch();4 Linha Comentário 2 A função getche causa uma parada no programa, o usuário digita um caractere que é atribuído à variável turma e em seguida o programa continua. 4 A função getch causa uma parada no programa, o usuário digita um caractere que não será mostrada na tela e nada é feito. Em seguida o programa continua. Prática 6: Lendo valores do teclado Algoritmos Prof. Hilton Cardoso Marins Junior Página 16 de 45 7. Identificando as partes de um programa Antes de finalizar esta parte introdutória, chamamos a atenção dos iniciantes em programação, para uma fase do desenvolvimento de programas, muitas vezes negligenciada, que é encontrar a solução do problema. Lembre-se de que o nosso objetivo, como programadores, é criarmos uma solução para um problema através do computador. Se não conhecemos a solução de um problema não conseguiremos instruir o computador a resolvê-lo. Vejamos um exemplo. Suponha que você deseja criar um programa para calcular a situação dos alunos de uma escola ao final do período letivo. Você sabe se as notas são agrupadas por bimestres ou trimestres? Você sabe se a recuperação é bimestral, trimestral ou semestral? Você sabe a média para ser aprovado? Quais as condições para aprovação? Qual a quantidade máxima de faltas possíveis? Se você desconhece alguma das questões anteriores não será possível criar um programa para resolver o problema. Aqui vai uma dicamuito importante: elabore uma solução para o problema antes de começar a codificar um programa para resolvê- lo. O nosso objetivo neste curso é criar programas para que o computador possa executá-los. Todo programa é constituído de instruções que orientarão o computador a resolver um determinado problema. Se você não conhece a solução do problema não conseguirá orientar o computador a resolvê-lo. Então fica a dica: só comece a implementar um programa depois de planejar a solução do problema. Isso é uma tarefa anterior à codificação. Essa é a maior dificuldade em programação: elaborar uma solução para um problema que não dominamos ou que não lidamos em nosso dia a dia. Prática 7: Identificando as partes de um programa Exercícios 1. Faça um programa que receba três notas, seus respectivos pesos, e calcule a média ponderada dessas notas. 2. Faça um programa que receba o salário de um funcionário e o percentual de aumento, calcule e mostre o valor do aumento e o novo salário. 3. Faça um programa que receba o salário-base de um funcionário, calcule e mostre o salário a receber, sabendo-se que esse funcionário tem gratificação de 5% sobre o salário-base e paga imposto de 7% sobre salário-base. 4. Faça um programa que receba um número positivo e maior que zero, calcule e mostre: a. O número digitado ao quadrado. b. O número digitado ao cubo. c. A metade do número digitado. d. O sucessor do número digitado. 5. Fazer um programa para determinar o consumo médio de combustível de um automóvel, sendo fornecida a distância total percorrida pelo automóvel e o total de combustível gasto. Algoritmos Prof. Hilton Cardoso Marins Junior Página 17 de 45 6. Fazer um programa capaz de calcular a área de uma figura geométrica do tipo circunferência. 7. Fazer um programa que leia o nome de um vendedor, o seu salário fixo e o total de vendas efetuadas por ele no mês (em dinheiro). Sabendo que este vendedor ganha 15% de comissão sobre suas vendas efetuadas, informar o seu nome, o salário fixo e salário no final do mês. 8. Codificar um programa para ler dois valores para as variáveis A e B, e efetuar as trocas dos valores de forma que a variável A passe a possuir o valor da variável B e a variável B passe a possuir o valor da variável A. Apresentar os valores trocados. 9. Codificar um programa para ler uma temperatura em graus Celsius e apresentá-la convertida em graus Fahrenheit. A fórmula de conversão é: F=(9*C+160) / 5, sendo F a temperatura em Fahrenheit e C a temperatura em Celsius. 10. Codificar um programa que efetue a apresentação do valor da conversão em real (R$) de um valor lido em dólar (US$). O programa deverá solicitar o valor da cotação do dólar e também a quantidade de dólares disponíveis com o usuário. 11. Faça um programa que receba um valor que foi depositado em uma conta poupança e exiba o valor com rendimento após um mês. Considere fixo o juro da poupança em 0,70% a. m. 12. A Loja Mamão com Açúcar está vendendo seus produtos em 5 (cinco) prestações sem juros. Faça um programa que receba um valor de uma compra e mostre o valor das prestações. 13. Faça um programa que receba o preço de custo de um produto e mostre o valor de venda. Sabe-se que o preço de custo receberá um acréscimo de acordo com um percentual informado pelo usuário. 14. Faça um programa para calcular quantas ferraduras são necessárias para equipar todos os cavalos comprados para um haras. 15. A padaria HotPão vende uma certa quantidade de pães franceses e uma quantidade de broas a cada dia. Cada pãozinho custa R$ 0,12 e a broa custa R$ 1,50. Ao final do dia, o dono quer saber quanto arrecadou com a venda dos pães e broas (juntos), e quanto deve guardar numa conta poupança (10% do total arrecadado). Você foi contratado para fazer os cálculos para o dono. Com base nestes fatos, faça um programa para ler as quantidades de pães e de broas, e depois calcular os dados solicitados. 16. Faça um programa para ler o nome e a idade de uma pessoa, e exibir quantos dias de vida ela já viveu. Considere sempre anos completos, e que um ano possui 365 dias. Ex: uma pessoa com 19 anos possui 6935 dias de vida. Veja um exemplo de saída: Maria, você já viveu 6935 dias. Algoritmos Prof. Hilton Cardoso Marins Junior Página 18 de 45 8. Controle do Fluxo de Execução Veremos agora uma das partes mais importantes do nosso curso, que é controlar o fluxo de execução de um programa. Você já percebeu que todos os programas desenvolvidos até agora apresentam uma sequência de instruções, ou seja, todas as instruções são executadas uma após a outra em uma sequência da primeira até a última. Haverá situações em que determinadas instruções só poderão ser executadas se uma condição for obedecida. Para exemplificar vamos voltar ao cálculo do IMC e imaginar uma funcionalidade capaz de indicar ao usuário a necessidade de se realizar um procedimento de perda de peso. É óbvio que essa indicação de perda de peso só deve ser realizada se IMC for superior a um determinado valor. Perceberam a vinculação de uma ação (indicação de perda de peso) a uma condição (IMC maior que um determinado valor)? Agora imagine outra situação em que o cálculo do IMC deverá ser realizado diversas vezes para várias pessoas. Neste caso devemos indicar que algumas instruções deverão ser executadas repetidas vezes. Já ficou claro que haverá situações em que não conseguiremos implementar um programa usando somente a estrutura sequencial de instruções. Será muito comum necessitarmos de estruturas de controle que implementam a alternativa e a repetição. 8.1 Sequência { Comando-1; Comando-2; . . . } Os comandos serão executados um após o outro. As chaves indicam início e fim de um bloco de comandos. Algoritmos Prof. Hilton Cardoso Marins Junior Página 19 de 45 8.2 Alternativa Simples Representação em fluxograma if (condição){ c1; c2; . . . cn; } Implementação em C Os comandos c1, c2, …, cn serão executados somente se a condição for verdadeira. Prática 8.1: Estabelecendo uma alternativa simples V F Condição C1 C2 Cn V Algoritmos Prof. Hilton Cardoso Marins Junior Página 20 de 45 8.3 Alternativa Composta Representação em fluxograma if (condição){ c1; c2; . . . cn; }else{ c’1; c’2; . . . c’n; } Implementação em C Se a condição for verdadeira os comandos c1, c2, …, cn serão executados, caso contrário os comandos c’1, c’2, ..., c’n é que serão executados. Condição C1 C2 Cn C’1 C’2 C’n V F Algoritmos Prof. Hilton Cardoso Marins Junior Página 21 de 45 ... int x = 10; if (x){ c1; }else{ c2; } ... ... int x = 10; if (x-10){ c1; }else{ c2; } ... Prática 8.2: Estabelecendo uma alternativa composta Observação Na linguagem C não existe o tipo de dados boolean (verdadeiro e falso) como em outras linguagens. Em C um valor diferente de zero é considerado verdadeiro e igual a zero falso. Uma instrução if não fica restrita expressões envolvendo os operadores lógicos e relacionais. O programa simplesmente precisa chegar a um valor zero (falso) e não zero (verdadeiro). Observe os dois trechos de programa abaixo e responda: quais instruções serão executadas, c1 ou c2?8.4 Alternativa Múltipla Representação em fluxograma Expressão Ordinal comandos_1 comandos_2 comandos_n. . . Caso 1 Caso 2 Caso n Algoritmos Prof. Hilton Cardoso Marins Junior Página 22 de 45 switch (expressão ordinal){ case constante1: instrucoes; break; case constante2: instrucoes; break; . . . default: instrucoes; } Implementação em C O resultado da expressão ordinal (cujo resultado deve ser do tipo char ou int) será comparado com cada constante informada após a palavra case. Sendo igual, todos os comandos relacionados ao case, serão executados até que um comando break seja encontrado. O comando break causa o desvio do fluxo de execução para a primeira instrução após o switch. Se não existir um comando break seguindo as instruções de um case, o programa segue executando as instruções dos cases seguintes. Se nenhum case for satisfeito a execução começa no default, que por sua vez é opcional. Cada case pode ter várias instruções e não devem estar entre chaves. Prática 8.3: Estabelecendo uma alternativa múltipla Exercícios 1) Faça um programa que gere um número aleatório de 0 a 9, receba um palpite via teclado e informe se o palpite é certo ou errado. Dicas: a) A instrução srand (time(NULL) ); faz com que o número gerado varie a cada execução do programa. Portanto só deve ser executada uma vez a cada execução do programa. b) A instrução numeroGerado = rand(); gera um número aleatório e atribui este valor à variável numeroGerado. c) As funções srand(), rand e time exigem a declaração da biblioteca time.h d) O operador % é chamado operador módulo ou resto da divisão. Assim, x = y % 10; atribui á variável x o resto da divisão de y por 10. Ou seja, se y = 23, x receberá o valor 3. e) O número gerado com a função rand() é grande. Se aplicarmos o operador módulo deste número grande por 10, por exemplo, teremos sempre o resto da divisão por 10, o que será um número de zero a 9. f) Teste de igualdade em C é feito com == e não apenas com um =. 2) Codificar um programa para verificar se 3 números inteiros podem ser lados de um triangulo. Informar também o tipo do triangulo (equilátero, isósceles ou escaleno). Dica: cada lado do triângulo é menor que a soma dos outros dois lados. Algoritmos Prof. Hilton Cardoso Marins Junior Página 23 de 45 3) Uma livraria está fazendo uma promoção para pagamento à vista em que o comprador pode escolher entre dois critérios de pagamento: Critério A: R$ 0,25 por livro + RS$ 7,50 fixo. Critério B: R$ 0,50 por livro + RS$ 2,50 fixo. Faça um programa em que o usuário digita a quantidade de livros que deseja comprar e o programa informa qual é a melhor opção de desconto. 4) Codificar um programa para verificar se um número é divisível por outro. 5) Faça um programa que receba 3 números via teclado e imprima o maior deles. 6) Faça um programa para calcular a(s) raízes reais de uma equação do segundo grau. O programa deverá receber os 3 coeficientes e não deverá aceitar o coeficiente de x2 igual a zero. 7) Uma empresa abriu uma linha de crédito para os funcionários. O valor da prestação não pode ultrapassar 30% do salário. Faça um programa que receba o salário, o valor do empréstimo e o número de prestações e informe se o empréstimo pode ser concedido. Nenhum dos valores informados pode ser zero ou negativo. 8) Fazer um programa que mostre uma questão de múltipla escolha com 5 opções (letras a, b, c, d, e). Sabendo a resposta certa, receber a opção do usuário e informar se a resposta está certa ou errada. Usar o tipo char para armazenar a variável de teste do switch. Ela pode ser lida do teclado com scanf e a máscara %c ou com a função getchar() (opcao = getchar()). Na comparação do case, deve-se colocar o valor a ser comparado entre aspas simples: case 'a'... 9) Fazer um programa que lê dois números, lê a operação desejada ( + - * / ), faz a operação pedida e mostra o resultado. A operação escolhida deve ser armazenada em uma variável do tipo char. Algoritmos Prof. Hilton Cardoso Marins Junior Página 24 de 45 8.5 Repetição com Teste no Início Representação em fluxograma while (condição) { C1; C2; . . . Cn; } Implementação em C Os comandos internos ao while (C1, C2, ..., Cn) serão executados repetidas vezes enquanto a condição for verdadeira. Quando a condição se tornar falsa o fluxo de execução será desviado para a primeira instrução após o comando while. Se a condição, inicialmente for falsa, nenhuma repetição ocorrerá. Prática 8.4: Estabelecendo uma repetição com while Condição C1 C2 Cn V F Algoritmos Prof. Hilton Cardoso Marins Junior Página 25 de 45 8.6 Repetição com Teste no Final Representação em fluxograma do{ C1; C2; . . . Cn; }while (condição); Implementação em C Os comandos internos ao do ... while (C1, C2, ..., Cn) serão executados repetidas vezes enquanto a condição for verdadeira. Quando a condição se tornar falsa o fluxo de execução será desviado para a primeira instrução após o comando while. Se a condição, inicialmente for falsa, ocorrerá uma repetição e essa é única diferença para a estrutura que implementa a Condição C1 C2 Cn V F Algoritmos Prof. Hilton Cardoso Marins Junior Página 26 de 45 repetição com teste no início. Aqui, como a condição é verificada no final da repetição, podemos garantir que pelo menos uma repetição sempre ocorrerá. 8.7 Repetição com Variável de Controle Representação em fluxograma for{ação-1; condição; ação-2){ C1; C2; . . . Cn; } Implementação em C V F Altera o valor da variável Condição envolvendo a variável variavel = valor inicial C2 Cn C1 Algoritmos Prof. Hilton Cardoso Marins Junior Página 27 de 45 O comando for usa uma variável para controlar o número de repetições. Normalmente em ação-1 inicializamos a variável de controle, em ação-2 alteramos a variável de controle, incrementando ou decrementando seu valor e em condição definimos uma forma de finalizar a repetição, verificando se a variável se controle já alcançou um determinado limite. A ação-1 é executada somente uma vez e antes da primeira repetição. Normalmente é usada para inicializarmos a variável de controle. A ação-2 é executada ao final de cada repetição. Define a maneira como a variável de controle será alterada a cada repetição. Permite que a variável de controle chegue a um valor que torne a condição falsa, ou seja, que a repetição chegue ao fim. Geralmente é usada para incrementar ou decrementar a variável de controle. A condição é testada antes de cada repetição, se for verdadeira haverá mais uma repetição e caso contrário o fluxo de execução é desviado para a próxima instrução após o for. Haverá repetição enquanto a condição for verdadeira. Prática 8.5: Estabelecendo uma repetição com for Exercícios 1) Considere a progressão geométrica (PG) 1, 2, 4, 8, 16, 32, .... e um inteiro positivo n. Deseja-se que um programa faça: Imprimir os n primeiros termos. Calcular e imprimir a soma dos n primeiros termos da PG sem utilizar a fórmula da soma. 2) Considere uma progressão aritmética (PA). Faça um programa que receba o termo inicial a1, a razão r e o número de termos a serem gerados.Em seguida, a PA é impressa, com 10 termos por linha. Ao final, depois de imprimir todos os termos desejados, deve-se imprimir a soma dos termos da PA. Faça uma verificação de acerto através da fórmula da soma dos termos da PA. dada pela expressão abaixo: 3) Faça um programa que receba um número n e gere os n primeiros números da sequência de Fibonacci, Definida na fórmula: Algoritmos Prof. Hilton Cardoso Marins Junior Página 28 de 45 4) Ler um número e imprimir todos os seus divisores. 5) Considere o programa abaixo. main(){ int linha,coluna; for (linha=1;linha<=5;linha++){ for (coluna=1;coluna<=5;coluna++){ printf("\t[%d,%d]",linha, coluna); } printf("\n"); } } A saída será a seguinte: [1,1] [1,2] [1,3] [1,4] [1,5] [2,1] [2,2] [2,3] [2,4] [2,5] [3,1] [3,2] [3,3] [3,4] [3,5] [4,1] [4,2] [4,3] [4,4] [4,5] [5,1] [5,2] [5,3] [5,4] [5,5] Considerando a saída como uma matriz, modique o programa acima para que apenas a diagonal principal e os dados acima dela sejam impressos. Com as modificações propostas a saída deverá ser assim: [1,1] [1,2] [1,3] [1,4] [1,5] [2,2] [2,3] [2,4] [2,5] [3,3] [3,4] [3,5] [4,4] [4,5] [5,5] 6) Codificar um programa para calcular o fatorial de um número informado pelo usuário. 7) Fazer um programa que leia uma quantidade desconhecida de números e imprima, no final, o maior deles, o menor deles e quantos números foram digitados. Para terminar de informar números e finalizar o programa o usuário deve informar 999. 8) Existem três candidatos a uma vaga no Senado. Feita a eleição, os votos são registrados da seguinte forma: Codificar um programa capaz de informar: o candidato vencedor, a quantidade de votos em branco, nulos e o número de eleitores que compareceram às urnas. Voto Significado 1 candidato 1 2 candidato 2 3 candidato 3 4 voto branco 5 voto nulo Algoritmos Prof. Hilton Cardoso Marins Junior Página 29 de 45 9. Estruturas de Dados Homogênea - Vetor O nosso conhecimento básico de programação, adquirido até momento é razoável, entretanto não é suficiente para resolvermos o problema que nós analisaremos agora. O objetivo é motivá-lo a conhecer uma nova técnica para armazenamento de dados. Vamos voltar ao programa media.c e alterá-lo de forma a calcular a quantidade de alunos que obtiveram nota acima da média da turma. Para verificar quem obteve nota acima da média, basta comparar cada nota com a média da turma, certo? Observe as instruções destacadas na nova versão do programa media.c. Programa media.c main(){ 1 float media, nota; 2 int cont = 0, qtnotas; 3 4 printf(“Informe a quantidade de notas: “); 5 scanf(“%d”, &qtnotas); 6 7 int acima = 0; 8 while (cont < qtnotas){ 9 printf(“\nInforme a Nota: ”); 10 scanf(“%f”, ¬a); 11 media = media + nota; 12 cont = cont + 1; 13 14 if (nota > media){ 15 acima = acima + 1; 16 } 17 } 18 media = media / qtnotas; 19 printf(“\nA media das notas da turma: %f“, media); 20 printf(“\nNotas acima da media......: &d”, acima); 21 }22 Linha Comentário 8 A variável acima contabiliza a quantidade de notas acima da média. Antes de começar a ler as notas o número de notas acima da média é zero, por isso a inicializamos com 0. 15 a 17 Cada nota lida será comparada com a média. No caso de ser maior do que a média, incrementamos a variável acima em uma unidade. 21 Ao final da repetição a variável acima conterá a quantidade de notas acima da média. Todo nosso raciocínio para a solução desse novo problema está certo, porém estamos esquecendo algo, você já percebeu? Algoritmos Prof. Hilton Cardoso Marins Junior Página 30 de 45 Voltemos nossa atenção para a linha 15. Não está achando esta condição estranha? Neste ponto do programa já temos disponível o cálculo da média? Não, isso só ocorrerá na linha 19, após o fim da repetição. Então concluímos que as instruções localizadas nas linhas 15, 16 e 17 devem ser retiradas do interior do comando de repetição e ser colocadas após o cálculo da média, ou seja, após a linha 19. Então vejamos como ficaria o nosso programa. Programa media.c main(){ 1 float media, nota; 2 int cont = 0, qtnotas; 3 4 printf(“Informe a quantidade de notas: “); 5 scanf(“%d”, &qtnotas); 6 7 int acima = 0; 8 while (cont < qtnotas){ 9 printf(“\nInforme a Nota: ”); 10 scanf(“%f”, ¬a); 11 media = media + nota; 12 cont = cont + 1; 13 } 14 media = media / qtnotas; 15 16 if (nota > media){ 17 acima = acima + 1; 18 } 19 20 printf(“\nA media das notas da turma: %f“, media); 21 printf(“\nNotas acima da media......: &d”, acima); 22 }23 Linha Comentário 17 a 19 Neste ponto do programam a média já foi calculada e podemos comparar com as notas. Agora apareceu outro problema: a variável nota armazena somente a última nota digitada. Como ter acesso às notas digitadas anteriormente? Nesta última versão do programa media.c resolvemos um problema mas apareceu outro. Como ter acesso a todas as notas digitadas? Sabemos que para cada nota lida o seu valor é armazenado na variável nota e o seu valor anterior é perdido, entretanto precisamos ter todas as notas disponíveis na memória para poder compará-las com a média (linhas 17 a 19). Com o conhecimento que temos, a única solução é criarmos tantas variáveis quanto a quantidade de notas. Já vimos anteriormente que esta solução não é a ideal. Vamos apresentar uma estrutura de dados capaz de armazenar vários valores e resolver este nosso problema. Trata-se da estrutura de dados homogênea. É uma coleção de dados do mesmo tipo (daí a palavra homogênea) que é referenciada por um único nome. Esta estrutura apresenta outras 2 características importantes: Algoritmos Prof. Hilton Cardoso Marins Junior Página 31 de 45 tipo nome-variável[tamanho] double notas[10] 1. Seus elementos ocupam posições contíguas da memória. O endereço mais baixo corresponde ao primeiro elemento e mais alto ao último. 2. Possui número de elementos fixo, ou seja, a variável desse tipo é declarada com uma quantidade de elementos que não pode ser alterada durante a execução do programa. Uma estrutura de dados homogênea é também conhecida como vetor, matriz, variável indexada ou array. Um elemento específico do vetor é acessado por meio de um índice. O índice é um número inteiro que corresponde à posição de um elemento dentro do vetor. A seguir veremos um exemplo de vetor que armazena 10 notas. Representação de um vetor com 10 elementos Observe que, como o primeiro índice do vetor é 0, a quantidade de elementos armazenada em um vetor é dada pelo maior índice mais 1, ou se preferir, podemos dizer que o último índice é igual ao numero de elementos do vetor menos 1. Geralmente associamos as posições do vetor a alguma entidade do mundo real. No caso acima associamos cada posição a uma nota de um aluno: posição 0 armazena a nota do 1º aluno, posição 1 armazena nota do aluno 2º aluno e assim sucessivamente. Vejamos agora a sintaxe correta para declarar um vetor. No exemplo abaixo é alocado espaço na memória suficiente para armazenar 10 notas. Esse local foi rotulado com o nome de notas. E para fazer referência a este local da memória usaremos o nome da variável que é notas e o índice indicando qual posição do vetor desejamos nos referir. Se os elementos do vetor ocupam posições contiguas da memória, porque os endereços não são consecutivos? A nota 8.0 do índice 1, por exemplo, não deveria estar no endereço 2293497,porque ela está no endereço 2293504? A explicação é simples, cada elemento é Posição 1ª 2ª 3ª 4ª 5ª 6ª 7ª 8ª 9ª 10ª Índice 0 1 2 3 4 5 6 7 8 9 Valor 7.5 8.0 3.5 10.0 6.0 8.0 9.0 6.5 7.5 4.5 Posição 1ª 2ª 3ª ... 8ª 9ª 10ª Índice 0 1 2 ... 7 8 9 Valor 7.5 8.0 3.5 ... 6.5 7.5 4.5 Como referenciar notas[0] notas[1] notas[2] ... notas[7] notas[8] notas[9] Supostos Endereços 2293496 2293504 2293512 ... 2293552 2293560 2293568 Algoritmos Prof. Hilton Cardoso Marins Junior Página 32 de 45 char nome[5] tipo nome-variável[linhas][colunas] double notas[50][4] armazenado em posições contíguas, porém cada valor do tipo double ocupa 8 bytes na memória. Em um vetor de char teríamos a situação abaixo. Lembre-se de que cada valor do tipo char ocupa 1 byte na memória: Prática 9.1: Vetor unidimensional O vetor que manipulamos até agora são considerados unidimensionais, pois cada informação está vinculada a apenas uma entidade (notas de alunos, nomes de pessoas, salários de funcionários). Para vetores unidimensionais necessitaremos de apenas um índice. Agora imagine que cada nota esteja vinculada a duas entidades, alunos e bimestres por exemplo. Neste caso precisaremos de um vetor bidimensional. Vetores bidimensionais necessitam de dois índices. Veremos abaixo como declarar e manipular um vetor bidimensional, ou mais comumente chamado de matriz. No exemplo abaixo é alocado espaço na memória suficiente para armazenar 200 notas, 4 para cada um dos 50 alunos. Ao declararmos um vetor bidimensional, sempre informamos primeiro o número de linhas e em seguida o número de colunas. No exemplo acima, associamos os alunos às linhas e os bimestres às colunas. Podemos representar nosso vetor conforme a figura abaixo. Posição 1ª 2ª 3ª 4ª Índice 0 1 2 3 Valor I F E T Como referenciar nome[0] nome[1] mome[2] nomea[3] Supostos Endereços 2293496 2293497 2293498 2293499 Algoritmos Prof. Hilton Cardoso Marins Junior Página 33 de 45 printf(“%f”, notas[49][2]) scanf(“%f”, ¬as[49][2]) printf(“%f”,(notas[49][0]+notas[49][1]+notas[49][2])+notas[49][3])/4) int i[10]={1,2,3,4,5,6,7,8,9,10} int quadrados[10][2] = {1,1,2,4,3,9,4,16,5,25, 6,36, 7,49,8,64,9,81,10,100} Para imprimir a nota do último aluno no 3o. bimestre: Para ler do teclado: Para imprimir a média das notas do último aluno: Prática 9.2: Vetor bidimensional O vetor, seja unidimensional ou bidimensional, pode ser inicializado como qualquer variável e é isso que veremos agora. No exemplo abaixo declaramos um vetor de inteiros com 10 elementos e ao mesmo tempo inicializamos com os valores informados. O vetor i será preenchido de forma que i[0] terá o valor 1, i[1] o valor 2 e assim sucessivamente. Veja abaixo um exemplo de inicialização de um vetor bidimensional: 0 1 0 1 1 1 2 4 2 3 9 3 4 16 4 5 25 5 6 36 6 7 49 7 8 64 8 9 81 9 10 100 0 1 2 3 0 10,0 9,5 8,5 9,5 1 7,0 8,5 9,5 10,0 2 9,0 6,5 7,5 9,5 . . . 49 8,5 5,0 10,0 9,0 Bimestres Alunos Algoritmos Prof. Hilton Cardoso Marins Junior Página 34 de 45 char str[18] = “Ifet Juiz de Fora” char str[30][80] Já vetores de caracteres, mais conhecidos como strings, devem ser inicializados assim: Toda string possui no seu final um caractere nulo que sinaliza o seu fim (‘/0’). Por isso que dimensionamos o vetor str com tamanho 18, apesar de “Ifet Juiz de Fora” só possuir 17 caracteres. Você não precisa adicionar o caractere nulo ao final das constantes string, manualmente. O compilador C faz isso por você automaticamente. Muitas linguagens de programação fornecem o tipo string para que possamos armazenar uma cadeia de caracteres. Não é o caso da Linguagem C. Em C uma String é definida como um vetor de caracteres. Para solicitar a entrada de uma string, utilize a função gets(). Veja um exemplo abaixo. Exemplo da função gets char frase[80]; 1 printf("\nDigite uma frase: "); 2 gets(frase); 3 4 Procure saber sobre algumas funções pré-definidas em C para a manipulação de string. No exemplo acima, o vetor frase armazena somente uma string. Como proceder para armazenar várias strings ? É simples, basta declararmos um vetor bidimensional de caracteres. O tamanho do índice esquerdo indica o número de strings que desejamos armazenar e o tamanho do índice direito especifica o comprimento máximo de cada string. A declaração de um vetor de 30 strings, cada qual com um comprimento máximo de 79 caracteres seria assim: Para acessar uma string individualmente, especificamos apenas o índice esquerdo. A instrução gets(str[2]) lê do teclado uma string e armazena 3ª linha do vetor bidimensional. Para acessar um caractere individualmente, de uma string, especificamos os dois índices. A instrução printf(“%c”,str[2][5]) mostra o 6º caractere da 2ª string. Vamos mostrar um programa que manipula strings. Trata-se de um editor de texto bem simples. Algoritmos Prof. Hilton Cardoso Marins Junior Página 35 de 45 Programa editor.c main(){ 1 int i; 2 char texto [100][80] ; 3 4 printf("\nDigite o texto...\n" ); 5 for (i=0; i<100; i++){ 6 gets(texto[i]); 7 } 8 9 //mostra o texto na tela 10 for (i=0; i<100; i++){ 11 if (texto[i][0] == '\0'){ 12 break ; 13 } 14 printf("%s\n", texto[i]); 15 } 16 }17 Linha Comentário 3 O vetor bidimensional de nome texto terá a capacidade de armazenar 100 linhas com 79 caracteres cada. 12 Se o primeiro caractere de uma linha for o ‘\0’significa que não tem mais linhas com texto. Exercícios 1) Faça um programa que receba via teclado 8 notas de uma turma. Depois de lidas todas as notas, calcule e imprima a média da turma, a menor nota e a maior nota. As notas devem ser armazenadas em um vetor de reais (float). 2) Ler 2 vetores de inteiros com 11 elementos cada um. Em seguida, gerar um vetor soma onde cada elemento corresponda à soma dos dois elementos dos vetores lidos. Gerar outro vetor produto cujos elementos correspondam ao produto dos elementos de mesma posição dos vetores lidos. Exibir os 4 vetores na tela. 3) Ler um vetor com 8 elementos do tipo float e imprimir seus elementos de trás pra frente (do último ao primeiro). 4) Ler 2 vetores com 7 elementos do tipo inteiro cada um e concatená-los em um terceiro vetor. 5) Fazer um programa que receba 15 valores inteiros e os grave em um vetor. Depois desta etapa, percorra o vetor e identifique o maior e o menor elemento do vetor. Informe os valores e a posição que eles ocupam no vetor. Depois desta etapa, some os elementos do vetor e exiba o valor desta soma. 6) Fazer um programa que leia a senha do usuário e informe se a senha está correta ou incorreta. Considere que a senha correta está gravada no código fonte do programa. Algoritmos Prof. Hilton Cardoso Marins Junior Página 36 de 45 7) Fazer um programa que leia uma string e a imprima de trás pra frente. Exemplo: Digitado: ifsudestemg Impresso: gmetsedus 8) Fazer um programa que leia os elementos de uma matriz 4X4. Em seguida, o programa calcula e exibe a soma dos elementos da diagonal principal. 9) Codificar um programa para simular a verificação se o dado usado em um determinado jogo é “viciado” ou não. Considere que dado não “viciado” é aquele em que não há grande variação na quantidade de vezes que cada face é sorteada ao final de vários lançamentos. O programa deve permitir ao usuário escolher o número de faces do dado (mínimo 2) e a quantidade de lançamentos a serem simulados. Após fazer a simulação,o programa deverá emitir um relatório apresentando a quantidade de vezes que cada face fora sorteada. Algoritmos Prof. Hilton Cardoso Marins Junior Página 37 de 45 10. Modularização A modularização consiste em um método para facilitar a construção de grandes programas, através de sua divisão em pequenos programas conhecidos como módulos, rotinas, sub- rotinas ou sub-programas. Um dos objetivos do programador é dividir o programa em módulos de menor complexidade, eliminando o inconveniente dos programas se tornarem extremamente grandes e complexos, em aplicações de maior porte. O programador ao projetar um programa deverá levar em conta que os módulos são criados de acordo com a sua função. Os módulos deverão ter funções específicas e independentes (em termos funcionais). Esta característica de independência funcional dos módulos facilita a manutenção do código e o trabalho em equipe. O programador ao projetar um programa deve procurar separar blocos de comandos de acordo com sua função. Chamamos estes blocos de funções. Na linguagem C, implementamos os módulos de programa através das funções. No início do nosso curso falamos sobre função, mas agora o enfoque será diferente. Estamos interessados na implementação de nossas próprias funções. Uma função é um trecho de programa que possui cabeçalho, variáveis e comandos próprios e que pode ser chamado (invocado) por um programa ou outra função. Quando uma função é referenciada, o controle do fluxo de execução é automaticamente transferido para o princípio dela. As instruções são então executadas e ao final, o controle é automaticamente devolvido à instrução imediatamente a seguir à chamada da função. Para executar uma função, ela deve ser invocada no corpo de outra função, exceto a função main(), que é executada ao iniciar o programa. O esquema abaixo mostra como é fluxo de execução ao invocarmos uma função. Veja abaixo um exemplo de programa, que diferentemente de todos que criamos até o momento, separa cada funcionalidade em módulos específicos. Programa funcao.c void apresentacao(void); 1 int edivisivel( int a, int b); 2 3 main(){ 4 funcao1(){ . . . funcao2(); . . . } funcao2(){ . . . } Algoritmos Prof. Hilton Cardoso Marins Junior Página 38 de 45 int n1,n2; 5 apresentacao(); 6 printf("\nInforme um numero: "); 7 scanf("%d", &n1); 8 printf("\nInforme um numero: "); 9 scanf("%d", &n2); 10 11 if ( edivisivel(n1,n2)){ 12 printf("%d e divisivel por %d", n1, n2); 13 }else{ 14 printf("%d NAO e divisivel por %d", n1, n2); 15 } 16 } 17 18 void apresentacao(void){ 19 system("cls"); 20 printf("\n*************************************"); 21 printf("\nPROGRAMA QUE EXPLICA O USO DE FUNCOES"); 22 printf("\n\nIF SUDESTE MINAS GERAIS"); 23 printf("\nProf. Hilton Cardoso Marins Junior"); 24 printf("\n*************************************"); 25 } 26 27 int edivisivel( int a, int b){ 28 if ((a%b) == 0 ){ 29 return 1; 30 }else{ 31 return 0; 32 } 33 }34 Linha Comentário 1 e 2 Escrevemos os protótipos de todas as funções que fazem parte do programa funcao.c. No nosso caso são duas: apresentacao() e edivisivel(). Um protótipo de função é composto apenas do cabeçalho da função, sem implementação. Mais adiante detalharemos melhor sobre o cabeçalho de uma função. 6 Chamada da função apresentação(). Neste ponto o fluxo de execução é desviado para a primeira instrução localizada dentro da função apresentacao(). Ao executar todas as instruções da função apresentação(), o fluxo de execução continua na próxima linha (7). 12 Verifica-se aqui uma chamada à função edivisivel() e o envio de duas variável (n1 e n2)e também o retorno de informação. Neste caso a informação retornada fará parte da expressão condicional. 13 e 14 O retorno da função pode ser um número diferente de 0 (verdadeiro) ou igual 0 (falso). 19 Cabeçalho da função apresentacao(). O cabeçalho de uma função possui 3 partes: O tipo de retorno, o nome da função e os dados necessários para que a função cumpra o seu papel. A função apresentacao() não precisa de nenhum dado e tão pouco retorna um dado, por isso usamos a palavra void. 28 Já a função edivisivel(), tem como objetivo verificar se um número é divisível por outro. Portanto ela precisa de dois dados e retorna uma indicação se o primeiro é ou não divisível pelo segundo. Quando a função edivisivel() é chamada os valores de n1 e n2 serão atribuídos às variáveis a e b, realiza-se a verificação e a palavra Algoritmos Prof. Hilton Cardoso Marins Junior Página 39 de 45 return sinaliza que a função será finalizada e o dado que aparece ao seu lado será devolvido à chamada da função. Vimos no exemplo acima que podemos passar dados para funções, assim como receber dados das funções. Vamos aprofundar um pouco neste assunto. Argumentos de uma função são utilizados para transmitir informações para a função. Se uma função usa argumentos, ela deve declarar variáveis que aceitem os valores dos argumentos. Estas variáveis são chamadas de parâmetros formais. Os parâmetros formais se comportam como quaisquer outras variáveis dentro da função. Uma função pode receber qualquer número de argumentos, inclusive nenhum. No caso de uma função sem argumentos pode-se escrevê-la de duas formas: deixando a lista de argumentos vazia (mantendo-se os parênteses) ou colocando o tipo void entre parênteses. Exemplo de função que recebe um int e retorna outro int int triplo(int r){ 1 return 3*r; 2 }3 Exemplo de função sem parâmetros e sem retorno void mostra(){ //ou void mostra(void) 1 printf(“Ola!”); 2 }3 O retorno de uma função é um valor que será retornado para quem a chamou. O tipo de retorno é fornecido no cabeçalho da função antes de seu nome. No caso da função triplo() acima, o retorno será um número do tipo int. O comando return faz com que seja retornado o valor especificado e faz com que a função termine. O comando return pode ser utilizado também para indicar a saída imediata da função. Se uma função não retorna nada, seu tipo de retorno deve ser definido como void. Se o tipo de retorno da função não é explicitamente declarado, o compilador C atribui automaticamente o tipo padrão, que é int. Vejamos mais um exemplo de programa que usa funções. Programa calculamedia.c float calculaMedia (float argA ,float argB ); 1 2 main() { 3 float a , b , m; 4 5 printf ("\nDigite o primeiro numero: " ) ; 6 scanf ("%f", &a ) ; 7 8 printf ("\nDigite o segundo numero: " ) ; 9 scanf ("%f", &b ) ; 10 m = calculaMedia (a, b) ; 11 Algoritmos Prof. Hilton Cardoso Marins Junior Página 40 de 45 12 printf("\nMedia entre %.2f e %.2f é %.2f\n",a,b,m); 13 } 14 15 float calculaMedia (float argA , float argB) { 16 float mediaCalculada ; 17 18 mediaCalculada = ( argA + argB ) / 2 ; 19 return mediaCalculada ; 20 }21 Linha Comentário 11 Há uma chamada à função calculaMedia() e o valor de retorno é atribuído à variaével m. 20 Sinaliza que o valor que será retornado. Podemos passar um vetor como parâmetro para uma função. Veja o exemplo abaixo. Programa imprimevetor.c void imprimeMatriz (float arg[4][4]); 1 2 int main(){ 3 float matriz [4][4] ; 4 int i , j ; 5 6 printf("\nDigite os elementos da matriz\n" ) ; 7 for (i = 0 ; i < 4 ; i++ ){ 8 for (j = 0 ; j < 4 ; j++ ){ 9 scanf ( "%f" ,&matriz [i][j]) ; 10 } 11 } 12 imprimeMatriz (matriz) ; 13 } 14 15 void imprimeMatriz (float arg[4][4]){ 16 int i , j ; 17 18 printf("\nImpressao da matriz\n" ) ; 19for (i = 0 ; i < 4 ; i++ ){ 20 for (j = 0 ; j < 4 ; j++ ){ 21 printf("%.1f\t" ,arg[i][j]); 22 } 23 printf("\n"); 24 } 25 }26 Para finalizar o assunto sobre funções vamos discutir sobre os cuidados a serem tomados com os locais de declaração de variáveis. O escopo de uma variável é a região do programa que ela pode ser referenciada. Essa região tem início na linha onde a variável é declarada e termina com o fim das chaves que finalizam o bloco. Existem 3 lugares em um programa em C onde as variáveis podem ser declaradas e desta forma são classificadas: Algoritmos Prof. Hilton Cardoso Marins Junior Página 41 de 45 1. Fora de todas as funções, inclusive da função main(). A variável assim declarada é chamada de variável global e pode ser usada em qualquer parte do programa. Uma variável global é criada (alocada na memória) quando o programa inicia e é destruída (liberada da memória) quando o programa é finalizado. 2. Dentro de uma função. A variável assim declarada é chamada de variável local e só pode ser usada dentro desta função. Uma variável local é criada quando a função é invocada e destruída quando a função é finalizada. 3. Na lista de parâmetros formais de uma função, para receber os argumentos que são passados para a função. Uma variável declarada como parâmetro formal de uma função é criada quando a função é invocada e destruída quando a função é finalizada. Comporta-se como uma variável local. Agora podemos apresentar a forma geral de um programa em C. declarações das variáveis globais declarações dos protótipos das funções tipo-devolvido main (lista-de-parâmetros){ sequência-de-comandos; } tipo-devolvido f1 (lista-de-parâmetros){ sequência-de-comandos; } tipo-devolvido f2 (lista-de-parâmetros){ sequência-de-comandos; } ... tipo-devolvido fn (lista-de-parâmetros){ sequência-de-comandos; } Observação: f1() até fn() representam as funções definidas pelo usuário. Exercícios 1) Fazer um programa que execute até que o usuário decida encerrar. Na execução, o programa recebe 2 números, o usuário escolhe a operação desejada ( + - * / ) e o programa efetua a operação desejada. Use chamadas de funções para executar as operações. Não permita divisão por zero. 2) Refaça o programa que calcula as raízes de um equação do 2º. grau usando funções. As seguintes funções devem ser criadas e usadas: float calculaDelta(float a, float b, float c): recebe os coeficientes da equação e retorna o valor de delta. Algoritmos Prof. Hilton Cardoso Marins Junior Página 42 de 45 float calculaRaizUm(float a, float b, float delta): recebe os coeficientes a e b da equação, recebe o valor de delta e retorna o valor de uma das raízes da equação. float calculaRaizDois(float a, float b, float delta): recebe os coeficientes a e b da equação, recebe o valor de delta e retorna o valor da outra raíz da equação. 3) Fazer um programa que gere e imprima um vetor com 20 números inteiros. Estes números devem ser aleatórios e gerados pela função int geraInt(int limite). Esta função gera aleatoriamente um número inteiro entre 1 e limite. 4) Faça um programa com um menu contendo as seguintes opções: gera vetor, exibe vetor, acha maior, acha menor, calcula média dos elementos, calcula soma dos elementos, calcula produto dos elementos, sai do programa. 5) Considere que o vetor em questão tenha 5 elementos inteiros para facilitar os testes. Implemente cada opção do menu através da chamada de uma função específica. 6) Codificar uma função que calcule o saldo final de uma aplicação financeira levando em consideração: que haverá um único deposito inicial. que a cada dia o valor aplicado deverá ser atualizado por uma taxa de juros. que o valor permanecerá aplicado por um prazo em dias. A função deverá obrigatoriamente possuir o seguinte protótipo: float aplica(double d, double t, int p); onde: d = valor do depósito inicial t = taxa de juros diária p = prazo em dias da aplicação 7) Codificar um programa capaz de verificar através de uma função, se um número é ou não palíndromo. A função deve receber um número e retornar “verdadeiro” ou “falso”. 8) Faça uma função que verifique se um valor (inteiro) é perfeito ou não. Um valor é dito perfeito quando ele é igual a soma dos seus divisores excetuando ele próprio. (Ex: 6 é perfeito, 6 = 1 + 2 + 3, que são seus divisores). A função deve retornar verdadeiro (1`) ou falso(0). 9) Faça uma função com o seguinte cabeçalho: int calcula(int v1, int v2, char op). Esta função retorna o resultado de uma determinada operação op (+ - / *) entre v1 e v2. 10) Codificar uma função para calcular a quantidade de vogais e consoantes existentes em uma string. 11) Codificar uma função para calcular o e-nésimo termo de uma PA. Não use fórmula. 12) Codificar uma função para calcular o e-nésimo termo de uma PG. Não use fórmula. Algoritmos Prof. Hilton Cardoso Marins Junior Página 43 de 45 13) Codificar uma função para calcular o fatorial de um número. 14) Codificar uma função que receba a pontuação dos 1000 candidatos participantes de um concurso e calcule a quantidade de candidatos aprovados (pontuação acima de 650). Algoritmos Prof. Hilton Cardoso Marins Junior Página 44 de 45 nome_da_variável.nome_do_campo 11. Estruturas de Dados Heterogênea - struct Em situações onde é necessário o armazenamento de dados de tipos diferentes, o vetor não nos atenderá. Necessitaremos de estruturas que armazenam dados de tipos diferentes. Uma estrutura de dados heterogênea é uma coleção de variáveis de tipos diferentes referenciadas por um único nome, permitindo agrupar informações que possuem algum tipo de relação. Primeiro devemos definir a estrutura. Esta ação equivale a definir um modelo a ser usado para criar diversas variáveis (exemplares). A palavra-chave struct indica a definição de uma estrutura. Exemplo de definição de uma estrutura de dados heterogênea de nome dados struct dados{ 1 char nome[30]; 2 char curso[20]; 3 char turma; 4 double nota; 5 }; 6 O trecho de código acima, não declarou nenhuma variável, apenas definiu a forma dos dados. Definimos que nossa estrutura possui o nome dados e que é composta de alguns membros (elementos ou campos). Após a definição da estrutura dados declaramos variáveis desse tipo. Veja o exemplo abaixo. Exemplo de declaração de variáveis struct dados aluno; 1 struct dados professor 2 struct dados funcionario 3 Declaramos 3 variáveis do tipo dados. Para manipular os campos de uma estrutura escrevemos assim: Prática 10: Structs Podemos combinar as estruturas estudadas até o momento, ou seja, podemos ter um vetor onde cada elemento é uma struct ou uma struct onde seus campos são vetores. Veja o exemplo abaixo. Algoritmos Prof. Hilton Cardoso Marins Junior Página 45 de 45 Exemplo de um vetor de struct struct info{ 1 char nome[30]; 2 float nota; 3 }; 4 5 struct info alunos[100]; 6 . 7 . 8 . 9 printf(“Nome: %s”, alunos[5].nome); 10 printf(“Nota..: %f”, alunos[5].nota); 11 Linha Comentário 1 a 4 Definição de uma estrutura chamada info que contém um campo chamado nome (vetor de char) e outro campo chamado nota. 6 Declaração de um vetor de nome alunos com 100 elementos do tipo info. 10 Faz referencia ao elemento de índice 5 do vetor alunos. Como os elementos do vetor são uma struct, complementamos com .nome. 11 Faz referencia ao elemento de índice 5 do vetor alunos. Como os elementos do vetor são uma struct, complementamos com .nota.
Compartilhar