·

Engenharia Civil ·

Outros

Send your question to AI and receive an answer instantly

Ask Question

Preview text

Algoritmos e Linguagem de Programação Prof Dr Edmundo Sérgio Spoto FEITEP 2021 Mantenedora e Diretora Geral Dra Lucinéia de Caires Bressanin Roschildt Vicediretora Nathalia Roschildt Direção Acadêmica Prof Dr Antonio Peixoto de Araujo Neto Algoritmos e Linguagem de Programação Prof Dr Edmundo Sérgio Spoto Maringá PR 2021 4 A reprodução total ou parcial desta publicação somente será permitida com prévia autorização por escrito da FEITEP A FEITEPEAD segue o Acordo Ortográfico da Língua Portuguesa em vigor no Brasil desde 2009 A aceitação das alterações textuais e de normalização bibliográfica sugeridas pelo revisor é uma decisão do autororganizador Revisor Técnico Fábio Splendor Revisora ortográfica e gramatical Silvana Camilo Diagramação projeto gráfico e capa Candida Bitencourt Haesbaert Paruna Editorial Avenida Paranavaí 1164 Zona 06 CEP 87070130 Fone 44 30294500 44 999490688 wwwfeitepedubr Prof Dr Edmundo Sérgio Spoto 2021 Dados Internacionais de Catalogação na Publicação CIP Bibliotecária Nadja Honarra Aranha CRB9 1972 S765a Spoto Edmundo Sérgio Algoritmos e Linguagem de Programação Edmundo Sérgio Spoto Maringá PR FEITEP 2021 198 p il Inclui Referências ISBN 9786599619618 1 Operadores Aritméticos 2 Linguagem C 3 Algoritmo I Spoto Edmundo Sérgio II Título CDD 005133 5 Bemvindos Caroa alunoa A Educação a Distância é uma modalidade de ensino que tomou grandes proporções na última década e por isso desenvolvemos um ensino de excelência para você A proposta dessa modalidade de ensino permite um alcance significativo ampliando a efetividade do direito ao acesso ao Ensino Superior O cenário atual se constitui por aparatos instrumentos e estratégias tecnológicas que re configuram os preceitos da prática tradicional de ensino a partir da mescla entre tecnologia informação e conhecimento Essa tríade marca a identidade de uma era educacional que cria oportunidades de for mação e qualificação por meio da construção do saber científico mediada por princípios in teracionistas No espaço virtual a relação entre professor e aluno se estabelece por meio de estratégias inovadoras e efetivas dentre elas a necessidade e relevância de um material exclusivo que visa a especificidade dessa instituição a formação em engenharias Assim convidamos você a ingressar no universo acadêmico por meio de cada disciplina Desejamos a você acadêmico ótimos estudos Coordenação Nead Fonte Paruna Editorial 6 O Autor Prof Dr Edmundo Sérgio Spoto possui graduação em Engenharia Civil pela Fa culdade de Engenharia de Araraquara 1983 mestrado em Ciências da Compu tação pelo ICMC da Universidade de São Paulo 1988 doutorado em Engenharia Elétrica pela Universidade Estadual de Campinas 2000 e Pós Doutoramento pela Universidade Federal de São Carlos DCUFSCAR em 2018 É professor Instituto de Informática UFG Coordenador do Curso de Especialização em Banco de Dados com Big Data Especialista em Validação Verificação e Teste de Software Tem expe riência na área de Ciência da Computação com ênfase em Engenharia de Softwa re atuando principalmente nos seguintes temas teste de software banco de da dos teste funcional desenvolvimento de software e teste estrutural 7 Sumário Introdução 10 UNIDADE 1 INTRODUÇÃO AO CONCEITO DE ALGORITMO 12 1 Introdução 13 2 O que é um algoritmo e como funciona 15 3 Descrição de Algoritmos gráficos fluxograma 18 4 Os principais benefícios 20 5 Tipos de problemas matemáticos 22 6 Exemplos e resultados 24 UNIDADE 2 TIPOS DE DADOS E OPERAÇÕES PRIMITIVAS 30 1 Introdução 31 2 Tipos de dados primitivos 32 3 Operadores aritméticos 37 4 Operadores Relacionais e Lógicos 40 5 Domínios dos tipos de dados em C 43 6 Expressões Matemáticas com uso dos operadores 45 7 Bibliotecas de operações em C 48 8 Exemplos e problemas 49 UNIDADE 3 ELEMENTOS FUNDAMENTAIS DA PROGRAMAÇÃO 54 1 Introdução 55 2 Divisão das etapas de um programa 58 3 Entrada de dados 60 4 Etapa de resolução do problema 61 5 Saída dos resultados 61 6 Observações importantes 62 8 UNIDADE 4 ESTRUTURAS DE FLUXO DE CONTROLE DAS INFORMAÇÕES 63 1 Introdução 64 2 Comandos de atribuição sequenciais 65 3 Comandos de decisão 68 4 Comandos de múltiplas decisões aninhadas 70 5 Comando Switch case 71 6 Comandos de Repetição 74 61 For 74 62 While 76 63 Do While 78 7 Exercícios 80 74 Valor em notas e moedas 81 75 Notas em conceitos 82 76 Reajuste Salarial83 77 Soma dos 3 menores valores 83 78 Ordem 83 79 Somatório simples 85 710 Companhia de Teatro 85 711 Mínimo Múltiplo Comum 86 712 Série de Taylor seno 87 UNIDADE 5 DADOS ESTRUTURADOS 96 1 Introdução 97 2 Estruturas homogêneas unidimensionais vetor98 3 Estruturas homogêneas bidimensionais matriz 105 4 Uso de estruturas heterogêneas registros 110 5 Uso de arquivos de armazenamentos 113 7 Exercícios 124 71 Exercícios de Vetor 124 72 Exercícios de Matriz 126 73 Exercícios de Tipos de Dados heterogêneos 130 9 UNIDADE 6 FUNÇÕES 147 1 Introdução 148 2 Funções 149 3 Procedimentos 151 4 Funcionalidades de um programa 153 5 Exercícios 155 51 Funções 155 UNIDADE 7 DESENVOLVIMENTO DE ALGORITMOS POR REFINAMENTOS SUCESSIVOS 167 1 Introdução 168 2 Refinamento sucessivo 169 3 Passagens de Parâmetros por valor 174 4 Passagens de Parâmetros por referência 175 5 Exercícios 177 UNIDADE 8 ASPECTOS DE IMPLEMENTAÇÃO DE ALGORITMOS 184 1 Introdução 185 2 Classificação por implementação Término do algoritmo 186 3 Iterativo ou recursivo 188 4 Lógico 190 5 Serial ou Paralelo 193 6 Determinístico ou não determinístico 194 7 Exato ou Aproximado 196 8 Conclusão final 198 10 Introdução Prezados alunos este material didático abrangerá a teoria e a prática de algoritmos de programação de uma forma geral envolvendo a linguagem de programação C e os as pectos principais da programação e da construção do algoritmo de um problema antes de levarmos para uma linguagem de alto nível aqui utilizaremos a linguagem C Um algoritmo nada mais é do que uma sequência de instruções escritas ou desenha das visando atender a solução de uma tarefa ou um problema Tais instruções devem ser bem elaboradas de forma a não deixarem dúvidas ou erros de interpretações e que sem pre levam aos mesmos resultados Se o problema for matemático devemos primeiro de senvolver o raciocínio lógico da construção da equação matemática conforme solicitada na descrição do problema podendo existir um modelo formal de execução ou até mes mo algorítmico que sempre leva ao mesmo resultado Depois de realizado o algoritmo devemos passar para uma escrita em uma linguagem de alto nível para que o computa dor siga o raciocínio construído no algoritmo e apresente as soluções do problemas com as entradas sugeridas pelo mesmo Desta forma este material induzirá a forma de construção de algoritmos sempre que uma nova atividade surja o ideal é podermos no futuro resolver todos tipos de proble mas de forma mais simples e seguindo sempre a construção do algoritmo conforme o mundo real faria O material também apresentará um estudo dos principais aspectos da programação utilizando a linguagem C estudando seus tipos primitivos operadores matemáticos e ló gicos bem como comandos de decisão repetição e outros Também faremos um estudo de tipos de dados homogêneos em C armazenados em estruturas unidimensionais veto res e multidimensionais matrizes bem como criação de tipos de dados heterogêneos registros podendo armazenar nestas mesmas estruturas dadas O uso de arquivos para gravar a informação em disco sempre que houver necessidades 11 Para melhorar a programação serão dadas o uso de modularização com uso de pro cedimentos e funções tratando as passagens de parâmetros das variáveis podendo ser passagem por valor ou por referência conforme a necessidade requerida pelo problema Para encerrar o estudo serão apresentados aspectos de desenvolvimentos de algorit mos e programação utilizados no mundo real com uma visão geral de cada tipo para que possamos classificar quais tipos de programação serão necessárias em determinados pro blemas existentes No final deste material serão colocados diversos problemas para serem estudados pe los estudantes durante o curso Os resultados serão postos posteriormente pelo professor em um local de download Espero que todos tenham um bom aproveitamento deste estudo Obrigado UNIDADE 1 INTRODUÇÃO AO CONCEITO DE ALGORITMO 13 1 Introdução Inicialmente para entendermos o que é um algoritmo vamos supor que temos que explicar os passos de uma tarefa como trocar um pneu de um carro As etapas da descri ção neste caso é primeiro verificar se existe um pneu de reserva Se não existir não pode mos continuar a troca Existindo temos que primeiro tirar o pneu do portamalas ou do local onde ele está colocado em seguida soltar os parafusos da roda danificada depois seguir passo a passo cada etapa que nos leva a efetuar a troca até guardar o pneu danifi cado etc O algoritmo de um problema possui 3 etapas fundamentais para serem observadas inicialmente entender o que o problema solicita realizar em geral ele dá informações que devem ser consideradas na construção do algoritmo em si Principalmente se houver con versões de valores que serão utilizadas e como esses valores devem ser trabalhados no problema Neste caso separaremos as etapas em 1 Entradas de Informações 2 Resolu ção do problemas utilizando as dicas dadas pela descrição do problema esta etapa pode rá requerer vários cuidados pois pode envolver uma análise lógica entre as variáveis que serão envolvidas bem como comandos de repetição ou decisão Em 3 saídas da informa ção seguindo a solicitação do problema Alguns cuidados específicos serão tratados no decorrer de cada Unidade em suas especificidades Então podese dizer que Algoritmo é um conjunto finito de regras que descrevem uma sequência de etapas visando resolver um determinado problema Podese dizer que é uma sequência de raciocínio instruções ou operações visando alcançar uma solução para o problema sendo necessário que os passos sejam finitos e executados sistematica mente até atingir seu objetivo ASCENCIO 2012 Esta descrição pode ser realizada com uma descrição portugol na linguagem portuguesa ou até mesmo na linguagem ingle sa ou por uma representação gráfica fluxograma nas quais as atividades dos algorit mos possuem desenhos que representam as etapas de inicialização comandos de atribui ção comandos aritméticos comandos de decisão entre outros Se tratar de um problema complexo existem técnicas que devem ser observadas que é dividir para conquistar que brar em pequenos problemas simples até alcançar o objetivo de todo problema existen te Essas técnicas serão observadas em unidades mais a frente quando for tratada a mo dularização de um problema 14 Para aprender trabalhar com algoritmos é necessário praticar vários tipos de proble mas da mesma forma que estudamos matemática fazendo exercícios Se apenas estuar mos como fazer pode surgir um problema que exija algo que não foi estudado e termos dificuldades em realizálo A origem do Algoritmo se deu na idade média tratase de uma palavra latinizada de rivada do nome de Al Khowarizmi matemático árabe do século 9 Ele surgiu da necessida de de fazer cálculos sem o auxílio de ábacos dedos e outros recursos Até então a estru tura dos cálculos esteve associada às ferramentas que havia à mão pedras sobre o chão varetas de bambu a calculadora de manivela a régua de cálculo e por fim a calculadora É resultado de técnicas de cálculo que levaram séculos para se desenvolver Também é usa do na computação para prever a solução de um problema antes de levar a solução para uma linguagem de alto nível como C Pascal Java Phyton etc SUGESTÃO DE LEITURA Um livro bom para ser consultado é o livro de Algoritmos teoria e prática Cormen et all 2012 e ASCENCIO 2012 15 2 O que é um algoritmo e como funciona Os algoritmos contribuíram para a evolução tecnológica vista nas últimas décadas e são cada vez mais complexos com o objetivo de entender o comportamento humano na internet em especial nas redes sociais Conhecêlos pode contribuir para melhorar a es tratégia digital de uma empresa Ele antecede a implementação do código bem como ajuda a melhorar o entendimento do problema antes de colocar em prática em uma lin guagem de programação de alto nível O algoritmo descreve uma sequência de raciocínio instruções ou operações que vi sam alcançar um determinado objetivo Um exemplo fácil de entender é quando temos que calcular uma equação do segundo grau na qual o problema entrará com valores de a b e c A equação do 2o Grau é descrita como ax2 bx c 0 O coeficiente a multiplica x2 o coeficiente b é o número que multiplica x e o coeficiente c é um número real Tipos de Algoritmos encontrados na literatura de forma descritiva Receita de execu ção de um problema em passos consecutivos ou como uma descrição de um código em pseudocódigo linguagem natural Existem vários tipos de algoritmos que podem representar o mesmo problema atra vés de descrições de etapas descritivas como uma receita ou um guia de execução para elaborar uma determinada tarefa No exemplo da Equação do 2o grau pode se descrever no formato de receita descrevendo as etapas passo a passo conforme segue abaixo Passo 1 Leia os valores de a b c sendo números reais podendo ser números com casas decimais O valor de a não pode ser 0 senão não será uma equação do 2o Grau Passo 2 Calcular o valor do Delta tendo em vista que a formula para calcular os valo res das raízes é dada pela Figura 1 Onde a equação dentro da raiz quadrada é denomina da de Delta a qual determina se haverá 2 raízes 1 raiz ou nenhuma raiz Delta b2 4ac Passo 3 Se Delta for 0 existirão 2 raízes X1 b sqrtdelta 2a e X2 b sqrtdelta 2a Passo 4 Se Delta 0 existirá apenas 1 raíz X b 2a 16 Figura 1 Cálculo das raízes da equação do 2º Grau Passo 5 Se Delta 0 como não existe raiz quadrada de valor negativo não existe raiz no mundo real Passo 6 Exibir o Resultado final Imprimir o valor das raízes caso houver ou uma men sagem que não existe raiz no mundo real E finalizar o algoritmo Após analisarmos o algoritmos acima iniciase a preparação do programa em uma lin guagem de alto nível ainda não falado neste material mas em breve mostraremos a mon tagem do código para a resolução de cálculo das raízes de uma equação do 2o grau Existe ainda um tipo de algoritmo que pode ser descrito com um pseudocódigo re presentação de um código mas em linguagem natural no caso utilizaremos a linguagem em português No Exemplo dado do cálculo da equação do 2o grau faremos um algorit mo em pseudocódigo Na época da programação estruturada a qual iniciávamos com o projeto baseado em fluxo de dados DFD no final do projeto eram gerados os pseudos códigos de cada funcionalidade visando deixar preparado para passar para codificação posteriormente Na representação do pseudocódigo temos algumas palavraschave que agem pró ximas aos comandos padrões existentes nas linguagens de programação Vamos mostrar um exemplo de um algoritmo em pseudocódigo para o mesmo problema da Equação do 2o Grau conforme apresentado na Figura 2 Figura 2 Exemplo de um algoritmo em pseudo código Algoritmo de cálculo da equação do 2o Grau Autor Edmundo Sérgio Spoto Data 16set2021 var a b c delta x1 x2 reais inicio escrevaa leiaa escrevab leiab 17 escrevac leiac delta bb 4ac se delta 0 então escrevaDelta delta escrevaNao existe reizes reais senão se delta 0 então x1 b2a escrevaDelta delta escrevax1 x2 x162 senão x1 b raizqdelta2a x2 b raizqdelta2a escrevaDelta delta escrevax1 x162 escrevax2 x262 fimse fimse fimalgoritmo Observe que o algoritmo em pseudocódigo é uma fase anterior a codificação é uma preparação da organização para se iniciar a programação numa linguagem de alto nível O terceiro tipo de algoritmo é mediante figuras geométricas que pode ser representa do todas instruções de um problema através de um fluxograma 18 3 Descrição de Algoritmos gráficos fluxograma A representação de um algoritmo também pode ser feita através de um fluxograma que são desenhos que possuem figuras que representam os tipos de instrução capturadas na interpretação do problema Para interpretar um fluxograma temos que primeiro enten der as formas de cada figura e seus significados A ideia básica desta forma de representação dos algoritmos é empregar figuras geo métricas na representação de cada instrução ou passo que compõe o algoritmo Existe um conjunto específico de símbolos empregados na elaboração dos fluxogramas Estes símbolos são definidos pela norma ISO 5807 ISO International Organization for Standar dization Apresentamse na Figura 3 como os mais importantes Figura 2 Representação de um fluxograma Terminal Indica o INICIO ou o FIM de um processamento Exemplo Inicio do Algoritmo Fluxo de Dados Indica o Sentido do fluxo de dados Conecta os demais Simbolos Processamento Processamento em Geral Exemplo Cálculo de 2 números ExibirSaída Mostra Informações ou Resultados Impressão de dados Exemplo exibe o resultado de um cálculo Decisão Permite Elaborar processos de Decisão Uso de um comando de decisão se verdadeiro ou se falso Entrada Manual Indica entrada de dados via teclado Exemplo digitar as notas da prova Desvio conector Permite um desvio para um ponto qualquer do programa Ele é numerado e mostra onde parou e depois onde continuar Entrada e Saída Genérica Operação de entrada e saída de dados Exemplo gravar ou ler de um arquivo texto ou binário Conector de Página Permite informar de qual página vem o fluxograma quando ele é muito extenso Fonte httpswwwdevmediacombrfluxogramasdiagramadeblocosedechapinno desenvolvimentodealgoritmos28550 19 O fluxograma é muito utilizado na engenharia como uma forma de representar os pas sos de um algoritmo de qualquer tipo de execução de problemas também podendo ser usado para a computação Existem réguas específicas que facilitam a confecção de um flu xograma com as figuras que representam as tapas do fluxograma No exemplo do cálcu lo da equação do 2o grau ficaria conforme a Figura 4 Figura 4 Representação de um fluxograma da equação do 2o grau sim nao 0 0 Delta b24AC Inicio Ler A B C A 0 A equação não é do 2º Grau Fim Delta 0 Não Existem Raízes Reais Fim X1 B 𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷 2A X2 B 𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷 2A X1 e X2 X1X2 B 2A X1 e X2 Fim Fim exemplo do Prof José Gonçalves Cruz UFSCAR Depois de verificado com um caso de teste iniciase a implementação do código vi sando escrever o programa em uma linguagem de alto nível para o computador lingua gem C Um caso de teste é supor uma entrada para a b e c e verificar seu resultado final e se o fluxo exerce sua execução de maneira correta 20 4 Os principais benefícios A evolução e aprimoramento dos algoritmos nas últimas décadas contribuíram tam bém com a melhoria dos comandos e uma evolução natural das linguagens de progra mação Um grande benefício de escrever primeiro um algoritmo para a resolução de um ou vários problemas é uma maneira de documentar as principais funcionalidades de um programa a ser construído A programação baseada em Objetos por exemplo teve uma grande evolução a partir da década de 90 com o surgimento da UML Linguagem de mo delagem Unificada que são diagramas de projetos bem definidos que evoluem desde a fase de análise de projeto a ser construído até sua criação do diagrama de classes Existem ferramentas de desenvolvimento de projetos que ajudam muito na sua confecção Da mesma forma todo algoritmo contribui em realizar uma análise antes de colocar no com putador o seu código evitando que algo falhe durante a sua execução Nos casos dos algoritmos conforme apresentados anteriormente é importante en tender e compreender os conceitos relacionados a eles durante sua criação focando prin cipalmente nas entradas de dados os tipos que serão adotados para as variáveis bem como estabelecer uma forma de conversão entre as variáveis quando esta exigir uma con versão de valores por exemplo entra em quilometro e deve ser convertida para metros e ajustando assim todos os parâmetros necessários para o seu melhor funcionamento Bem como é importante saber como as saídas dos resultados devem ser apresentados aos usuários adotando uma informação coerente com o esperado por eles Alguns algoritmos também podem ter a necessidade de filtrar os seus resultados para diferentes tipos de usuários essa característica pode exigir diferentes tipos de funções vi sando atender diferentes níveis de usuários e isso pode contribuir para se pensar em suas execuções ainda na etapa de algoritmo para depois levar para a codificação entre ou tras formas de segurança da informação que poderão existir em diferentes tipos de algo ritmos Existem algoritmos que são complexos e precisam ter estratégias de modularização de suas funcionalidades criandose etapas construtivas para se atingir um determinado ob jetivo exigido pelo problema Desta forma o algoritmo pode contribuir para preparar as funcionalidades principais em etapas que se tornem bem mais fácil seu desenvolvimento 21 depois interligar essas funcionalidades para montar o algoritmo todo esse benefício po derá facilitar muito e evitar retrabalhos futuros Quando trabalhamos com uma estrutura estática ou dinâmica em uma implementação é fundamental termos suas inicializações etapas de leituras depois etapas de consultas etapas de exibição de resultados etapas de realização de alguma alteração e assim por diante pois a construção do algoritmo ajuda a quebrar cada etapa dessa em um pequeno algoritmo procedimento isolado o qual torna o entendimento mais fácil alcançando o objeto que no seu início era complexo Todo problema a ser resolvido pode envolver outras tecnologias exemplo banco de dados gerador de imagens etc que serão observadas durante a construção dos algorit mos e tais tecnologias podem ser acopladas como uma caixa preta inicialmente e poste riormente serão também desenvolvidos e resolvidos para se ajustar ao desenvolvimento do programa como um todo Existem vários tipos de algoritmos que podem ser comprados como um serviço de uma necessidade que serão usadas no futuro em nosso programa por exemplo carrinho de compra pagamentos por cartão segurança de redes entre outros Esses não serão co mentados neste curso pois o objetivo deste é ajudar o estudante a construir seu próprio algoritmo e posteriormente sua programação Agora que já sabemos o que é um algoritmos podemos dizer que os principais bene fícios é ajudar na mediação para quem ele se destina e como deve ser realizado seu uso Cada usuário pode ter críticas diferentes de um mesmo algoritmo pois é natural ter usuá rios que gostam mais de teclas de atalho outros de ler todas informações e outros que possuem suas próprias formas de trabalhar Podese também analisar com detalhes todas exigências levantadas antes de sua construção Dizem que muitos erros podem ser corri gidos ainda em fase de análise do algoritmo e não deixar para serem verificadas posterior mente para após sua implementação Outro benefício importante é entender quais tipos de comandos poderão ser utiliza dos para a execução de um determinado laço ou de várias decisões Na etapa de algorit mo é importante levantar se pode ser utilizado recursividade ou iteratividade antes de pôr em prática Alguns perigos hoje levantados por muitas empresas é que existe pouca von tade de se desenvolver algoritmos que preceda a implementação e muitas empresas de desenvolvimento no mercado partem para a implementação do código com poucas aná lises ou quase nenhuma dos algoritmos realizados 22 5 Tipos de problemas matemáticos Existem muitos desenvolvedores que possuem um modelo de algoritmos sempre que for desenvolver um problema matemático É muito comum que isso aconteça dado sua experiência e sua percepção do domínio do conteúdo para se desenvolver Outros já uti lizam mais os comandos e trechos de execuções explorando suas habilidades de progra mação e pouca de uso de formalismos para resolver seus problemas matemáticos Pode se dizer inicialmente que os principais cuidados que temos que ter são a Ler o enunciado Leia atentamente o enunciado do problema quantas vezes for necessário até compreender todas suas informações passadas b Coletas de Dados Anote todas informações relevantes do problema bem como todas equações e adaptações que deverão ocorrer da questão a ser resolvida c Defina um procedimento depois de ter compreendido o problema e já ter cole tado os dados defina um procedimento de sua execução podendo quebrar as equações muito complexas em partes se for necessário ou a sequência que elas devem ser resolvidas até obtenção do resultado final d Resolução do problema objeto aqui é momento de resolução do problema e validação de seu resultado observando as aproximações exigidas etc e Busque problemas similares Encontre problemas parecidos e verifique se a es tratégia utilizada se aplica para esses problemas f Gere etapas de execução se houver necessidade podese gerar etapas de exe cução ou criação de funções e pequenos procedimentos que podem facilitar a melhorar o entendimento de sua execução e obtenção da solução Em geral isso é necessário quando se tratar de problemas complexos e que envolvam vários tipos de formulas difíceis g Elabore as saídas das informações todo resultado pode ter um formato especí fico levantado pelos usuários ou proprietários do problema de como eles pre tender obter tais informações resultantes Procure criar saídas mais próximas do mundo real solicitado assim oberemos mais sucessos com os usuários 23 Alguns cuidados ainda com as expressões matemáticas em linguagem C por exem plo que existem operações simples entre variáveis inteiras que retornam apenas resulta dos inteiros por exemplo A 103 resultará em um valor inteiro 3 e o esperado seria que seu resultado fosse um valor real com duas casas decimais Esses problemas iremos abor dar na linguagem C quando forem trabalhados os tipos primitivos de variáveis Nos algo ritmos temos apenas que apontar tais necessidades para alertar o programador a arrumar tais problemas Outras informações que não são pertinentes levantar nos algoritmos quando traba lharmos com expressões matemáticas é a necessidade do uso ou não da biblioteca de operações matemática em C mathh Porém o programador tem que saber quando exis te ou não a necessidade de colocar esta biblioteca Vamos listar alguns problemas a serem gerados algoritmos e posteriormente um programa computacional que possa ser resolvido na Linguagem de Programação C Nesta Unidade somente serão desenvolvidos os algoritmos mais para frente faremos o uso destes algoritmos para a geração do código para a solução computacional P1 Consumo de energia grau de dificuldade 1 Sabendose que 100 kW de energia custam 70 do salário mínimo escreva um algoritmo que leia o valor do salário mínimo e a quantidade de kW gasta por uma residência Calcule e imprima o valor em reais de cada kW o valor em reais a ser pago pelo consumo da residência o novo valor a ser pago pela residência com um desconto de 10 Entrada O programa deve ler o valor do salário mínimo e a quantidade de kW gasta por uma residência Ambos os valores são reais Saída O programa deve imprimir três linhas contendo o texto Custo por kW R xxx Custo do consumo R xxx Custo com desconto R xxx Caso de Teste Entrada 81 354 Saída Custo por kW R 057 Custo do consumo R 201 Custo com desconto R 181 P2 Custo da Lata de Cerveja dificuldade 1 Um fabricante de latas deseja desenvolver um programa para calcular o custo de uma lata cilíndrica de alumínio sabendose que o custo do alumínio por m² é R 10000 Entrada O programa deve ler dois valores na entrada o raio e a altura da lata Ambos os valores correspondem a valores em metros Cada valor ocorre em uma linha diferente na entrada Saída O programa deve imprimir a frase O VALOR DO CUSTO E XXXXX onde XXXXX é o valor do custo da lata Logo após o valor do custo da lata o programa deve imprimir o carácter de quebra de linha Observações O seu programa deve utilizar a constante π com o valor aproximado de 314159 O valor total da área de um cilindro é dada por A t 2 A c A l onde A c é a área do círculo calculada como A c πr² e A l é a área lateral do cilindro computada por A l 2πrh onde r é o raio e a altura da lata em metros Caso de teste Entrada 002 009 Saída O VALOR DO CUSTO E 138 26 Após o valor do determinante o algoritmo deve fazer o cursor avançar para a próxi ma linha Observações Dada uma matriz quadrada bidimensional M o determinante de M detM é definido por detM ad bc M a b c d Caso de teste Entrada 4 3 5 4 Saída O VALOR DO DETERMINANTE E 100 P4 Decolagem de um avião dificuldade 2 Escrever um algoritmo que leia a massa em toneladas de um avião sua aceleração ms 2 e o tempo s que levou do repouso até a decolagem O algoritmo deve calcular e escrever a velocidade atingida Kmh o comprimento da pista m e o trabalho mecânico realizado J no momento da decolagem Dicas v velocidade a aceleração t tempo 1 ms 36 Km h m massa v a t s espaço percorrido s at22 W trabalho mecânico realizado W mv2 2 Utilize valores do tipo double deve ser lido com lf A massa utilizada no trabalho é em Kg Entrada O algoritmo deve ler três linhas de entrada A primeira linha contém um valor do tipo double representando a massa do avião em toneladas A segunda linha contém um valor do tipo double correspondente à aceleração de avião A terceira linha contém um valor do tipo double correspondente ao tempo em segundos gasto na decolagem 27 Saída O Algoritmo deve escrever três linhas A primeira contém a frase VELOCIDADE x onde x é o valor da velocidade do avião em Kmh A segunda contém a frase ESPACO PERCORRIDO y onde y corresponde ao espaço em metros percorrido pelo avião duran te a decolagem A terceira linha contém a frase TRABALHO REALIZADO z onde z corres ponde ao valor do trabalho em Joules realizado pelo avião durante a decolagem Os valo res de x y e z devem ser do tipo double e devem conter duas casas decimais e após esses valores deve vir o caractere de quebra de linha movendo o cursor para a próxima linha Soluções S1 Algoritmo do Calculo de consumo de Energia Algoritmo do calculo do Consumo de energia Autor Edmundo S Spoto Data 16092021 var salmin qtdkw custokwhreal inicio escrevasalario minimo leiasalmin escrevaQuantidade em Kw leiaqtdkw custoKwHsalmin07100 escrevaCusto por kW R custoKwH62 escrevaCusto do consumo R custoKwHqtdkw62 escrevaCusto com desconto R custoKwHqtdkw962 fimalgoritmo 28 S2 Algoritmo do calulo do custo da lata de cerveja Algoritmo do calculo de latas de cerveja autor Edmundo S Spoto Data 16092021 Contante PI314159 var r areal var custo real inicio escrevaRaio da lata leiar escrevaAltura da lata leiaa custo 100 2PIrr 2PIra escrevaO VALOR DO CUSTO E custo62 fimalgoritmo S3 Algoritmo do Calculo de Determinante de matriz quadrada Algoritmo que calcula o determinante de uma matriz de ordem 2x2 Autor Edmundo S Spoto Data 16092021 var a b c d inteiro var detreal inicio escrevaa leiaa escrevab leiab escrevac leiac escrevad leiad det ad bc escrevaO VALOR DO DETERMINANTE E det62 fimalgoritmo 29 S4 Algoritmo de Decolagem de um Avião Algoritmo em pseudo código para resolver o problema D decolagem de um avião Autor Edmundo S Spoto Data 16set2021 var massa a t velocidade trabalhoespacoDouble inicio entrada de dados escrevaMassa leiamassa escrevaAceleracao leiaa escrevaTempo leiat Calculo da velocidade velocidade at escrevaVELOCIDADE velocidade3662 transformação de ms para kmh espacoatt20 calculo do espaço percorrido para a decolagem escrevaESPACO PERCORRIDO espaco62 trabalhomassa1000velocidadevelocidade20 calculo do trabalho em jaule escrevaTRABALHO REALIZADO trabalho62 escrita do trabalho com 2 casas decimais fimalgoritmo UNIDADE 2 TIPOS DE DADOS E OPERAÇÕES PRIMITIVAS 31 1 Introdução Nesta sessão estudaremos os tipos de dados primitivos em C bem como os opera dores matemáticos e lógicos e iniciaremos nossos estudos de programação na Lingua gem C A linguagem C nasceu na década de 70 Seu inventor Dennis Ritchie imple mentouo pela primeira vez usando um DEC PDP11 rodando o sistema operacional UNIX O C é derivado de uma outra linguagem o B criado por Ken Thompson O B por sua vez veio da linguagem BCPL inventada por Martin Richards O C é uma linguagem de programação genérica que é utilizada para a criação de programas diversos como processadores de texto planilhas eletrônicas sistemas ope racionais programas de comunicação programas para a automação industrial geren ciadores de bancos de dados programas de projeto assistido por computador progra mas para a solução de problemas da Engenharia Física Química e outras Ciências etc O Linux Sistema Operacional muito utilizado foi todo construído pela linguagem C Utilizaremos a estrutura do ANSI C que é o padrão da Linguagem C As bibliotecas uti lizadas pelos compiladores são diferentes em Sistemas Operacionais distintos por isso sempre que migrar a linguagem de um ambiente para outro é necessário recompilar o programa Quando não houver equivalentes para as funções em outros sistemas apre sentaremos formas alternativas de uso dos comandos Para o aprimoramento do uso da linguagem C é importante que o estudante use o máximo de tempo para fazer os exercícios problemas que serão postados neste ma terial Só assim o conhecimento e a habilidade na programação em C será melhorada com o tempo SUGESTÃO DE LEITURA Herbert Schildt C Completo e Total Ed Person 3a Edição 1997 Para estudos da Linguagem C 32 2 Tipos de dados primitivos Todo programa deve conter variáveis que vão conduzir a informação os valores de entrada bem como controlar os cálculos e operações que forem necessárias Para isso tais variáveis devem receber um tipo de dado para tornar seus resultados mais apropria do com as necessidades do problema A Linguagem C possue 5 tipos de dados primitivo conforme mostra a Tabela 1 A Linguagem C é case sensitiva se você chamar uma variá vel de A e quiser utilizar outra variável a serão diferentes Isto significa que letras maiús cula e minúsculas são diferentes Evite de usar nomes de variáveis com palavras reservadas como if else do while for end switch case goto entre outras que compões os coman dos da linguagem Tabela 1 Tipos primitivos em C Palavra Chave Tipo char caracter int inteiro float real precisão simples double real precisão dupla void vazio sem valor O padrão ANSI C determina somente um intervalo de valores mínimo para cada tipo de dado Modificadores de Tipos Com exceção de void os outros tipos de dados primitivos podem ter modificadores Os modificadores alteram o tamanho do tipo de dado ou sua forma de representação Sua utilização faz com que seja possível adequarse melhor às necessidades de armazenamen to de dados em determinados casos Veja quais são os modificadores na Tabela 2 Tabela 2 Tipos de dados e modificadores Palavra Chave Tipo signed caracter unsigned inteiro long longo short curto 33 Tabela 3 Tipos de dados e seus domínios de valores e número de bytes usados Palavra chave Tipo bytes Intervalo char Caracter 1 128 a 127 signed char Caractere com sinal 1 128 a 127 unsigned char Caractere sem sinal 1 0 a 255 int Inteiro 2 32768 a 32767 signed int Inteiro com sinal 2 32768 a 32767 unsigned int Inteiro sem sinal 2 0 a 65535 short int Inteiro curto 2 32768 a 32 767 signed short int Inteiro curto com sinal 2 32768 a 32767 unsigned short int Inteiro curto sem sinal 2 0 a 65535 long int Inteiro long 4 2147483648 a 2147483647 signed long int Inteiro longo com sinal 4 2147483648 a 2147483647 unsigned long int Inteiro longo sem sinal 4 0 a 4294967295 float Ponto flutuante com precisão simples 4 34 E38 a 34E38 double Ponto flutuante com precisão simples 8 17 E308 a 17E308 long double Ponto flutuante com precisão dupla longo 16 34E4932 a 11E4932 Todo programa em C deve conter uma função main que é denominado de função principal por onde o programa inicia e termina Pode haver outras funções e procedimen tos para compor seu programa quando houver necessidade Existem várias bibliotecas que são fundamentais para facilitar nossas operações como biblioteca de entrada e saí da stdioh biblioteca que tratam operações matemáticas mathh biblioteca de opera ções para strings stringh biblioteca de funções e operadores básicos stdlibh que de vem ser estudadas em separadas para ter um melhor aproveitamento de suas funções e atribuições Para gerar as operações de entrada e saída utilizaremos a biblioteca stdioh através das funções scanf e printf que serão utilizadas para manipular as informações de entra da e saída Todo tipo de variável devem utilizar uma diretiva que está apresentada na Ta bela 4 34 Tabela 4 Diretivas de manipulação de tipos de dados na leitura e gravação Identificador Significado d Inteiro decimal c Caractere simples f Real simples decimal s Cadeia de caractere string e Ponto flutuante notação exponencial g Usa o f ou o e mais curto ld Inteiro longo long lf Real longo double u Inteiro decimal sem sinal o Inteiro Octal sem sinal x Inteiro hexadecimal sem sinal i Usado para inteiro independente se a base é decimal octal ou hexadecimal Quando pretende imprimir A função de escrita contida na biblioteca stdioh é utilizada o printf que pode ser usado para escrever uma frase e no final deve ter um comando de mudança de linha ou se quiser tabular alguma saída entre outros que são apresentados na Tabela 5 Tabela 5 Constantes de barras invertidas comando significado b Retrocesso back f Alimentação de formulário form feed Nova linha new line Tabulação horizontal tab Aspas Apóstofro 0 Nulo 0 em decimal Barra invertida v Tabulação vertical a Sinal sonoro beep N Constante octal N é o valor da constante xN Constante hexadecimal N é o valor da constante 35 Todo programa em C tem uma estrutura conforme mostraremos na Figura 21 inician do com as bibliotecas no formato include stdioh que pede para incluir no programa a biblioteca de entrada e saída Todas bibliotecas que forem utilizadas devem estar nas pri meiras linhas do programa antecedendo todas as demais estruturas de código Vamos fa zer uma equação que é entrar com 3 variáveis inteiras e gerar um resultado em ponto flu tuantes com 2 casas decimais sendo resultado abacPI sendo que PI será um valor constante de 3141516 include stdioh biblioteca de entrada e saída define PI 3141516 valor de PI a ser adotado na equação int main int a b c float resultado printfEntre com os valores de a b e c scanfd d dabc observe que para colocar o valor na memória é preciso passar o endereço da variável resultado floatab toda divisão entre dois inteiros retorna inteiro para isso utilizaremos um cast float para forçar durante a operação que a se transforme em float para retornar float resultado resultadofloatac resultado resultadoPI printfO resultado da operacao e 2f resultado return 0 Figura 21 Programa que executa operações de inteiro resultando em float Observe duas coisas para ler variáveis de tipo simples devemos usar o endereço re presentado pelo comando e comercial antes de cada variável lida na função scanf A outra coisa a se observar foi o uso do cast que é muitas vezes utilizado em operações e comandos que devemos forçar a transformação de um resultado durante a execução A divisão entre dois tipos inteiros ab resultaria em um valor inteiro tipo 103 resultaria em 3 Para fazer com que o resultado da operação não perca os valores nas casas decimais de vemos usar então o cast float antes da operação Lógico que quando a operação é com número basta usar 1003 que já iria retornar 333 mas por se tratar de variáveis foi neces sário o uso do cast floatab o mesmo entre floatac 36 Toda impressão de informações realizadas pelo print é necessário colocar no final da frase ou depois das diretivas de valores um para que após a escrita na tela o cursor mude de linha faça isso sempre que necessário Podese criar também um enumerador uma enumeração é útil quando se deseja uti lizar um conjunto determinado de valores que podem estar associados a uma variável Quando tentase atribuir a uma variável de um tipo enumeração um valor que não faz parte da própria enumeração o compilador emite uma mensagem de erro Uma declara ção de variável de um tipo enumeração consiste da palavra reservada enum seguida de uma lista de identificadores entre chaves e seguido finalmente pelo nome da variável Por exemplo enum AZUL VERMELHO BRANCO PRETO cor Declara a variável cor como sendo do tipo enumeração que consiste dos valores cons tantes AZUL VERMELHO BRANCO e PRETO estes são os únicos valores que a variável cor pode assumir Outro exemplo dias da semana como enum SEGUNDA TERCA QUARTA QUINTA SEXTA dsem Declara a variável dsem como sendo do tipo enumeração que consiste dos valores constantes dos dias da semana postado entre as Evite de usar nomes com acento ou Ç ou outros tipos que podem dar erros na compi lação Mesmo na escrita de alguma frase não utilize acentuação SUGESTÃO DE LEITURA Stroustrup J A Tour of C2a Edição Addison Wesley Edition 2008 É um livro que apresenta as principais peculiaridades da linguagem C dentro de C Stroustrup é o precursor da linguagem C seus livros são bem didáticos e importante para quem pretende seguir na programação em CC 37 3 Operadores aritméticos Os operadores aritméticos são usados para desenvolver operações matemáticas Na Tabela 6 é apresentada a lista dos operadores aritméticos do C Tabela 6 Operadores aritméticos em C Operadores Ação Soma inteira e ponto flutuante Subtração ou troca de sinal unário Multiplicação inteira e ponto flutuante Divisão inteira e ponto flutuante Resto de divisão de inteiros Incremento inteiro e ponto flutuante Decremento inteiro e ponto flutuante O C possui operadores unários e binários Os unários agem sobre uma variável apenas modificando ou não o seu valor e retornam o valor final da variável Os binários usam duas variáveis e retornam um terceiro valor sem alterar as variáveis originais A soma é um ope rador binário pois pega duas variáveis soma seus valores sem alterar as variáveis e retor na esta soma Outros operadores binários são os operadores subtração e O ope rador como troca de sinal é um operador unário que não altera a variável sobre a qual é aplicado pois ele retorna o valor da variável multiplicado por 1 O operador divisão quando aplicado a variáveis inteiras nos fornece o resultado da divisão inteira quando aplicado a variáveis em ponto flutuante nos fornece o resultado da divisão real O opera dor fornece o resto da divisão de dois inteiros Assim seja o seguinte trecho de código int a 17 b 3 int x y float z 17 z1 z2 x a b y a b z1 z b z2 ab 38 Ao final da execução destas linhas os valores calculados seriam x 5 y 2 z1 5666666 e z2 50 Note que na linha correspondente a z2 primeiramente é feita uma di visão inteira pois os dois operandos são inteiros Somente após efetuada a divisão é que o resultado é atribuído a uma variável float Os operadores de incremento e decremento são unários que alteram a variável sobre a qual estão aplicados O que eles fazem é incre mentar ou decrementar a variável sobre a qual estão aplicados de 1 Então x x são equivalentes a xx1 xx1 Estes operadores podem ser préfixados ou pós fixados A diferença é que quando são préfixados eles incrementam e retornam o valor da variável já incrementada Quando são pósfixados eles retornam o valor da variável sem o incremento e depois incrementam a variável Então em x23 yx teremos no final y23 e x24 Em x23 yx teremos no final y24 e x24 Uma curiosidade a linguagem de programação C tem este nome pois ela seria um incremento da linguagem C padrão A linguagem C é igual a linguagem C só que com extensões que permitem a programação orientada a objeto o que é um recurso extra O operador de atribuição do C é o O que ele faz é pe gar o valor à direita e atribuir à variável da esquerda Além disto ele retorna o valor que ele atribuiu Isto faz com que as seguintes expressões sejam válidas xyz15 Expressao 1 if kw Expressao 2 39 A expressão 1 é válida pois quando fazemos z15 ela retorna 15 que é passado adian te fazendo y 15 e posteriormente x 15 A expressão 2 será verdadeira se w for diferen te de zero pois este será o valor retornado por kw Pense bem antes de usar a expressão dois pois ela pode gerar erros de interpretação Você não está comparando k e w Você está atribuindo o valor de w a k e usando este valor para tomar a decisão Para verificar se você entendeu dessas atribuições e incrementos pré e pós interprete o resultado da sequência de operações a seguir int xyz xy10 zx xx y xxyz Qual seriam os valores de x y e z no final Inicialmente x 10 y10 Na operação zx o valor de z11 e x11 Na operação x x o valor de x 11 A operação y y11 No final na operação xxyz x assumi rá o valor x11 y11 e z10 Outras operações abreviadas existentes em C e C são int x y z x y é o mesmo que x xy x z é o mesmo que x xz z yx é o mesmo que z zyx x z é o mesmo que x xz operação que retorna o resto da divisão entre x e z Com esses operadores matemáticos podemos elaborar algoritmos e programas que com expressões matemáticas em problemas do mundo real No final desta Unidade apre sentaremos vários exercícios com expressões matemáticas nas quais iremos exercitar nos so conhecimento matemático que é muito importante na programação em C SUGESTÃO DE LEITURA Stroustrup J A Tour of C2a Edição Addison Wesley Edition 2008 e BRASIL Reyolando M L R F BLTHAZAR José Manoel GÓIS Wesley Métodos numéricos e computacionais na prática de engenharias e ciências São Paulo Blucher 2015 40 4 Operadores Relacionais e Lógicos Os operadores relacionais do C realizam comparações entre variáveis São apresenta dos na Tabela 7 Tabela 7 Relação de operadores Relacionais em C Operador Ação Maior do que Maior ou Igual a Menor do que Menor ou Igual a Igual a Diferente Os operadores relacionais retornam verdadeiro 1 ou falso 0 Uma forma de verificar o uso dos operadores relacionais é entender que seus usos devem estar em comandos de decisão ou laços que serão vistos em Unidade mais à frente Faremos um exemplo no qual a operação será colocada nos comandos de escrita nos quais serão impressos 1 se for verdadeiro ou 0 se for falsa include stdioh int main int xyz printf Entre com os valores de X Y Z scanfd d dxyz printf dd resultado d xyxy printf dd resultado d xyxy printf dd resultado d xyxy printf dd resultado d xzxz printf dd resultado d xyxz printf dd resultado d xyxz printf dd resultado d yzyz printf dd resultado d yzyz printf dd resultado d yzyz return 0 41 Podese observar que o resultado dos operadores relacionais é sempre igual a 0 falso ou 1 verdadeiro Para fazer operações com valores lógicos verdadeiro e falso temos os operadores lógicos mostrados na Tabela 8 Tabela 8 Operadores Lógicos em C Operador Ação And E OR OU Not NÃO Usando os operadores relacionais e lógicos podemos realizar uma grande quantidade de testes Na Tabela 9 é apresentada uma tabela verdade entre as combinações dos ope radores e quais resultados se alcançam Tabela 9 Tabela Verdade entre os operadores Lógicos em C P Q P ou Q P E Q F F F F F V V F V F V F V V V V Para ilustrar o uso dos operadores lógicos vamos criar um programa no qual entrare mos com dois valores de A e B podendo ser 0 falto ou 1 verdadeiro Como ainda não entramos em comando de decisão faremos no ato da escrita de valores include stdioh int main int A B printfinforme dois nmeroscada um sendo 0 ou 1 scanfdd A B printfd AND d resultado d A B A B printfd OR d resultado d A B A B printfNOT d resultado d A A return 0 Também existem operadores lógicos denominados de bit a bit A Linguagem C per mite que se faça operações logicas bitabit em números Ou seja neste caso um núme ro é representado por sua forma binária e as operações são feitas em cada bit dele Imagi ne um número inteiro de 16 bits a variável i armazena o valor 2 A representação binaria 42 de i será 0000000000000010 contendo 16 dígitos sento 14 zeros a esquerda seguido de 1 e 0 Podese fazer operações em cada um dos bits deste número Por exemplo se fizer mos a negação do número operação binária NOT ou operador binário em C isto é i o número se transformará em 1111111111111101 As operações binárias ajudam progra madores que queiram trabalhar com o computador em baixo nível As operações lógicas bit a bit só podem ser usadas nos tipos char int e long int Os operadores são Tabela 10 Operadores lógicos bit a bit Operador Ação AND OR XOR ou exclusivo NOT Deslocamento de bits a direita Deslocamento de bits a esquerda Os operadores e são as operações lógicas bit a bit Para se utilizar os desloca mentos devemos fazer valorvaloraserdeslocadoadireita valorvaloraserdeslocadoaesquerda O valor a ser deslocado a direita indica o quanto cada bit será deslocado Por exemplo para a variável i anterior armazenando o número 2 i 3 lembrando que i vale 000000000000010 i terá a representação binária no valor 0000000000010000 isto significa que o valor ar mazenado em i passa a ser igual a 16 Em nossas programações poderá ser útil quando formos trabalhar com valores em bi nário e tivermos a necessidade de operar com esses operadores 43 5 Domínios dos tipos de dados em C Antes de prosseguirmos é importante alertar sobre os domínios que cada tipo traba lha e sempre tomarmos cuidados com o estouro desses domínios Conforme foi visto na Tabela 3 os intervalos que representam o campo de domínio em que cada tipo de da dos trabalha facilitará para nossas operações matemáticas quando necessários Para isso quando houver necessidade de um resultado aumentar a capacidade de domínio de seu resultado podemos utilizar tipos maiores conforme visto Algumas transformações de tipos para tipos também é importante ter a preocupação sempre que houver essa necessidade e ver quais tipos poderemos ter menos perdas pos síveis ao fazer uma adaptação em casos de programas que envolvam banco de dados ou valores já pré estabelecidos no mercado O que acontecerá se usarmos um valor muito grande em uma variável inteira O com pilador C poderá nem dar um alerta durante a compilação porém o erro do valor surgirá no resultado saindo um valor não esperado O programa a seguir induzirá que um resultado onde estoura o domínio da variável c A operação é c aabb sendo a 1000 e b5000 include stdioh int main int a1000 b5000 c c aabb printfResultado da operacao d c return 0 Resultado da operação 1004630016 Observe que o valor do resultado deu negativo o que indica que estourou o limite máximo da variável c que é inteira e vai até 232 1 Que dá 32767 A operação acima deviria dar 25000000000000 Neste caso o tipo que poderia acomodar esse valor seria float e mandar imprimir em tipo exponencial potência de 10 conforme mostra a seguir 44 include stdioh int main int a1000 b5000 float c c floataabb printfResultado da operacao e c return 0 Neste caso o resultado seria Resultado da operacao 2500000e13 Essa dica é importante quando tivermos que trabalhar com valores muito grande e podermos cair em situações que estouraria o domínio das variáveis a serem utilizadas 45 6 Expressões Matemáticas com uso dos operadores As expressões matemáticas são combinações entre variáveis constantes e operado res aritméticos Alguns tipos de necessidades nas expressões matemáticas como raiz qua drada potencia seno coseno tangente entre outros devemos incluir a biblioteca math h A expressão quando for muito grande temos que tomar cuidado com as preferências de operadores que são executados antes de outros como e precede e e outros co mandos podem ter precedência maior Para evitar isso pode se fazer uso de que tor na a operação com maior precedência Outras maneiras de resolver uma equação muito grande é quebrar sua fórmula em pequenas fórmulas mais simples e depois montar com os respectivos resultados Exemplo X A B3A2C foi necessário colocar AB en tre parênteses por ser uma operação de menor precedência e poderia dar problemas na operação Outra maneira poderia ser X AB depois X X3A e por fim X X2C que chegaremos ao mesmo resultado sem cometermos erro Todo problema que possui uma formula a ser desenvolvida como dada uma equação linear simples resolver os valores entre x e y sendo ax by c dx ey f Antes de levar para o computador deve ser desenvolvido colocando primeiro em fun ção de x e depois em função de y usando uma das 2 expressões x c bya dcbya ey f dcdbya ey f dc dby aey af logo aey dby afdc yaedb afdc y afdcaedb essa formula iria tirar o valor de y depois só colocar na primeira formulada x c bya 46 teremos também o valor de x Portanto na programação só usaremos as formulas y afdcaedb e x c bya O programa a seguir executa essa equação linear conforme desenvolvemos acima include stdioh int main int a b c d e f float x y printfEntre com os valores de a b c d e f scanfd d d d d dabcdef y floatafdcaedb x floatc bya printfX 2f Y 2f xy return 0 com os valores de entradas abaixo o programa executou da seguinte forma Entre com os valores de a b c d e f 7 8 12 3 5 9 valores de entrada X 109 Y 245 resultado obtido Desta forma todas equações matemáticas devem ser refinadas antes de colocar em operação nos programas em C Para usar esses cálculos matemáticos em C pode ser utilizado o compilador debugger que tem disponível na internet on line no link httpswwwonlinegdbcom esse compi lador é multilinguagem portanto antes de apertar run veja se a linguagem desejada está acionada A Figura 23 mostra uma imagem desse compilador e no lado direito superior a linguagem que está sendo utilizada 47 Figura 23 Imagem do compilador online no site httpswwwonlinegdbcom Outros compiladores podem ser utilizados como devc do sistema operacional windows ou geany do sistema operacional linux Ubuntu Todos possuem uma interface amigável e fácil de se trabalhar Esse apresentado na Figura 23 é um bom compilador por aceitar todas bibliotecas em C 48 7 Bibliotecas de operações em C Existem várias bibliotecas em C que devem ser estudadas antes de começar a utilizar A mais importante já conhecida até agora é a biblioteca stdioh que possui funções de entrada e saída Veja algumas amostras simplificadas de interfaces das principais Bibliotecas padrão em C stdlibh stdioh mathh stringh limitsh ctypeh timeh stdboolh Para ter acesso a uma biblioteca seu programa deve incluir uma cópia do corres pondente arquivointerface Por exemplo basta escrever include stdlibh Para que o pré processador da linguagem C acrescente uma cópia de stdlibh ao seu programa No sistema Linux os arquivos de interface ficam em geral no diretó rio usrinclude mas você não precisa saber disso A documentação das funções de uma biblioteca deveria idealmente estar no ar quivo de interface Na prática porém a documentação é mantida à parte Para consul tar a documentação de uma função de biblioteca no sistema Linux digite man nome dafunção no terminal ou consulte o Function and Macro Index da GNU C Library httpswwwgnuorgsoftwarelibcmanualhtmlnodeFunctionIndexhtml Todas as linguagens possuem bibliotecas sendo que muitas são bem ricas em con teúdo como o caso de Java que muitas vezes ajuda em melhorar o desenvolvimen to em 80 com muitos pacotes e classes prontas Em C as bibliotecas também devem ser explorada pois possuem muitas funções e procedimentos prontos que não preci samos refazer apenas aprender como utilizálos 49 8 Exemplos e problemas Continuando com a resolução de problemas ainda iremos explorar problemas mate máticos que envolvem operações simples ou sem necessidade de laços 2A Custo Final de um Carro O custo ao consumidor de um carro novo é a soma do custo de fábrica com a porcen tagem do distribuidor e dos impostos aplicados ao custo de fábrica Supondo que a por centagem do distribuidor seja de x do preço de fábrica e os impostos de y do preço de fábrica fazer um programa para ler o custo de fábrica de um carro a percentagem do distribuidor e o percentual de impostos calcular e imprimir o custo final do carro ao con sumidor Entrada O programa deve ler três valores na entrada o preço de fábrica do carro o percentual do distribuidor e o percentual de impostos Cada valor aparece em uma linha de entrada Todos os valores são do tipo float Saída O programa deve imprimir uma linha contento a frase O VALOR DO CARRO É Z onde Z é o valor do preço final do carro ao consumidor O valor de Z deve ter duas casas deci mais Após imprimir o valor do preço final o programa deve imprimir o caractere de que bra de linha Caso de Teste Entrada 25000 12 30 Saída O VALOR DO CARRO E 3550000 50 2B Conversão de Decimal para Binário Escreva um algoritmo em Linguagem C que leia um número 0 n 255 na base de cimal e apresente sua representação em binário Caso o número informado não esteja no intervalo especificado o programa deve finalizar imprimindo a mensagem Numero inva lido na tela A transformação de um número na base decimal para binária é obtida pela sequência de divisões por 2 O número 123 por exemplo tem sua representação binária 01111011 porque Não é permitido o uso de outras bibliotecas além da stdioh Entrada O programa deve ler um número inteiro qualquer Saída Caso o número lido esteja fora do intervalo especificado o programa deve imprimir a mensagem Número inválido e encerrar Caso o número lido seja válido o programa deve apresentar a representação binária de n na tela Observação Neste problema todos os números binários deverão conter 8 bits O número zero em decimal por exemplo tem sua representação binária 00000000 O número 1 00000001 o 2 000000010 e assim por diante Caso de teste Entrada Entrada 0 123 Saída Saída 00000000 01111011 51 2C Valor em notas e moedas Escreva um algoritmo par ler um valor em reais e calcular qual o menor número pos sível de notas de R 100 R 50 R 10 e moedas de R 1 em que o valor lido pode ser de composto O programa deve escrever a quantidade de cada nota e moeda a ser utilizada Entrada O programa deve ler uma única linha na entrada contendo um valor em Reais Consi dere que somente um número inteiro seja fornecido como entrada Saída O programa deve imprimir quatro frases uma em cada linha NOTAS DE 100 X NO TAS DE 50 Y NOTAS DE 10 Z MOEDAS DE 1 W onde X Y Z e W correspondem às quantidades de cada nota ou moeda necessárias para corresponder ao valor em Reais dado como entrada Após cada quantidade o programa deve imprimir um caractere de quebra de linha Caso de Teste Entrada 46395 Saída NOTAS DE 100 463 NOTAS DE 50 1 NOTAS DE 10 4 MOEDAS DE 1 5 2D Distância entre dois pontos Dados dois pontos A e B cujas coordenadas Ax 1 y 1 e Bx 2 y 2 serão informadas via teclado desenvolver um programa que calcule a distância entre A e B Entrada O programa deve ler os quatro valores reais correspondendo às coordenadas dos dois pontos x 1 y 1 x 2 y 2 nessa ordem e um valor por linha Saída O programa deve imprimir uma linha contendo a frase A DISTANCIA ENTRE A e B X onde X é o valor da distância entre os dois pontos e deve conter no máximo 2 casas decimais Após o valor da distância o programa deve imprimir um caractere de quebra de linha 52 Observação A distância entre dois pontos é computada pela fórmula d x2 x12 y2 y12 Caso de teste Entrada 3 4 5 6 Saída A DISTANCIA ENTRE A e B 283 Os resultados dos problemas apresentados devem ser retirados e passados ao profes sor para que ele possa resolver junto com os alunos Resultados 2A include stdioh int main float precoFabricapercDist percImpostoprecoFinal printfEntre com o preço de fabrica percDist percImposto scanffprecoFabrica scanffpercDist scanffpercImposto printfO VALOR DO CARRO E 2f precoFabrica percDist100 precoFabrica percImposto100precoFabrica 2B include stdioh int main int n printfEntre com o valor scanfd n ifn 0 n 255 printfNumero invalido return 0 printfd n1282 printfd n642 printfd n322 53 printfd n162 printfd n82 printfd n42 printfd n22 printfd n2 return 0 2C include stdioh int main int valor n100 n50 n10 m1 resto printfEntre com o valor scanfdvalor n100valor100 restovalor100 n50resto50 restoresto50 n10resto10 m1resto10 printfNOTAS DE 100 d n100 printfNOTAS DE 50 d n50 printfNOTAS DE 10 d n10 printfMOEDAS DE 1 d m1 return 0 2D include stdioh include mathh int main printfEntre com os pontos X1 Y1 X2 Y2 float x1y1x2y2dist scanffx1 scanffy1 scanffx2 scanffy2 distsqrt x1x2x1x2y1y2y1y2 printfA DISTANCIA ENTRE A e B 2f dist UNIDADE 3 ELEMENTOS FUNDAMENTAIS DA PROGRAMAÇÃO 55 1 Introdução Nesta Unidade estudaremos os principais fundamentos da programação na linguagem C sua estrutura principal linguagem de alto nível linguagem genéricas e específicas A lin guagem C é uma linguagem que depende muito da plataforma em que ela se propõe a ser projetada As bibliotecas apesar de serem padrões para todas plataformas existem al gumas diferenças básicas que mudam alguns tipos de funções dependendo da biblioteca Um programa de computador é um conjunto de instruções que descreve um algorit mo pré definido ao qual foi descrito para exercer algumas ações principais de um contex to do mundo real Essas instruções são descritas com um conjunto de códigos que cha mamos de comandos de programação e que seu padrão representa uma ação em cada tipo de linguagem mudando apenas algumas características dependendo da linguagem Em C que é nossa linguagem escolhida possuem diversos comandos que possuem um conjunto de regras semânticas que devem ser respeitadas estruturas lógicas e sintaxe própria Dizemos então que esse conjunto de comandos e regras formam um programa O programa deve ser compilado corrigido sempre que aparecem erros ou alertas evitan do que algo possa surpreender durante a sua execução Existem muitas linguagens de programação Podemos escrever um algoritmo para re solução de um problema por intermédio de qualquer linguagem A seguir mostramos al guns exemplos de trechos de códigos escritos em algumas linguagens de programação Exemplo trecho de um algoritmo escrito em Pseudolinguagem que recebe um número num e escreve a tabuada de 1 a 10 para este valor leia num para n de 1 até 10 passo 1 faça tab num n imprime tab fim faça Exemplo trecho do mesmo programa escrito em linguagem C scanfnum forn 1 n 10 n tab num n printf d tab 56 Exemplo trecho do mesmo programa escrito em linguagem Basic 10 input num 20 for n 1 to 10 step 1 30 let tab num n 40 print chr tab 50 next n Exemplo trecho do mesmo programa escrito em linguagem Fortran read num do 1 n 110 tab num n writetab 10 continue Exemplo trecho do mesmo programa escrito em linguagem Assembly para INTEL 8088 MOV CX0 IN AXPORTA MOV DXAX LABEL INC CX MOV AXDX MUL CX OUT AX PORTA CMP CX10 JNE LABEL Existem linguagens de Baixo Nível Assembly entre outras que são linguagens voltadas para uso de máquinas usando as instruções do microprocessador do computador Essas linguagens tornam os programas mais rápidos e ocupam menos espaços de memorias porém os programas em Assembly tem pouca portabilidade sendo um código gerado para um tipo de processador não serve para outro O programa em Assembly não são es truturado tornando a programação muito difícil 57 Já as linguagens de Alto Nível são voltadas mais para ser humano sendo estrutura das e podendo tornar o código mais legível Elas precisam de compiladores e interpreta dores para gerar os códigos mais próximo do microprocessador O interpretador faz a in terpretação de cada instrução do programa fonte executandoa dentro de um ambiente de programação Já os compiladores fazem a tradução de todas as instruções do progra ma fonte gerando um programa executável Após a compilação o programa executável pode ser executado fora do ambiente de programação a Linguagem C utiliza compilador assim como Pascal ou Fortran Com isso tornam os programas com maior portabilidades podendo ser executados em várias plataformas com poucas adaptações Todos programas podem ter vidas longas existem softwares que já estão em uso a mais de anos podendo sofrer algumas manutenções com o tempo e adaptações Por isso devemos sempre pensar em fazer uma bom software programa com um conjunto de do cumentações e funcionalidades bem definidas visando sua manutenção e correções fu turas Um programa em C é constituído de um cabeçalho contendo as diretivas de compilação onde se definem o valor de constantes simbólicas declaração de variáveis inclusão de bibliotecas declaração de rotinas etc um bloco de instruções principal e outros blocos de rotinas documentação do programa comentários que podem estar em várias linhas usando ou em uma mesma linha ou após um determinado comando usando Todo programa segue um padrão e a Linguagem C possui um padrão ANSI e seus caracteres seguem o padrão de caracteres ASCII Em geral o padrão ASCII possui os caracteres Caracteres válidos a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1 2 3 4 5 6 7 8 9 0 Caracteres não válidos á é ó ç Os Comentários em C podem ser escritos em qualquer lugar do programa e são desprezados pelo compilador ele ajuda no entendimento do programa ou de cada comando utilizado Para sua identificação podese utilizar os comentários entre várias linhas da seguinte forma Este é um comentário que podemos escrever em várias linhas ou uma mesma linha após um determinado comando comentário em uma mesma linha 59 As diretivas de compilação são comandos que são processados durante a compila ção em C e servem para ajudar a programação do usuário A diretiva include inclui outros programas bibliotecas que contêm funções e outros arquivos A diretiva define ajuda a definir constantes que serão usadas no programa Elas facilitam algumas operações que serão utilizadas no programa As declarações de variáveis ou definições de tipos de dados são usadas em seguida dessas diretivas o que veremos em Unidades mais a seguir Procure declarar as variáveis de programas no início de cada procedimento que serão utilizados apenas o necessário As variáveis em C são sensíveis ao contexto uma variável A é diferente de outra variável a Procure sempre organizar seu programa em etapas bem definidas evitando confusões de entendimento Todo programa em C pode ser modularizado ou seja quebrado em procedimentos que resolvam pequenas tarefas que são esperadas para atender as especi ficações do sistema 60 3 Entrada de dados Todas entradas de dados devem ser utilizadas tipos que possam melhor representar a informação que o programa deseja tratar As variáveis devem ser declaradas no início do programa podendo ser de vários tipos int inteiro float real de simples precisão e con forme já apresentamos na Unidade 2 Outros tipos não primitivos serão vistos mais a se guir quando houver necessidades de criarmos novos tipos para ajustar as informações que iremos utilizar em nosso programa Os comandos de leitura e gravação estão melhor representados em funções das bi bliotecas de C Por isso é muito importante se habituar a utilizar tais funções como scanf fgets para ler strings getchar para leitura de char ou controle de parada entre outros Os principais comandos de entrada e saída estão na biblioteca stdioh ou stdlibh Todo comando scanf deve ter um código de leitura apresentado na Unidade 2 por exemplo d para int f para float c para char lf para long e outros Da mesma forma esses comandos serão colocados nos comandos de saída de infor mação printf que será comentado no item 5 desta Unidade As entradas de informações podem ser por teclado ou por arquivo que veremos em Unidades mais à frente quando formos tratar de arquivos de armazenamentos das infor mações para facilitar as operações contínuas do nosso programa 61 4 Etapa de resolução do problema Após lidas todas informações necessárias de nosso programa iniciamos a etapa de re solução dos problemas pré definidos pelos requisitos do software Essa etapa pode ser dis tribuída para uso de módulos quando for algo muito complexo visando quebrar partes da resolução em pequenas partes mais fáceis A modularização sempre é necessária quando temos muitas atividades funcionalida des a serem resolvidas visando atender as necessidades do usuário Imaginamos que te remos uma função de leitura dos dados outra de inserção de valores quando houver ne cessidade outras de exibição de resultados outras de orientações e assim por diante Em um programa que devemos resolver um caso do mundo real podemos atender as etapas de resolução de várias maneiras Muitas vezes procuramos resolver tudo no progra ma principal main mas devemos evitar que isso aconteça quando nosso programa ti ver várias funcionalidades de usuário e que devem ser separadas por etapas Veremos esse tipo de resolução em Unidades mais à frente 5 Saída dos resultados Como a terceira e a mais importante etapa de um programa são as saídas das informa ções visando levar ao usuário todos resultados esperados pelo software de acordo com a especificação Alguns programas guardam seus resultados em relatórios outros mostram na própria tela de saída do programa Outros guardam em arquivos ou banco de dados utilizando técnicas mais avançadas da programação Aqui neste material só iremos ver resultados na tela ou em arquivos armazenados para uso do mesmo em outros momentos e suas infor mações somente será lida pelo próprio programa Como já vimos o principal comando de saída da informação é o printf por ser mais es truturado e mais fácil de representar o resultado da maneira esperada pelo usuário Ou fprintf quando formos armazenar em arquivos 62 6 Observações importantes Procure estruturar sempre seu programa em etapas bem definidas Documente seu programa sempre que achar necessário Evite utilizar nomes de variáveis que não signifi cam muito para o que ela representará no seu programa tipo você deverá usar uma variá vel para calcular uma equação y ab ac2a neste caso procure declarar as variáveis y a b e c Utilize os mesmos nomes dados pela equação Estude todo conteúdo dado no Capitulo 2 ele será muito utilizado ao decorrer das pró ximas Unidades principalmente os comandos de leitura e gravação bem como as direti vas utilizadas para mudar de linha tabulação entre outros usando o Faça os exercícios sempre que forem propostos por esse material eles ajudam a refor çar o entendimento e aprendizado dos conteúdos que iremos abordar em cada Unidade Anote sempre as dúvidas e leve para o monitor da disciplina ou professor Não deixe acumular muitas dúvidas por que isso pode atrapalhar na continuidade do entendimen to do restante dos conteúdos Referência Ascencio A F e Campus EA V Fundamentos da Programação de Computadores Algoritmos Pascal C C e Java Pearson 3a Edição 2012 UNIDADE 4 ESTRUTURAS DE FLUXO DE CONTROLE DAS INFORMAÇÕES 64 1 Introdução Nesta Unidade veremos os comandos que farão mudanças aos fluxos de informação na programação em C Iniciaremos com os comandos básicos de atribuição matemáticos e outros simples que são considerados comandos que calculam as necessidades exigidas pelo problema em questão E outros que ajudam a investigar se seus resultados estão sen do verificados da forma correta com comparações simples e compostas que definiremos por predicativos Essas comparações são inicialmente colocadas em comandos de deci são como ifthenelse que iremos ver com detalhes e suas necessidades com exemplos Da mesma forma abordaremos exemplos das necessidades do uso do comando switch case quando é importante utilizarmos e também outros exemplos de ninhos de ifthen else que as vezes se faz necessário Após trabalharmos com os comandos de decisão iniciaremos os comandos de laços repetição que muitas vezes serão necessários para executarmos sequências de ativida des repetidas com pequenas mudanças O uso de cada tipo de comando de repetição e quando são importantes utilizarmos o comando for ou while ou dowhile Cada um des ses comandos ajuda a exercer uma tarefa que mesmo que essa tarefa de para usar um ou mais comandos devemos entender a necessidade de cada comando para ter seu uso correto Para ilustrar esses comandos que serão estudados nessa Unidade faremos exercícios e indicaremos outros para que o aluno possa melhorar seus estudos e práticas com os co mandos aqui estudados para que nas etapas mais a frente eles sejam bem trabalhados e praticados UMA BOA LEITURA seria o Livro de Algoritmos Teoria e Prática de Thomas Cormen Charles Leiserson e Ronald Rivest 3a Edição 2009 65 2 Comandos de atribuição sequenciais Um conjunto de comandos em C sequencial denominamos de bloco de comandos que são tratados como comandos sem mudanças de fluxo de controle dentro de um programa Quando um comando desse bloco de comandos sequenciais são executados apenas ocorrem alterações nas informações nos valores das variáveis envolvidas no con junto de comandos que estão nesse bloco Para exemplificarmos essa sequência vamos ilustrar o cálculo de uma operação mate mática que dado 3 valores de a b e c iremos calcular a média aritmética desses valores Para ilustrar operações de inteiros resultando em valores com ponto flutuante real em pascal ou float em C iremos mostrar como procedemos tais resultados sem perda de casas decimais Então consideraremos a b e c valores inteiros e a média valor float 01 include stdioh 02 03 int main 04 int a b c 05 float media 06 entrada de dados 07 scanfd d d a b c a leitura exige o endereço das variaveis a b e c 08 media floatabc30 09 printfA media entre d d e d 2f abcmedia 10 return 0 11 supondo valores 3 10 4 o resultado ficaria A media entre 3 10 e 4 567 Observe que na linha 08 foi colocado um float antes da soma de a b e c Este é um comando de forçar que a soma entre 3 inteiros se transforme em float é denominado de cast Essas operações são necessárias sempre que as operações são entre variáveis de um tipo e temos que transformar em outro tipo de dados Apesar que nessa operação realizando na linha 8 o divisor foi colocado em ponto flutuante 30 e sendo assim não seria necessário o uso do cast vocês podem verificar tirando o cast float nessa linha o resultado seria o mesmo porém se colocarmos o divisor por 3 como inteiro aí seria necessário o uso do cast Em outras operações usaremos o cast como forma de converter o resultado para o tipo da variável que está recebendo a informação A sequência de comandos que vai entre a linha 07 até a 09 podem ser colocadas num mesmo bloco de comandos o bloco só se quebraria se houvesse algum comando de mudança de fluxo de controle como um if ou de um laço que veremos mais a seguir Um outro exemplo que podemos mostrar para entender o conceito de bloco de comandos em uma determinada sequência de comandos sem alteração de fluxo de controle vamos ver um problema como exemplo Exemplo 41 Um fabricante de latas deseja desenvolver um programa para calcular o custo de uma lata cilíndrica de alumínio sabendose que o custo do alumínio por m² é R 10000 O programa deve ler dois valores na entrada o raio e a altura da lata Ambos os valores correspondem a valores em metros Cada valor ocorre em uma linha diferente na entrada O programa deve imprimir a frase O VALOR DO CUSTO E XXXXX onde XXXXX é o valor do custo da lata Logo após o valor do custo da lata o programa deve imprimir o caractere de quebra de linha Observações O seu programa deve utilizar uma constante π com o valor aproximado de 314159 O valor total da área de um cilindro é dada por At 2Ar Al onde Ar é a área do círculo calculada como Ac πr² e Al é a área lateral do cilindro computada por Al 2πrh onde r é o raio e a altura da lata em metros 67 Resultado 01 include stdioh 02 define PI 314159 03 04 int main 05 06 float r a 07 float custo 08 09 scanff r 10 scanffa 11 custo 100 2PIrr 2PIra 12 printfO VALOR DO CUSTO E 2f custo 13 14 return 0 15 Se as entradas lidas fossem 100 100 o resultado seria O VALOR DO CUSTO E 12566360 Observem que os comandos entre as linhas de 09 a 12 são sequências que não afetam o fluxo de controle do programa Neste caso são considerados como bloco de comandos sequenciais A seguir será introduzido comandos de decisão ifthenelse que muda o bloco de co mandos em um programa devido à mudança de fluxos de controle que ocorre em um programa conforme a necessidade exigida pelo problema 68 3 Comandos de decisão O comando if ou ifelse em C instrui o programa a tomar uma decisão em seu resulta do O comando é descrito como if predicativo de decisão comando ou comandos else comando ou comandos Em geral os comandos de decisão simples são tratados no comando if as expressões lógicas que são colocadas no predicativo de decisão devem resultar em valores boolea nos true verdadeiro ou false falso que entra no bloco de comando do if ou do else Vamos ver um exemplo que mostra a mudança de fluxo de controle nos comandos de decisão ifelse 01 include stdioh 02 int main 03 char c 04 printfdigite c ou p 05 scanfcc 06 if c c 07 printfVoce digitou c 08 else ifcp 09 printfVoce digitou p 10 else printfVoce digitou outra letra diferente de c e p 11 return 0 12 Neste exemplo da linha 04 até a linha 06 pertence ao mesmo bloco de comandos de pois que aparece o comando if o comando da linha 07 está na decisão verdadeira do co mando if da linha 06 o comando da linha 08 está como parte falsa do comando if da linha 06 nesse comando existe outro if que verifica se o digito digitado foi p mudando nova mente o fluxo caso sim ou caso não Se a pessoa digitou p irá executar o comando da linha 09 caso contrário não tenha digitado nem c e nem p irá executar o comando da linha 10 Para entender a necessidade de um comando de decisão em um problema vamos fa zer um exemplo para ilustrar o uso dos comandos de decisão 69 Exemplo 42 Desenvolver um programa que leia um número inteiro e verifique se o número é divi sível por três e também é divisível por cinco O programa deve ler uma linha contendo um número inteiro na entrada O programa deve imprimir uma linha contendo a frase O NUMERO É DIVISIVEL se ele for divisível tanto por três quanto por cinco ou a frase O NUMERO NAO É DIVISIVEL em caso contrário Após imprimir uma das frases o programa deve imprimir um caractere de quebra de linha Solução 01 include stdioh 02 int main 03 int num 04 scanfdnum 05 ifnum30 num50 06 printfO NUMERO E DIVISIVEL 07 08 else 09 printfO NUMERO NAO E DIVISIVEL 10 Se o valor de entrada for 871 o resultado deverá ser O NUMERO NAO E DIVISIVEL porém se o valor for 75 o resultado será O NUMERO E DIVISIVEL Observe que o fluxo de controle muda na linha 05 se o predicativo de comparação num30 num50 resultar em verdadeiro a resposta será O NUMERO É DI VISIVEL caso contrário a resposta será da linha 09 O NUMERO NAO É DIVISIVEL Outros exemplos serão colocados na parte de exercícios desta Unidade para que os alu nos possam exercitar seu conhecimento em comandos de decisão simples e compostos A seguir vamos ver melhor quando há necessidade de múltiplas decisões colocadas de forma aninhadas em uma sequência construtiva visando interpretar melhor as neces sidades do problema 70 4 Comandos de múltiplas decisões aninhadas Os comandos ifelse aninhados são quando existem uma sequência de decisões para se obter diferentes tipos de resultados Um exemplo simples porém demanda uma deci são aninhada seria determinar qual é o menor valor entre 4 números inteiros a b c e d Para isso devemos inicialmente ler os valores das variáveis inteiras a b c e d e em se guida iniciar a verificação de qual seria o menor valor entre elas 01 include stdioh 02 int main 03 int a b c d menor 04 scanfd d d d a b c d 05 06 if abacad 07 menor a 08 else ifbcbd 09 menor b 10 else ifcd 11 menor c 12 else menor d 13 printfO menor valore entre a d b d cd e dd eh d abcdmenor 14 15 return 0 16 O exemplo é fácil de entender pois primeiro foi necessário comparar a com todas va riáveis b c e d na linha 06 depois se a não for menor que todas vamos para a 2a compa ração linha 08 que ocorre entre b com as variáveis c e d pois b já foi comparada com a na linha 06 E assim caso b também não for menor que todas iremos para a 3a comparação entre c e d na linha 10 que encerra o ninho de ifelse necessário para detectar qual será o menor valor entre a b c e d Alguns cuidados são necessários quando temos comparações compostas como ocor reu na linha 06 é necessário separar entre parênteses cada item da comparação e depois toda a comparação deve estar entre parênteses facilitando para o compilador 71 5 Comando Switch case O comando switch case é um comando que facilita a comparação quando um valor a ser comparado pode ser uma sequência de valores pré definidos evitando assim de fazer mos um ninho de ifelse Para entender o uso correto do comando switch case vamos su por que queremos ler uma dada sendo ddmmaaaa em um número único inteiro e escre ver primeiro se o dia ou mês ou ano for inválido sabendo que os dias de um mês pode ser de 1 a 28 fevereiro de 1 a 31 para janeiro março maio julho agosto outubro e dezem bro e de 1 a 30 para os demais meses Ex se entrarmos com a data 10121999 devemos es crever 10 de dezembro de 1999 Então Faça um programa que leia uma data no formato ddmmaaaa usando um único número inteiro Escreva a mesma data no formato diamêsano dia de mês por ex tenso de ano O programa deve verificar se o número informado representa uma data válida Caso não seja imprimir na tela a mensagem Data invalida Considere que o ano em questão nunca é bissexto ou seja fevereiro tem somente 28 dias A entrada será um único número inteiro com 8 dígitos O programa deve apresentar uma transição da data no formato dd do mês por exten so de aaaa ano Resultado 01 include stdioh 02 int main 03 int data d m a 04 scanfd data 05 06 ifdata 0 data100000000 0 07 printfData invalida 08 return 0 09 10 d data 1000000 11 m data 1000000 10000 12 a data 10000 13 72 14 if d 1 d 31 m 12 m 1 15 printfData invalida 16 return 0 17 18 ifm2 d29 19 printfData invalida 20 return 0 21 else ifm2d29 22 ifa1000 a10040 23 printfData invalida 24 return 0 25 else if a40 26 printfData invalida 27 return 0 28 29 30 31 if m4 m6 m9 m11 d30 32 printfData invalida 33 return 0 34 35 printfd de d 36 switch m 37 case 1 printfjaneiro 38 break 39 case 2 printffevereiro 40 break 41 case 3 printfmarço 42 break 43 case 4 printfabril 44 break 45 case 5 printfmaio 46 break 47 case 6 printfjunho 48 break 49 case 7 printfjulho 50 break 51 case 8 printfagosto 52 break 53 case 9 printfsetembro 73 54 break 55 case 10 printfoutubro 56 break 57 case 11 printfnovembro 58 break 59 case 12 printfdezembro 60 break 61 62 printf de d a 63 return 0 64 Se a entrada for 10192019 o resultado deverá sair Data invalida porém se a entrada for 10082021 a saída deverá ser 10 de agosto de 2021 Observe que esse exemplo tivemos que fazer vários ifs aninhados e outros isolados e para decidir o mês utilizamos o comando switch case para facilitar nossa operação Po deria ter sido usado comandos ifs também aninhados porém ia fica muito grande e mais confuso No comando switch case na linha 36 houve a necessidade abrir um conjunto de comandos com o e fechando com o na linha 61 no final do comando switch Para cada case utilizado para escrever o respectivo mês de Janeiro até Dezembro tivemos que colocar um comando break que faz com que o case que ele entrar seja realizado e encer rado o comando não deixando continuar no próximo case Portanto o uso do break nos cases do switch é necessário Outro uso muito importante do comando switch é quando temos um programa com várias opções dadas por um menu como por exemplo inserir um elemento remover ele mento consultar exibir todos elementos etc que serão muito úteis quando estivermos desenvolvendo um programa real para um determinado usuário Neste caso utilizaremos o comando switch para as opções de escolha do menu 74 6 Comandos de Repetição Os comandos de repetição laços são muito necessários quando temos atividades re petitivas para serem utilizadas como por exemplo efetuar o cálculo de uma somatório de valores ou expressões ou entrar com dados de um vetor ou buscar um valor em um de terminado vetor ou ler os dados de uma matriz ou buscar valores de em uma matriz e as sim sucessivamente quando houver essas Os comandos de repetição também conheci dos como laços ou do inglês loops ajudam a executar uma sequência de repetição de um conjunto de comandos quando for necessário Os laços devem ser finitos visando atender a especificação do problema Caso o laço não atenda o programa poderá resulta do em um erro de Run Time Error tempo de execução errada Os comandos de repetição em C são for quando temos uma sequência a ser seguida podendo ter na forma crescente ou decrescente conforme a necessidade Outros comandos de repetição podem caracterizar como melhor caso não entrar ne nhuma vez ou só 1 vez no laço ou pior caso quando tem que entrar todas vezes no laço esse é o caso dos comandos while ou do while Os quais veremos com exemplos mais a seguir 61 For O comando for permite que um certo trecho de programa seja executa do um determinado número de vezes A forma do comando for é a seguinte for comandos de inicializaçãocondição de testeincrementodecremento comandos a serem repetidos comandos a serem repetidos comandos após o for 75 Figura 41 Fluxograma do comando for O comando for executa uma sequência de iterações podendo ser crescente ou de crescente e tendo um número inicial e um número que finaliza sua sequência de execu ção em um determinado exemplo O comando tem o formato fori0ini i1 comando sendo i0 o comando de inicialização in a condição de teste e i i1 o incremento da variável i Neste comando mostra que a variável i deve ser inteira e declarada no início do proce dimento e ela irá executar o comando n vezes sendo n um valor pré definido ou lido pelo usuário O comando pode ser um único comando ou um bloco de comandos quando for mais do que um comando devemos por todos entre e Um exemplo Dado dois inteiros num e n sendo num o número inicial de uma se quência de pares n que deverão ser descrito a seguir Ex 20 4 os pares a partir de 20 se rão 20 22 24 26 Resultado 01 include stdioh 02 int main 03 int x y c 04 scanfddx y 05 ifx2 0 06 printfPRIMEIRO NUMERO NAO E PAR 07 return 0 08 09 forc0cy1c 10 printfd x 11 x 2 76 12 13 printfd x 14 return 0 15 Caso a entrada for 20 10 o resultado será 20 22 24 26 28 30 32 34 36 38 caso a entrada for 21 10 o resultado seria PRIMEIRO NUMERO NAO E PAR Neste exemplo na linha 09 caso o primeiro número seja par o laço é executado de 0 até atingir o n1 e na saída escreve o valor final mudando a escrita do laço que tem espa ço e sequencial com uma escrita única e mudando de linha com o Outros exemplos serão vistos no final desta Unidade com exercícios para o aluno pra ticar e utilizar os comandos de repetição 62 While O outro comando de repetição é o while enquanto condição faça O formato do comando é whilecondição de teste comando ou conjunto de comandos Figura 42 fluxograma do comando while O comando while é muito utilizado quando fazemos uma busca em conjunto de valo res e somente para sua execução quando atingir a quantidade de valores existentes ou en contrar o valor neste conjunto Neste caso podemos dizer que o melhor caso seria encontrar no início do conjunto de valores e temos apenas uma comparação executada No pior caso num conjunto de N valores seria encontrar no final do conjunto e termos n comparações executadas O caso médio seria N12 que é a média entre o melhor caso e o pior caso Para ilustrar esse comando vamos fazer o exercício 46 a seguir Escreva um programa que leia várias linhas contendo cada uma a matrícula de um fun cionário um valor inteiro seu número de horas trabalhadas o valor que recebe por hora e calcule o salário desse funcionário A seguir mostre o número e o salário do funcionário com duas casas decimais 77 A entrada é formada por várias linhas cada uma contendo três valores decimais separa dos um do outro por um espaço em branco O último valor na linha é seguido pelo carac tere de quebra de linha A última linha contém uma matrícula igual a zero e não deve ser processada Ela serve apenas para indicar ao programa o término da entrada de dados A saída deve conter para cada linha de entrada a matrícula um espaço em branco e o salário calculado com duas casas decimais Observações Para ler uma linha com os três valores utilize a função scanf scanfd f f A B C e em seguida a função getchar A função getchar é usada para consumir o carac tere de quebra de linha na entrada Resultado do Programa 01 include stdlibh 02 include mathh 03 include stdioh 04 int main 05 int matricula horasTrab 06 double salarioHora salarioTotal 07 08 scanfd d lf matriculahorasTrabsalarioHora 09 getchar 10 while matricula quando matricula for diferente de 0 é verdadeiro 11 salarioTotal salarioHorahorasTrab 12 printfd 2f matriculasalarioTotal 13 scanfd d lf matriculahorasTrabsalarioHora 14 getchar 15 16 para a entrada 2015001 16000 323 2015002 16010 30 2015003 16009 299 0 0 00 a saída será 2015001 5168000 2015002 4803000 2015003 4786691 78 No exemplo dado o comando while usou como teste apenas matricula o que em C isso é possível pois qualquer valor diferente de 0 zero é verdadeiro e 0 zero é falso Seria o mesmo que ter colocado while matricula0 O comando while pode ter a expressão lógica de comparação simples ou composta conforme a necessidade que tivermos que exercer tal comparação Quando chegarmos em algoritmos de busca iremos utilizar expressão lógica de comparação no while com posta 63 Do While O comando do while também conhecido como repeat until do pascal é bem pare cido com o comando while mudando apenas que a comparação ocorre no final do corpo do laço A Figura 43 mostra como seria o fluxograma deste comando Figura 43 fluxograma do comando dowhile Observe que a saída do laço ocorre no final após o corpo do laço ter sido executado Neste caso a primeira vez o laço é executado sempre Muito utilizado para casos quando temos que executar o fluxo de comandos no laço pelo menos uma vez podendo não ter a necessidade de executar outras vezes Um exemplo muito usado é quando temos um programa que executa um menu e tem uma opção de parada tipo digitar um número Vamos fazer um exemplo prático que será o exercício 47 Faça um programa que leia uma sequência de números inteiros diferente de zero e apresente a média nos números pares e a média nos números ímpares O programa deve ler uma sequência de números inteiros diferentes de zero O programa deve apresentar duas linhas a primeira contendo a mensagem MEDIA PAR mpe a segunda com a mensagem MEDIA IMPAR mi onde mp e mi são os valo res das médias dos números pares e ímpares respectivamente 79 Resultado do programa 01 include stdioh 02 int main 03 int n 04 int np ni 05 double sp si 06 np ni 0 07 sp si 0 08 scanfd n 09 do 10 if n2 0 11 np 12 spn 13 else 14 ni 15 sin 16 17 scanfd n 18 whilen 19 if np 0 sp spnp 20 if ni 0 si sini 21 printfMEDIA PAR f sp 22 printfMEDIA IMPAR f si 23 return 0 24 Se a entrada for a sequência 12 12 12 12 14 14 15 151 5 7 7 7 7 7 7 7 12 4 0 a saída deverá ser MEDIA PAR 11500000 MEDIA IMPAR 22000000 Observe que o comando dowhile a condição do while ocorre após o fechamento do laço e o comando whilecondição possui um o que não acontece no comando while apenas O laço dowhile nesse exemplo ocorre entre as linhas 09 e 18 Os comandos de repetição desta Unidade foram apresentados e a seguir vamos colo car exercícios para serem praticados pelos estudantes 80 7 Exercícios Exercícios de expressões E71 Custo final de um carro O custo ao consumidor de um carro novo é a soma do custo de fábrica com a porcen tagem do distribuidor e dos impostos aplicados ao custo de fábrica Supondo que a por centagem do distribuidor seja de x do preço de fábrica e os impostos de y do preço de fábrica fazer um programa para ler o custo de fábrica de um carro a percentagem do distribuidor e o percentual de impostos calcular e imprimir o custo final do carro ao con sumidor Entrada O programa deve ler três valores na entrada o preço de fábrica do carro o percentual do distribuidor e o percentual de impostos Cada valor aparece em uma linha de entrada Todos os valores são do tipo float Saída O programa deve imprimir uma linha contento a frase O VALOR DO CARRO E Z onde Z é o valor do preço final do carro ao consumidor O valor de Z deve ter duas ca sas decimais Após imprimir o valor do preço final o programa deve imprimir o caractere de quebra de linha Caso de teste Entrada 25000 12 30 Saída O VALOR DO CARRO E 3550000 E72 Distância entre dois pontos Dados dois pontos A e B cujas coordenadas Ax1 y1 e Bx2 y2 serão informadas via teclado desenvolver um programa que calcule a distância entre A e B Entrada O programa deve ler os quatro valores reais correspondendo às coordenadas dos dois pontos x1 y1 x2 y2 nessa ordem e um valor por linha Saída O programa deve imprimir uma linha contendo a frase A DISTANCIA ENTRE A e B X onde X é o valor da distância entre os dois pontos e deve conter no máximo 2 ca sas decimais Após o valor da distância o programa deve imprimir um caractere de que bra de linha 81 Observação A distância entre dois pontos é computada pela fórmula d sqrtx2 x1 2 y2 y1 2 sqrt é função da biblioteca mathh Você pode usar a função sqrt para calcular a raiz quadrada na fórmula da distância Para computar o quadrado de um valor x você pode usar a função powx2 Para usar es sas funções você precisa colocar include mathh no início do texto do programa Caso de teste Entrada 3 4 5 6 Saída A DISTANCIA ENTRE A e B 283 E73 Número Invertido Escreva um programa para ler um número de três dígitos e imprimir o número invertido Entrada A entrada contém apenas um número com três dígitos Esse número é dife rente de zero e não é múltiplo de 10 ou 100 Saída A saída deve conter apenas uma linha com o número correspondente ao valor da entrada com seus dígitos invertidos Logo após o número deve ser impresso o carac tere de quebra de linha Caso de teste Entrada 123 Saída 321 Entrada 987 Saída 789 74 Valor em notas e moedas Escreva um algoritmo par ler um valor em reais e calcular qual o menor número pos sível de notas de R 100 R 50 R 10 e moedas de R 1 em que o valor lido pode ser de composto O programa deve escrever a quantidade de cada nota e moeda a ser utilizada Entrada O programa deve ler uma única linha na entrada contendo um valor em Reais Considere que somente um número inteiro seja fornecido como entrada Saída O programa deve imprimir quatro frases uma em cada linha NOTAS DE 100 X NOTAS DE 50 Y NOTAS DE 10 Z MOEDAS DE 1 W onde X Y Z e W correspon dem às quantidades de cada nota ou moeda necessárias para corresponder ao valor em Reais dado como entrada Após cada quantidade o programa deve imprimir um caracte re de quebra de linha 82 Caso de teste Entrada 46395 Saída NOTAS DE 100 463 NOTAS DE 50 1 NOTAS DE 10 4 MOEDAS DE 1 5 Exercícios de decisão 75 Notas em conceitos Em um curso de mestrado as avaliações dos alunos no histórico escolar aparecem em forma de conceito O regulamento do mestrado indica que um professor pode avaliar seus alunos com notas convencionais de zero a dez mas precisa repassar à secretaria do curso a avaliação em termos de conceito Nesse caso a seguinte tabela de conversão deve ser usada pelo professor Intervalo da Nota Conceito 90 a 100 A 75 a 89 B 60 a 74 C 00 a 59 D Escreva um programa para ler um nota e convertela no conceito correspondente Entrada A entrada consiste de uma linha com um valor real entre 0 e 10 e com uma casa decimal Saída O programa deve imprimir a seguinte frase NOTA x CONCEITO y onde x é o valor da nota lido na entrada impresso com uma casa decimal y é o conceito correspon dente Após a frase o programa deve imprimir o caractere de quebra de linha Caso de teste Entrada 34 saída NOTA 34 CONCEITO D Entrada 60 saída NOTA 60 CONCEITO C 76 Reajuste Salarial Fazer um algoritmo que calcule e imprima o salário reajustado de um funcionário de acordo com as seguintes regras Salário de até R 30000 reajuste de 50 Salário maior que R30000 reajuste de 30 Entrada A entrada conterá uma linha com o salário do funcionário Saída A saída deve conter numa linha com a frase SALARIO COM REAJUSTE x onde x é um valor real com duas casas decimais e corresponde ao valor do salário reajustado Logo em seguida ao valor de x o programa deve imprimir o caractere de quebra de linha Caso de Teste Entrada 75500 Saída SALARIO COM REAJUSTE 98150 Entrada 26532 Saída SALARIO COM REAJUSTE 39798 84 Entrada A entrada conterá duas linhas A primeira com três números inteiros positi vos separados entre si por um espaço Todos os três números são inferiores ou iguais a 100 A segunda linha conterá três letras maiúsculas A B e C sem espaços entre elas repre sentando a ordem desejada de impressão dos valores das variáveis Saída A saída deve conter numa linha os inteiros a b e c na ordem desejada separa dos por espaços simples Após o último número da saída deve aparecer apenas o caracte re de quebra de linha Observação Após o último número na primeira linha da entrada está no buffer de entrada o caractere Com isso ao tentar ler o primeiro caractere A B ou C na segunda linha de entrada com scanfd x será lido o caractere na variável x ao invés de uma das letras na entrada A B ou C Para evitar isso você pode fazer com que a leitura do úl timo número na primeira linha consuma o caractere da primeira linha colocando esse caractere na especificação de formato do scanf Por exemplo suponha que você decla rou as seguintes variáveis na entrada int a bc para armazenar os três número da primeira linha e char x y z para armazenar as três letras que aparecem na segunda linha de entra da A leitura dessas variáveis de entrada pode ser realizada assim scanfd d d a b c scanfccc x y z Repare o ao final da formatação do primeiro scanf e repare que não há espaços entre os cna formatação do segundo scanf O ao final da formatação do primeiro scanf faz com que o caractere de quebra de linha seja consu mido no buffer Asssim no segundo scanf será armazenada na variável x a primeira letra da segunda linha e não o resolvendo o problema da leitura Casos de teste Entrada Saída 1 5 3 A B C 1 3 5 6 4 2 C A B 6 2 4 85 Exercícios de Repetição 79 Somatório simples Faça um programa que leia um valor n inteiro e positivo calcule e mostre a seguinte soma n S 1k 1 12 13 14 1n k1 Entrada O programa deve ler um número inteiro positivo e maior que 1 Saída O programa deve apresentar uma linha contendo o valor final do somatório com 6 casas decimais Caso o número lido não atenda as especificações da entrada o pro grama deve apresentar a mensagem Numero invalido Observação Use precisão dupla para o cálculo de S Caso de Teste Entrada 10 Saída 2928968 710 Companhia de Teatro Uma companhia de teatro deseja dar uma série de espetáculos A direção calcula que o ingresso sendo vendido ao valor comum de mercado ValorIngresso serão vendidos 120 ingressos e que as despesas fixas serão de R 20000 mais R 005 por cada ingresso Diminuindose R 050 o preço dos ingressos esperase que as vendas aumentem em 25 ingressos Aumentandose R 050 o preço dos ingressos esperase que as vendas dimi nuam 30 ingressos Para resolver este problema a companhia de teatro deseja que você faça um programa que escreva uma lista de valores de lucros esperados em função do preço do ingresso fazendose variar esse preço de A a B de R 100 em R 100 O progra ma deve apresentar na tela um resumo contendo o preço do ingresso informado o lu cro máximo calculado e a quantidade de ingressos vendidos para a obtenção desse lucro Entrada O programa deve ler três números reais ValorIngresso correspondente ao va lor de mercado dos ingressos ValorInicial e ValorFinal correspondentes ao intervalo de va lores que se deseja testar Caso o ValorInicial informado seja maior ou igual ao ValorFinal o programa deve encerrar após apresentar a mensagem INTERVALO INVALIDO Saída O programa deve apresentar na tela uma linha para cada valor testado com o seguinte formato V xxxxx N xxx L xxxxx onde V é o valor do ingresso N é a quantida de de ingressos vendidos e L o lucro obtido Ao final o programa deve apresentar um re sumo contendo três linhas com o seguinte formato 86 Melhor valor final xxxxx Lucro xxxxx Numero de ingressos xx Observação Todos os valores reais devem ser apresentados com 2 casas decimais Caso o intervalo de valores indicados não produza lucro positivo os valores que devem aparecer no resumo devem assumir o valor zero Casos de testes Entradas Saídas 5 2 8 V 200 N 270 L 32650 V 300 N 220 L 44900 V 400 N 170 L 47150 V 500 N 120 L 39400 V 600 N 60 L 15700 V 700 N 0 L 20000 V 800 N 60 L 67700 Melhor valor final 400 Lucro 47150 Numero de ingressos 170 05 0 2 V 000 N 145 L 20725 V 100 N 90 L 11450 V 200 N 30 L 14150 Melhor valor final 000 Lucro 000 Numero de ingressos 0 711 Mínimo Múltiplo Comum Faça um programa que calcule o Mínimo Múltiplo Comum MMC de 3 números intei ros A Figura 71 apresenta um exemplo de cálculo de MMC Figura 71 Calculo de MMC 87 Entrada O programa deve ler 3 números inteiros diferentes de zero Saída A saída é composta por várias linhas O programa deve replicar a saída do pro cedimento da Figura 71 com expresso nos exemplos de entrada e saída Cada linha deve ser impressa com o seguinte código d d d d onde o número 5 indica a quantida de mínima de espaços ou dígitos do número a ser apresentado Casos de teste Entrada Saída 10 5 6 10 5 6 2 5 5 3 3 5 5 1 5 MMC 30 3 5 7 3 5 7 3 1 5 7 5 1 1 7 7 MMC 105 712 Série de Taylor seno Escreva um programa que dado um número real x e a quantidade de termos N calcu le o valor da função sinx a partir da série onde x é o ângulo em radianos e N a quantidade de termos da série menos 1 Entrada O programa deve ler o valor de x e N Saída O programa deve apresentar uma linha contendo o texto senox y onde x é o ângulo fornecido pelo usuário e y o seno do ângulo x deve ser impresso com 2 ca sas decimais e y com 6 casas decimais Observação Neste tipo de problema a quantidade de termos pode gerar números muito grandes por conta da operação de fatorial e potenciação de x Atentese aos tipos de dados usados nas declarações das variáveis e não use valores de N maiores que 9 Lem brese que um ângulo qualquer sempre pode ser representado por um valor entre 0 e 2π Use a constante MPI da biblioteca mathh Como sugestão de desafio à solução do problema tente escrever um algoritmo que use apenas um laço de repetição 88 Caso de teste Entrada Saída 2 9 seno200 0909297 314 6 seno314 0001614 1 4 seno100 0841471 Encerramos aqui uma lista de exercícios para prática desse conteúdo dado na Unidade 4 A seguir veremos vários outros comandos dentro das estruturas homogêneas trabalhadas em vetores e matrizes A seguir colocaremos as respostas dos exercícios dados nessa sessão R71 Custo final do Carro include stdioh int main float precoFabricapercDist percImpostoprecoFinal scanffprecoFabrica scanffpercDist scanffpercImposto printfO VALOR DO CARRO E 2f precoFabricapercDist 100precoFabricapercImposto100precoFabrica R72 Distância entre dois pontos include stdioh include mathh int main float x1y1x2y2dist scanffx1 scanffy1 scanffx2 scanffy2 distsqrt x1x2x1x2y1y2y1y2 printfA DISTANCIA ENTRE A e B 2f dist 89 R73 Numero Invertido include stdioh int main int n i dig1 dig2 dig3 Lendo um numero inteiro scanfdn Isolando os digitos do numero dig1n100 dig2n100 dig2dig210 dig3n10 ImpriminRdo os digitos na ordem inversa As duas formas alternativas abaixo funcionam printfd dig3100dig210dig1 printfddd dig3dig2dig1 return 0 R74 Valores em Notas include stdioh int main int valor n100 n50 n10 m1 resto scanfdvalor n100valor100 restovalor100 n50resto50 restoresto50 n10resto10 m1resto10 printfNOTAS DE 100 d n100 printfNOTAS DE 50 d n50 printfNOTAS DE 10 d n10 printfMOEDAS DE 1 d m1 return 0 90 R75 Notas Conceitos include stdioh int main float nota char conceito scanff nota if nota60 conceitoD else ifnota75 conceitoC else ifnota90 conceitoB else conceitoA printfNOTA 1f CONCEITO c notaconceito return 0 R76 Reajuste Salarial include stdioh include stdlibh int main float salAtual salReajustado scanff salAtual if salAtual 3000 salReajustadosalAtual 05salAtual else salReajustadosalAtual 03salAtual printfSALARIO COM REAJUSTE 2f salReajustado return 0 91 R77 Soma dos 3 menores valores include stdioh int main int n1 n2n3n4maior soma scanfdn1 scanfdn2 scanfdn3 scanfdn4 soman1n2n3n4 ifn1n2 n1n3 n1n4 maiorn1 ifn2n1 n2n3 n2n4 maiorn2 ifn3n1 n3n2 n3n4 maiorn3 ifn4n1 n4n2 n4n3 maiorn4 printfd somamaior R78 Ordem include stdioh include stdlibh int main int abc menor meio maior char X YZ scanfd d d a b c scanfd b scanfd c scanfccc X Y Z scanfc Y scanfc Z Encontrar o menor elemento o intermediario e o maior elemento if ab ac menora ifbc meiob maiorc else meioc 92 maiorb else if ba bc menorb ifac meioa maiorc else meioc maiora else menorc ifab meioa maiorb else meiob maiora if XA printfd menor if XB printfd meio if XC printfd maior if YA printfd menor if YB printfd meio if YC printfd maior if ZA printfd menor if ZB printfd meio if ZC printfd maior return 0 93 R79 Somatório Simples include stdioh int main int n k double soma scanfdn if n 1 printfNumero invalido return 0 soma 00 k 1 while k n soma 10k k printf6f soma return 0 R710 Companhia do Teatro include stdioh int main double ValorIngresso ValorInicial ValorFinal double MelhorValor MelhorLucro int MelhorNIV double val lucro int niv número de ingressos vendidos scanflf lf lfValorIngresso ValorInicial ValorFinal if ValorInicial ValorFinal printfINTERVALO INVALIDO return 0 MelhorLucro 0 MelhorValor 0 MelhorNIV 0 94 val ValorInicial while val ValorFinal if val ValorIngresso niv 120 ValorIngressoval2505 else niv 120 valValorIngresso3005 lucro nivval 200niv005 printfV 2f N i L 2f val niv lucro if lucro MelhorLucro MelhorLucro lucro MelhorValor val MelhorNIV niv val 1 printf Melhor valor final 2f Lucro 2f Numero de ingressos i MelhorValor MelhorLucro MelhorNIV return 0 R711 Minimo Multiplo comum include stdioh int main int n1 n2 n3 int m int mmc mmc 1 m 1 scanfd d d n1 n2 n3 while n1 1 n2 1 n3 1 m 2 while n1m0 n2m0 n3m0 m 95 printfd d d n1 n2 n3 printfd m mmc m if n1m 0 n1 m if n2m 0 n2 m if n3m 0 n3 m printfMMC d mmc return 0 R712 Série de Taylor seno include stdioh include mathh int main double x sinx px int n N long int f char s 1 scanflfdxN x x180314 x x2MPI x x intx x x2MPI printfsinLf x f 1 px x sinx x s 1 printf Lf1 Lf px sinx for n 1 n N n px xx f 2n12n s s sinx spxf printfs s0 ifs0 printf2Lflld Lf px f spxf else printf2Lflld Lf spx f spxf printfseno2lf 6lf x sinx return 0 77 Soma dos 3 menores valores Fazer um programa para quatro valores inteiros e imprimir a soma dos três menores Entrada O programa deve ler os quatro valores inteiros na entrada Cada valor ocupa uma linha na entrada Saída O programa deve imprimir uma linha contendo o valor da soma dos três menores números Após o valor da soma o programa deve imprimir um caractere de quebra de linha Caso de teste Entrada 9 4 2 12 Saída 15 78 Ordem Você receberá três valores inteiros e deve descobrir quais deles correspondem às variáveis a b e c Os números não serão dados em ordem exata mas sabemos que o valor correspondente a a é menor do que o valor correspondente a b e que o valor correspondente a b é menor do que o correspondente a c Será informada a você a ordem em que os valores associados a cada variável devem ser impressos Escreva um programa que imprima os valores na ordem requisitada 97 1 Introdução Nesta Unidade iremos trabalhar com as estruturas homogenias Vetores e Matrizes ampliando a forma de armazenamento de nossas informações Depois será introduzido geração de tipos de dados heterogêneos onde ajudarão a dar exemplos mais reais Fina lizando a Unidade com armazenamentos da informação em arquivos textos ou binários Vários exemplos serão mostrados para ilustrar o uso dessas estruturas e como mapear os elementos armazenados nela O usuário tem uma visão externa de como essas estru turas funcionam porém a implementação computacional tem outra forma de armazenar para isso faremos um mapeamento sempre informando na visão do usuário Livro Didático para leitura Waldemar Celes Renato Cerqueira José Lucas Rangel Introdução a Estruturas de Dados Editora Campus 2004 Thomas Cormen e outros Algorithmos teoria e prática 3a Edição 2012 2 Estruturas homogêneas unidimensionais vetor Nas Unidades anteriores estudamos as opções disponíveis na linguagem C para representar Números inteiros em diversos intervalos Números fracionários com várias alternativas de precisão e magnitude Letras dígitos símbolos e outros caracteres Todas estas opções estão definidas previamente na própria linguagem C e portanto são chamadas de tipos de dados primitivos da linguagem C Iremos introduzir mecanismos para definir outros tipos de dados conforme a necessidade do seu programa Assim eles são chamados de tipos de dados do programador Porém iniciaremos com tipos Homogêneos ou seja cria um vetor de um mesmo tipo de dado primitivo inteiro real ou letras Depois estaremos avançando para outros tipos Heterogêneos Um vetor é uma sequência de vários valores do mesmo tipo armazenados sequencialmente na memória e fazendo uso de um mesmo nome de variável para acessar esses valores Um vetor também pode ser entendido logicamente como uma lista de elementos de um mesmo tipo Cada elemento desta sequência pode ser acessado individualmente através de um índice dado por um número inteiro Os elementos são indexados de 0 até N1 onde N é a quantidade de elementos do vetor O valor de N também é chamado de dimensão ou tamanho do vetor O vetor tem tamanho fixo durante a execução do programa definido na declaração sendo assim é uma estrutura estática Durante a execução não é possível aumentar ou diminuir o tamanho do vetor Note que a numeração começa em zero e não em um Essa é uma fonte comum de erros A Figura 51 ilustra um vetor com 10 elementos denominados v0 v1 v9 todos eles de tipo int É importante saber que os elementos do vetor são armazenados sequencialmente na memória do computador Assim na figura se cada valor de tipo int ocupar 4 bytes de memória teremos 40 bytes consecutivos reservados na memória do computador para armazenar todos os valores do vetor No entanto por ora não faremos uso explícito dessa informação uma vez que o compilador se encarregará de endereçar cada elemento 98 99 do vetor automaticamente conforme as necessidades do programador como veremos Declaração de vetores int vetor10 o compilador reserva um local sequencial para armazenar 10 int 10 8 11 16 9 14 21 1 18 3 vetor 0 1 2 3 4 5 6 7 8 9 Figura 51 Demonstração da alocação de um vetor de tamanho 10 de inteiros A declaração de vetores obedece à mesma sintaxe da declaração de variáveis A dife rença está no valor entre colchetes que determina quantos elementos ele armazenará ou seja em outras palavras determina o seu tamanho ou dimensão Observe no exemplo da Figura 51 int vetor10 Ao declarar o vetor o compilador reserva o espaço solicitado e põem o nome da variável nesse espaço Para declarar um vetor de um determinado tipo basta por tipo nomevetortamanho onde o tipo pode ser qualquer tipo primitivo ou um tipo criado pelo usuário O nome do vetor deve ser sempre algo que represente seu uso no mundo real do problema O ta manho deve ser pré definido não podendo ser alterado em tempo de execução O tamanho do vetor deve ser um número inteiro ou constante pré estabelecido no programa não pode ser uma expressão do tipo int vetorn2 onde n será lido anterior mente esse tipo de declaração é ERRADA Conforme já observado anteriormente uma invocação de nome da variável é possí vel acessar um dado na memória O tipo do valor retornado é igual ao tipo utilizado na declaração da variável O nome da variável também é denominado de uma expressão de referência de memória ou simplesmente de referência de memória No caso de vetores temos uma nova expressão de referência de memória o operador de índice entre Ele utiliza uma referência de memória normalmente uma variável do tipo vetor e um núme ro inteiro para representar o índice Ele retorna uma referência para o elemento correspon dente ao índice O tipo do valor retornado é o mesmo tipo da declaração do vetor Conforme mostrado na Figura 51 o valor armazenado em vetor3 é o valor 16 Porém esse valor seria o elemento 4 para o usuário e não o 3 armazenado Para atribuir o valor 10 na primeira posição do vetor armazenado na posição 0 devemos fazer um comando de atribuição da seguinte forma vetor0 10 Note que o índice zero indica a primeira posição no vetor computacionalmente A ex pressão vetor0 referência a posição de memória correspondente ao elemento de índice 100 zero no vetor Para somar os primeiros três elementos do vetor e armazenar o resultado no quarto elemento do vetor faremos vetor3 vetor0 vetor1 vetor2 Em expressões uma referência indexada a um vetor pode ser usada da mesma forma e nas mesmas posições em que usaríamos variáveis convencionais de mesmo tipo Tudo se passa como se tivéssemos várias variáveis declaradas simultaneamente todas de mes mo tipo e com nomes vetor0 vetor1 e assim por diante É muito comum utilizar a es trutura de repetição for para percorrer todos os elementos de um vetor Por exemplo para imprimir todos os elementos de um vetor de 100 elementos int indice int vetor100 for indice 0 indice 100 indice printfd vetorindice Em geral na programação para ler todos elementos do vetor conforme mostrado na Figura 51 faremos int vetor10 i fori0i10i scanfdvetori entrada de valores pelo usuário o mesmo para efetuar a escrita do vetor fori0i101i printfd vetori printfd vetori exibição dos valores do vetor Lembrese para um vetor de tamanho N indicado pelo problema o vetor irá de 0 até N1 por ser uma estrutura estática utilizamos uma constante com uso da diretiva define N 1000 para usarmos na declaração do vetor no programa principal Supomos que um exercício tenha que trabalhar com a entrada de um inteiro positivo maior que 2 e menor que 1000 para entrarmos com n elementos do tipo inteiro variando de 0 a 100 Neste caso por não sabermos qual o valor inicial utilizase a capacidade máxi ma solicitada pelo problema include stdioh define N 1000 int main int vetorN n i printfEntre com a quantidade de elementos a ser usado de 3 a 1000 101 scanfdn printfEntre com oa valores do vetor fori0ini printf vetor3d i scanfdvetori printf Exibindo o vetor fori0ini printf vetor3d 3divetori return 0 Observe que mesmo que o vetor tenha 1000 espaços de inteiro reservado na memó ria para armazenamento só utilizaremos n posições entrada pelo usuário Isso acontece quando o vetor pode ter tamanho variável em tempo de execução o usuário é quem de finirá quantos elementos serão usados no vetor Quando conhecemos a quantidade de valores exata de um vetor e quais são seus ele mentos podemos declarar e já definir os valores para as posições do vetor Exemplo tipo variáveln elem0 elem1 elem2 elemn1 ou tipo variável elem0 elem1 elem2 elemn1 Neste último ele monta o vetor com tamanho n O acesso aos valores de um vetor temos que tomar cuidado com os limites declarados no vetortamanho máximo do vetor Passar pelo índice n1 de um vetor significa entrar em área não pertencente mais ao vetor podendo ocasionar erros graves ou desconhe cidos Para buscar um valor dentro de um vetor onde seus valores estão em uma ordem qualquer aleatória devemos usar um laço de consulta conforme mostraremos abaixo include stdioh include stdlibh define N 10 10 40 20 15 18 6 32 44 1 33 int main int vetN i x Entrada dos valores do vetor fori0iNi scanfdveti 102 Entrada de um valor que pretendemos buscar no vetor printfEntre com um valor que deseja buscar no vetor scanfdx i0 whileiNxveti laço para buscar um valor no vetor i ifiN printfO valor d nao esta no vetor x else printfO valor d esta na posicao d do vetor xi1 return 0 Para copiar um vetor A em um vetor B não podemos fazer como variáveis simples tipo B A no caso de vetor temos que utilizar um comando de laço for para passar elemen to por elemento do tipo fori0iNi Bi Ai sendo A e B dois vetores de mesmo tipo de dados As buscas em um vetor são controladas pelo tipo de entrada que o vetor teve se os valores estiverem em uma ordem crescente podemos mudar a forma de buscar um valor no vetor da seguinte forma include stdioh include stdlibh define N 10 5 10 15 17 18 20 30 44 50 63 ordenado int main int vetN i x fori0iN1i scanfdveti printfEntre com um valor que deseja buscar no vetor scanfdx i0 whileiNxveti i ifiNxveti printfO valor d nao esta no vetor x else printfO valor d esta na posicao d do vetor xi1 return 0 103 Existem outras formas de busca como a busca binária quando os valores estão orde nados A busca binária procura o elemento central do vetor e compara com o valor de x caso o valor seja menor a busca continua na parte inicial do vetor 1a Metade caso seja maior continuará na parte final do vetor 2a Metade e assim sucessivamente o algoritmo irá quebrar o vetor em 2 partes até alcançar o valor ou fazer inicio fim Exemplo de busca binária include stdioh define MAX 20 int main int vetMAX i x ini fim meio fori0iMAXi scanfdveti fori0iMAX1i printfd veti printfd veti printfEntre com valor procurado scanfdx ini 0 fim MAX1 meio ini fim2 whileini fim meio ini fim2 ifx vetmeio printfvalor encontrado de d esta na posicao d xmeio1 fim 1 else ifxvetmeio fim meio 1 else ini meio 1 iffim 1 printf O valor d nao esta no vetor x return 0 Desta forma o algoritmo de busca binária se torna mais rápido quando N passar de 1000 elementos Por exemplo para N 220 1048576 elementos significa que em 20 consultas no pior caso encontraremos o valor de x caso ele esteja no vetor 104 Um vetor de char é também denominado de string ou cadeia de caracteres Por exem plo um nome pode ser armazenado em um string de tamanho 40 char nomecliente40 Neste caso se o usuário utilizar um nome inferior a 40 caracteres ele será gravado no veto nomecliente colocando depois do último caractere um encerramento que é repre sentado pelo caractere 0 Se o tamanho do nome for 40 ou mais só será gravado 39 ca ractere sendo que na última posição do vetor será colocado o caractere 0 A leitura de uma string não precisa utilizar o endereço representado pelo caracter como fazemos com inteiro char float e outros Neste caso podemos usar scanfsnomecliente onde nomecliente representa o endereço da primeira posição do vetor de char Ou seja é mesmo que escrever nomecliente0 Para ler um nome com espaço e comple to com scanf devemos utilizar a diretiva scanf nomecliente se usarmos só o s quando ocorrer o espaço tipo Joao da Silva ele só lerá Joao e o restante será jogado para as próximas leituras Outro comando que podemos usar para ler string é o comando fget snomecliente 40 stdin já comentado anteriormente Iniciaremos a seguir a estrutura bidimensional matriz 105 3 Estruturas homogêneas bidimensionais matriz A noção de matriz é a generalização imediata da noção de vetor Uma matriz é uma es trutura de vários valores do mesmo tipo armazenados sequencialmente e fazendo uso de um mesmo nome de variável para acessar esses valores Cada elemento da matriz pode ser acessado individualmente através de dois índices com valores inteiros Estes índices poderiam ser interpretados como a linha e a coluna da matriz A linguagem C define uma matriz como um vetor cujos elementos são novamente vetores de mesmo tamanho e tipo Na verdade o número de linhas corresponde ao número de elementos do vetor ex terno e o número de colunas é o tamanho dos vetores internos que constituem cada ele mento dos vetores externos A Figura 52 mostra como a matriz bidimensional é represen tada computacionalmente int matriz410 0 1 2 3 4 5 6 7 8 9 linha010 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 linha110 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 linha210 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 linha310 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 Figura 52 representação de uma matriz 4x10 Todos os conceitos e todas as regras válidas para os vetores também são válidas para as matrizes A matriz tem tamanho fixo definido na declaração As linhas são numeradas de 0 até linhas1 e as colunas de 0 até colunas1 Para colocar o valor 10 por exemplo no inicio da matriz fazemos matriz00 10 A declaração de matrizes obedece a mesma sintaxe que a declaração de vetores exce to pela adição de uma nova dimensão escrita entre colchetes 106 tipo variávellinhascolunas Por exemplo para declarar uma matriz de números inteiros com 4 linhas e 10 colunas int matriz410 A atribuição ou leitura de valores em uma matriz utiliza dois índices O primeiro ele mento é armazenado em matriz00 o segundo em matriz01 e assim por diante até o último elemento que é armazenado em matrizlinhas1colunas1 Para atribuir o valor 3 na linha 2 coluna 5 escrevemos matriz14 3 Note como a linha 2 é numerada como 1 pois começamos a contar a partir do zero Idem a coluna 5 é numerada como 4 Para percorrer os elementos de uma matriz são ne cessárias duas estruturas de repetição for uma dentro da outra O for externo percorre as linhas da matriz o for interno percorre as colunas de uma determinada linha que está fi xada pelo for externo Por exemplo para imprimir todos os elementos de uma matriz 4x10 linha por linha int linha coluna int matriz410 for linha 0 linha 4 linha for coluna 0 coluna 10 coluna printfd matrizlinhacoluna printf Para cada valor de linha fixado pelo for externo entre 0 e 3 o for interno executa var rendo as colunas correspondentes àquela linha de 0 a 9 Assim quando o for interno exe cuta o valor de linha está fixado pelo for externo fazendo com que o printf imprima os vaChamamos de Matriz a todo conjunto de valores dispostos em linhas e colunas Dada uma matriz A denotaremos cada elemento da matriz A por aij onde i é o número da linha e j é o número da coluna desse elemento A 107 Muitas vezes trabalharemos com matriz quadrada onde o número de linhas é igual ao número de colunas Alguns tipos de Matriz serão mostradas a seguir Matriz transposta é um tipo de ma triz trocandose o número da linha pelo número da coluna exemplo Matriz identidade é a matriz quadrada cujos elementos da diagonal principal são iguais a 1 e os demais elementos iguais a zero Matriz Nula quando todos elementos são iguais a zero Matriz triangular inferior quando todos elementos da diagonal principal para baixo são diferentes de 0 os demais são nulos iguais a 0 Mti A matriz triangular superior é quando todos elementos da diagonal principal para cima são diferentes de 0 os abaixo da diagonal são nulos iguais a 0 Matriz Diagonal é quando somente os elementos da diagonal principal são diferente de 0 os demais são 0 D Uma matriz pode sofrer uma multiplicação por um escalar k pré definido sendo que cada elemento da matriz fosse multiplicado pelo escalar k 108 Matriz simétrica é quando os elementos opostos à diagonal principal são iguais o ele mento aij aji A matriz A é simétrica quanto A AT A Matriz Antisimétrica quando os elementos da diagonal principal for nulos e aij aji Ou é o mesmo que dizer que A AT A A igualdade entre duas Matriz A e B é realizado elemento por elemento só será igual se todos elementos de uma matriz NxM ocorrer de aij bij sendo que i varia de 0 até N1 e j variar de 0 até M1 A comparação deve ser realizada com 2 laços um percorrendo as li nhas representado pelo índice i e outro percorrendo as colunas representado pelo ín dice j int main int ANM BNM i j igual 0 for i0iNi forj0jMj ifAij Bij igual 1 return 0 A soma ou subtração entre duas matrizes A e B só podem ocorrer se tiverem os mes mos números de linhas e colunas Já a multiplicação entre duas matrizes A e B só podem ocorrer se o número de colunas de A for igual ao número de linhas de B e a matriz resul tante receberá o número de linhas de A e o número de Colunas de B 109 Neste caso se C AxB sendo que A tem a dimensão de nxp e B tem a dimensão pxm então C terá a dimensão nxm Supondo que as matrizes M1 M2 e M3 se referem a M3 M1xM2 onde M1 M2 e M3 são matriz quadradas de dimensão N int main int M1NNint M2NN int M3NN int i j k int L1 L2 C1 C2 sendo C colunas e L linhas C1 N C2 N L1 N L2 N certo quando a matriz for quadrática fori 0 i L1 i forj 0 j C2 j M3ij 0 fork 0 k C1 k M3ij M1ik M2kj return 0 Como M3 é o resultado de M1 x M2 k toma as ocorrências de C1 ou L2 por isso que ti vemos que testar se essas variáveis são iguais como nossa Matriz é quadrada então isso já acontece As buscas em matriz ocorre da mesma forma que em vetor utilizaremos laços e bus car um determinado valor exige percorrer linhas e depois colunas até encontrar ou até atingir o final de todos elementos da matriz Faremos alguns exercícios que solicitam a busca de um ou vários valores em uma de terminada Matriz Para isso utilizaremos fori para percorrer as linhas da matriz e forj para percorrer as colunas Se encontrar o valor informaremos a linha e coluna caso con trário avisaremos que o valor não está na matriz Para isso utilizaremos uma variável achei 0 e linha 1 e coluna 1 Ao encontrar o valor x na matriz mudaremos achei para 1 e linha será o número da linha e coluna o número da coluna para o usuário que seria linha i1 e coluna j1 110 4 Uso de estruturas heterogêneas registros O uso de registros em C denominado de struct são formas de criarmos tipos de dados heterogêneos que representem a mesma informação do mundo real O comando para criação de um tipo de dado em C é dado por typedef struct int codigo char nomefunc40 char datanasc11 char email60 char cargo30 char dataadmissao11 float salario Empregado Neste caso typedef está definindo um tipo de dados sendo um registro ou um con junto de valores contendo inteiro strings e float e foi chamado de Empregado Neste caso a partir desta criação Empregado pode ser usado no programa como um tipo do usuário Como devemos armazenar os Empregados de uma empresa em uma estrutura de vetor sendo que a empresa possui menos que 1000 funcionários até o presente mo mento mas que tem por exemplo intenção de contratações futuras podendo passar de 1000 funcionários Neste caso podemos criar um tipo de dados para controlar os empre gados da empresa include stdioh include stdlibh include stringh define Nfunc 5000 typedef struct int codigo char nomeemp40 char datanasc11 char email60 char cargo30 111 char dataadmissao11 float salario Empregado gastou 164 bytes typedef struct Empregado funcNfunc int quantidadefunc char Nomeempresa50 char cnpj20 char telempresa15 Empresa 820089 bytes Observe que agora temos um tipo de dados heterogêneo denominado Empresa onde guarda todos os Empregados em um vetor de tamanho 5000 Neste tipo de dados temos as informações básicas da empresa Desta forma teremos um vetor com valores heterogêneos contendo todas informa ções necessárias de um Empregado A quantidade de empregados é o controle desse ve tor ou seja inicialmente essa quantidade será 0 e marcará onde o empregado cadastrado no sistema será guardado no vetor Quando tivermos 1000 empregados a quantidade de empregados marcara 1000 e essa será a posição do 1001o empregado cadastrado no ve tor que está no tipo de dados Empresa Como acessar os valores dentro dos registros struct Inicialmente iremos mostrar como isso acontece Para isso vamos supor que temos que declarar os tipos Empregado e Empresa como fazemos no início da função principal main Empregado func Empresa Emp Empquantidadefunc 0 iniciando o controle de quantidade de funcionário return 0 Quando criarmos um programa para controlar esses dados de uma Empresa e seus funcionários devemos acrescentar funções e procedimentos que veremos na Unidade seguinte Apenas para ilustrar nesta Unidade vamos criar um procedimento para efetuar a leitura de um empregado Para isso devemos passar como parâmetro um Empregado e como iremos alterar seus dados devemos passar como referência ponteiro Neste caso o procedimento seria 112 void lerempregadoEmpregado E printfEntre com o código do empregado scanfdEcodigo getchar printfEntre com o nome do empregado fgetsEnomefunc 40 stdin printfEntre com o data de nascimento do empregado fgetsEdatanasc 15stdin e assim sucessivamente até ler todas informações do funcionário Na função main esse procedimento será chamado da seguinte forma int main Empregado func Empresa Emp lerempregadofunc return 0 Todo controle dos empregados de uma empresa neste caso são realizados com MENU e opções das principais funcionalidades que o usuário deverá ter para atender suas ne cessidades pré estabelecidas No MENU são colocadas as opções de cadastrar um empre gado consultar um empregado gerar folha de pagamento informar o maior salário da empresa ou o menor salário da empresa e assim sucessivamente de acordo com as ne cessidades da empresa para gerar o controle de todos empregados Em Unidades mais a seguir iremos abordar novamente a definição de tipos de dados heterogêneos struct para ilustrar outros exemplos quando formos abordar funções e procedimentos A seguir vamos dar exemplos de como pordemos armazenar em arquivos informa ções que acharmos necessário Temos dois tipos de arquivos para isso texto ou binário Os arquivos textos podem ser lidos fora do programa serve como geração de relatórios ou outras informações para logísticas de controle do usuário O outro arquivo binário é para armazenar grandes volumes de informação de uma só vez e só pode ser lido pelo próprio programa que o gerou 5 Uso de arquivos de armazenamentos Os programas em C utilizam o conceito de fluxo de dados streams para comunicaremse com dispositivos do computador com arquivos em disco ou com outros programas Os fluxos permitem uma padronização das operações de entrada e saída Um conjunto fixo de funções existem para ler e escrever nos fluxos Há um mecanismo para associar fluxos a um dispositivo ou programa Esse modelo de comunicação permite ao programador enviar e ler dados parade diversos dispositivos usando as mesmas funções de ES O Modelo de um fluxo de dados é dado pelas seguintes características O fluxo corresponde a uma abstração implementada por uma área de memória e um conjunto de funções que dão a ideia de existir um fluxo de dados entre um produtor e um consumidor O fluxo funciona como um buffer uma área de dados na memória principal utilizada para guardar dados durante a comunicação entre o produtor e consumidor Funciona também como uma fila o produtor insere dados em uma extremidade do buffer e o consumidor obtém os dados na outra extremidade O modelo de fluxo de dados é dado pela Figura 53 Figura 53 Modelo de Stream O produtor e consumidor podem ser representados pelo programa ou dispositivo de ES Podendo ser o próprio programa que Lê e Escreve ou pode ser lido pelo programa e gerado uma saída para outro dispositivo utilizar 113 Os tipos de Operação do fluxo podem ser Fluxo de Leitura apenas Fluxo de Escrita apenas Leitura e Escrita Quanto ao tipo de acesso pode ser sequencial ou aleatório A seguir veremos exemplos de cada tipo de acesso Quanto ao tipo de dados pode ser apenas texto ou binário O fluxo da linguagem C é criado usando um ponteiro para o tipo FILE definido em stdioh Ex FILE arq FILE é definida como uma struct cujos campos contêm várias informações sobre o fluxo sendo Operações Sobre Fluxos Arquivos Binários Um ponteiro para o buffer que armazena os dados do fluxo Tipo de operação permitida no fluxo Códigos de erro Ponteiros para funções Um indicador da posição atual no buffer Etc A operação de abertura de um arquivo é dada pelo comando fopen Deve ser a primeira operação a ser executada sobre o fluxo e serve para 1 Tentar alocar na memória uma struct FILE para armazenar dados sobre o fluxo 2 Alocar o buffer que armazenará dados do fluxo e armazenar seu endereço na struct FILE correspondente ao fluxo 3 Associar um dispositivo de ES ao fluxo 4 Definir as operações de ES que são permitidas no fluxo 5 Definir o tipo de acesso no fluxo 6 Definir o tipo de dados do fluxo texto ou binário 114 115 A forma geral da operação de abertura do arquivo FILE é dada da seguinte forma FILE f open nome do arquivo modo Onde nomedoarquivo é uma constante string ou uma variável char que armazena o caminho no disco onde se encontra o arquivo E o modo é uma é uma constante string ou uma variável char que descreve o tipo de operação possível no arquivo o tipo de aces so e o tipo de dados O modo de abertura pelo modo sequencial é dado pelas diretivas r de read abre o arquivo para leitura sequencial apenas A função fopen retorna NULL se o arquivo não existir w de write abre o arquivo para escrita sequencial apenas Se o arquivo não existir ele é criado Se existir seu conteúdo original é apagado a de append abre o arquivo somente para escrita Se o arquivo não existir ele é cria do Se existir não é apagado Permite escrever apenas ao final do arquivo Já a operação de abertura no modo aleatório é dado por r abre o arquivo para leitura e escrita Se arquivo não existir retorna NULL O fluxo é de leitura e escrita e acesso aleatório w abre o arquivo para leitura e escrita Se o arquivo não existe ele é criado Se exis te seu conteúdo será apagado O acesso é aleatório a abre o arquivo para leitura e escrita Se o arquivo existir mantém o conteúdo exis tente A leitura pode ser feita de modo aleatório mas a escrita só pode ser feita ao final do arquivo Os modos de abertura de tipos de dados são dados pelas seguintes diretrizes Acrescentandose um b na string de modo indicase que o fluxo é binário Acrescentandose um t na string de modo indicase que o fluxo é um arquivo de texto Na ausência de b e t no modo o arquivo é aberto como arquivo tipo texto Arquivos binários armazenam os dados em formato binário São utilizados para armazenar em disco os dados armazenados em formato binário na memória do computador int floats structs etc Arquivos texto armazenam sequências de caracteres 116 A operação de leitura de arquivo do tipo texto é dado pela função fgetc da seguin te forma O cabeçalho int fgetc File pFile Retorna o próximo caractere de um fluxo tipo texto e avança o ponteiro do ar quivo para o próximo caractere Embora retorne valores da tabela ASCII O tipo retornado é um int porque retor na EOF 1 se o fim do arquivo for encontrado não há um caractere para repre sentar fim de arquivo Por isso a função não pode ser do tipo char pois qual quer um dos 256 valores da tabela ASCII ou 1 podem ser retornados O arquivo deve ter sido aberto em modo texto e com alguma das opções que permite leitura A seguir vamos apresentar um exemplo include stdlibh include stdioh int main FILE pFile int c int n 0 Abrir um arquivo tipo texto apenas para leitura sequencial pFilefopen Arquivotxtrt Testar se o arquivo existe if pFileNULL printfArquivo nao foi encontrado Terinando o programa exit1 Leitura caractere por caractere c fgetc pFile while cEOF putchar c cfgetcpFile Fechando o arquivo fclose pFile return 0 As operações de Leitura de Arquivos do tipo texto com entradas formatadas são da das pela função fscanf 117 O Cabeçalho é dados pelo comando int fscanf FILE arq const char format Tem a mesma funcionalidade da função scanf porém a entrada é feita a partir do arquivo indicado por arq Retorna o número de itens lido se conseguir ler algum dado Se não conseguir ler nenhum dado por causa de um erro na entrada ou por ter encontrado o fim do arquivo retorna EOF O arquivo deve ter sido aberto em modo texto e com alguma das opções que permi te leitura As Operações de escrita em arquivos texto é dada pela função fputc Cabeçalho int fputc int c FILE arq Imprime o caractere passado pelo parâmetro c no arquivo indicado por arq Retorna o mesmo caractere recebido no parâmetro c se conseguir realizar a escrita Retorna EOF caso ocorra um erro durante a escrita O arquivo deve ter sido aberto em modo texto e com alguma das opções que permita a escrita Exemplo Mostrar como copiar um arquivo Arq1 para o arquivo Arq2 include stdioh include stdlibh int main FILE pFile1 FILE pFile2 char linha500 int n 0 pFile1fopen Arquivotxtrt if pFile1NULL printfArquivo nao foi encontrado Terinando o programa exit1 pFile2fopenCopiatxt wt if pFile2NULL printfArquivo de saida nao foi criado Terinando o pro grama exit1 nfscanfpFile1 linha while nEOF fgetcpFile1 para consumir o fprintfpFile2s linha nfscanfpFile1 linha fclose pFile1 fclosepFile2 return 0 A operação de escrita em arquivo Texto é realizada pela função fprintf Cabeçalho int fprintf FILE arq const char formato Tem a mesma funcionalidade da função printf porém a saída é feita a partir do arquivo indicado por arq Retorna o número de caracteres escritos caso consiga realizar a escrita com sucesso Retorna um número negativo em caso contrário O arquivo deve ter sido aberto em modo texto e com alguma das opções que permite escrita Fluxos especiais do tipo texto são dados pelos fluxos Padrões Como dito anteriormente os fluxos permitem padronizar a entrada e a saída de modo que fiquem independentes do dispositivo usado Assim operações semelhantes são feitas tanto para arquivos em disco como para o teclado ou terminal por exemplo Para todos os programas em C mesmo os que não abram arquivos explicitamente são criados alguns fluxos automaticamente Quatro desses fluxos são os seguintes stdin stdout stderr stdprn Detalhamento do fluxo padrão stdin fluxo de entrada padrão geralmente associado ao teclado é utilizado pelas funções de entrada que não usam explicitamente arquivos scanf getchar stdout fluxo de saída padrão geralmente associado ao terminal Utilizado por funções que não usam explicitamente arquivos printf putchar stderr fluxo de mensagens de erro pode ser utilizado para enviar mensagens de erro para um fluxo diferente do stdout stdprn fluxo destinado a impressão ao qual se conecta um impressora O USO dos fluxos padrões são dados da seguinte forma Os quatro fluxos são automaticamente abertos e automaticamente fechados São do tipo texto Equivalência printfUm dois fprintfstdout Um dois escrita scanfd x fscanf stdin d x leitura Impressão de mensagem de erro em stderr printfstderr Nao ha memoria suficiente perrorNao ha memoria suficiente definida na stdioh 119 Saída na impressora padrão fprintf stdprn Um dois O Uso de arquivos binários são dados pelo fluxo de bytes que são contados pelo tipo criado para armazenamento Em um arquivo binário os bytes são transmitidos em uma operação de escrita como estão na memória RAM Assim se um valor do tipo int for gravado em um arquivo binário seus bytes são copiados como estão armazenados e não são tradu zidos em caracteres como o ocorre quando se imprime no formato d da função fprintf De forma análoga durante uma operação de leitura de um arquivo binário os bytes armazenados no arquivo são copiados como estão no arquivo para a memória RAM do computador Dado que é feita uma transmissão de bytes quando o arquivo é binário podese trans ferir grandes blocos de bytes de uma vez entre a memória e o dispositivo de ES No exemplo criado de controle de empregado dado no item anterior se fossemos criar um arquivo binário do tipo Empresa teríamos um fluxo de 5000xnumero de bytes do tipo empregado que seria 164 bytes a quantidade de bytes criada no tipo Empresa dando um total de 820089 bytes Esse será o volume de bytes que esse tipo de arquivo bi nário ira transitar no buffer do computador A operação de escrita em um arquivo binário é dado por fwrite Cabeçalho sizet fwrite const void ptr sizet tam sizet cont FILE arq Transfere tam bytes a partir do endereço ptr da RAM cont vezes para o arquivo cujo fluxo está indicado por arq O indicador de posição do arquivo é deslocado para frente cont tam bytes A função retorna o número de blocos de tamanho tam que foram gravados Se o valor de retorno for diferente do parâmetro cont é porque houve um erro de escrita e a opera ção falhou em transferir a quantidade de blocos especificada em cont Já a operação de leitura em um arquivo binário é dado pela função fread Cabeçalho sizet fread const void ptr sizet tam sizet cont FILE arq Transfere cont blocos de tam bytes do arquivo arq e os armazena a partir do endere ço ptr da RAM O indicador de posição do arquivo é deslocado para frente cont tam bytes A função retorna o número de blocos de tamanho tam que foram lidos Se o valor de retorno for diferente do parâmetro cont é porque o arquivo terminou ou houve um erro de leitura e a operação falhou em transferir a quantidade de blocos especificada em cont 120 Verificando o fim de arquivo em arquivo binário usase a função feof Arquivos binários não podem usar EOF para checar fim de arquivo pois os bytes po dem representar qualquer coisa na memória A escrita de uma variável do tipo char con tendo o valor 1 EOF seria interpretada como fim de arquivo Na linguagem C há uma função para detectar fim de arquivo É a função feof Cabeçalho int feof FILE arq A função retorna um valor diferente de zero se o fim do arquivo foi atingido e zero em caso contrário Apesar de ser necessária para detecção de fim em arquivos binários feof pode ser utilizada também com arquivos texto Já o acesso Aleatório em arquivos é dado com a mudança do indicador de posição do arquivo O indicador de posição de arquivo é um valor que até agora foi utilizado indireta mente a após a abertura do arquivo ele é indica o início do arquivo b Após cada ope ração de leituraescrita ele é avançado de acordo com o número de bytes lidosescritos É possível mudar diretamente o indicador de posição de arquivo através da função fseek Após a mudança é possível ler ou gravar em uma outra posição do arquivo fazendo com que o processamento da leituraescrita deixe de ser sequencial Denominamos esse tipo de acesso a qualquer posição de acesso aleatório A escritaleitura nesse caso só é possível se o arquivo foi aberto no modo acesso alea tório Outra função de acesso aleatório a arquivos é a função fseek Cabeçalho int fseek FILE arq long int desloc int origem O argumento desloc corresponde a número de bytes que o indicador de posição deve ser deslocado em relação a origem A origem pode ser uma das seguintes constantes definidas em stdioh SEEKSET Início do arquivo SEEKCUR Posição atual do indicador de posição SEEKEND Final do arquivo A função fseek retorna zero se executar corretamente e um outro valor em caso con trário Existem outras funções para arquivo como é o caso da função ftell 121 Cabeçalho long int ftell FILE arq Retorna o valor do indicador de posição atual do arquivo cujo ponteiro é indicado por arq Para arquivos binários o valor do indicador corresponde ao número de bytes entre o início do arquivo e a posição atual do indicador Para arquivos texto o valor pode não ter significado mas ainda pode ser usado para voltar à posição atual por guardar o valor atual em uma variável long int e usar futura mente essa variável como parâmetro para fseek Em caso de falha a função retorna 1 Outra função é que retorna erro é a função ferror Cabeçalho int ferror FILE arq Definição Verifica se um erro foi indicado na struct FILE para o fluxo arq Um valor diferente de zero retornado indica que houve algum erro com a última ope ração executada sobre o arquivo O valor de indicação de erro na struct FIlLE é limpado sempre que uma das operações rewind e freopen ocorre sobre o fluxo A função de fluxo fflush Cabeçalho int fflush FILE stream Se fluxo foi aberto para escrita ou se foi aberto para leituraescrita e a última operação foi de escrita a função descarrega o buffer do fluxo no dispositivo de saída a ele associado Se arq for NULL todos os buffers de todos fluxos na situação anterior são descarregados A função não fecha os fluxos Retorna zero se obteve sucesso e EOF em caso contrário Já a função rewind reinicia o arquivo Cabeçalho void rewind FILE arq Faz com que o indicador de posição do arquivo aponte para o início do fluxo arq Função freeopen CabeçalhoFILE freopen const char nomearq const char modo FILE arq Tenta fechar o fluxo atual indicado por arq Reutiliza o fluxo abrindoo com associação ao arquivo especificado em nomearq e no modo especificado na string modo Essa função é especificamente útil para redirecionar a saída padrão dentro do progra ma para um outro dispositivo ou arquivo em disco 122 Se executar com sucesso a função retorna o ponteiro para arq caso contrário retor na NULL O fechamento de fluxo é dado pela função fclose O fechamento de um fluxo consiste em Realizar descarga do conteúdo do buffer no dispositivo de saída Fazer a desvinculação do fluxo com o dispositivo através de chamadas ao siste ma operacional Liberar a struct FILE alocada para representar o fluxo O Cabeçalho da função int fclose FILE stream O Retorno da função de fechamento será Zero se o fluxo foi fechado com sucesso EOF em caso de falha A seguir vamos usar um exemplo para ler e escrever um arquivo binário do tipo Em presa dada no item 54 include stdioh include stdlibh include stringh define Nfunc 5000 typedef struct int codigo char nomeemp40 char datanasc11 char email60 char cargo30 char dataadmissao11 float salario Empregado typedef struct Empregado funcNfunc int quantidadeemp char Nomeempresa50 char cnpj20 char telempresa15 Empresa void Gravarempresa Empresa E grava todo o tipo Empresa FILE fp 123 fp fopen Empresadat wb arquivo para escrita binária apaga e grava tudo de novo if fp NULL printf Erro ao abrir o arquivo aqui pode por a função que inicializa Empresa return 0 else printf Arquivo Binario Empresadat foi criado com sucesso fwriteE sizeofEmpresa 1 fp fclose fp Função responsável por exibir o conteúdo do arquivo Empresadat void CarregarempresaEmpresa E FILE fp fp fopen Empresadat rb if fp NULL return else freadEsizeofEmpresa1fp faz a leitura no arquivo Empresadat e passa para a variável tipo empresa fclosefp fecha o arquivo e copia no buffer da memória RAM como esses procedimentos são usados no programa main int main Empresa emp Empregado func Carregarempresaemp la no fechamento do programa Gravarempresaemp return 0 124 7 Exercícios Iremos colocar 3 exercícios de cada modalidade vista nesta Unidade 71 Exercícios de Vetor E711 Maior Elemento de um vetor Faça um programa que receba vários vetores e informe para cada um deles qual o maior elemento e o indice da primeira ocorrência em que encontrase tal elemento Entrada O programa possui vários casos de testes A primeira de cada caso contem um inteiro N 1 N 10000 representando o tamanho do vetor A segunda linha conterá N inteiros entre 0 e 1000 representando os N elementos do vetor A entrada termina quando N0 Saída O programa gera N linhas de saída com dois inteiros separados por um espaço em branco O primeiro inteiro é o índice da primeira ocorrência do maior elemento do vetor e o segundo inteiro é o maior valor do vetor Após a impressão de cada saída inclusive a úl tima quebre uma linha Casos de Testes Entrada 10 6 54 7 3 73 6 67 23 6 9 5 9 8 7 6 5 8 0 1 2 3 4 5 6 7 0 Saída 4 73 0 9 7 7 125 E712 Maior frequência de uma Nota Dada uma sequência de N notas entre 0 e 10 escreva um programa que exiba o valor da última nota informada e quantas vezes ela apareceu no conjunto O programa deve exi bir ainda a maior nota informada e a posição índice do vetor da sua primeira ocorrência Entrada Na primeira linha há um inteiro N sendo 1 N 10000 representando a quantidade de notas da sequência Não é necessário validar o valor de N na entrada Nas N linhas se guintes haverá um número inteiro entre 0 e 10 inclusive em cada linha Saída O programa gera 2 linhas de saída A primeira linha exibirá a frequência da última nota informada e a segunda linha exibirá a maior nota e a posição índice do vetor da sua pri meira ocorrência seguindo o formato da saída apresentado a seguir Não se esqueça de quebrar uma linha após a última impressão Caso de Teste Entrada 11 5 6 3 4 3 8 7 4 8 6 4 Saída Nota 4 3 vezes Nota 8 indice 5 E7113 Contagem de Elementos únicos em um vetor Elabore um programa que conte o número total de elementos únicos em um vetor de números inteiros Entrada A entrada contém duas linhas A primeira contém um valor inteiro n 5000 que cor responde ao número de elementos que aparecem na segunda linha A segunda linha con tém n valores inteiros separados entre si por um espaço 126 Saída A saída é formada por uma linha contendo um valor inteiro que corresponde ao nú mero de elementos que aparecem apenas uma vez no vetor Após o valor o programa deve imprimir o caractere de quebra de linha Caso de teste Entrada 7 3 6 2 9 2 7 9 Saída 3 72 Exercícios de Matriz 721 Ampulheta O objetivo desse exercício é identificar um conjunto de elementos cuja somatória seja o maior valor entre todos os conjuntos definidos por um padrão na forma de ampulheta em uma matriz de inteiros quadrada e de ordem 6 Cada elemento da matriz está no in tervalo 9 9 Uma ampulheta é formada pelos valores que estão posicionados de acor do com a seguinte configuração a b c d e f g Uma ampulheta é a soma de todos os valores presentes nas respectivas posições Seu programa deve retornar o maior valor entre todos os valores de ampulheta possíveis na matriz Entrada Uma matriz quadrada de ordem 6 Saída Um único inteiro que corresponde à maior soma de todos os valores de ampulheta Após imprimir o valor quebre a linha 127 Caso de Teste Entrada Saída 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 Entrada Saída 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 2 4 4 0 0 0 0 2 0 0 0 0 1 2 4 0 19 E722 Cidade Segura Com o aumento da violência na cidade o prefeito decidiu instalar câmeras de vigilân cia em todas as esquinas A cada mês um mapa atualizado com as câmeras em funcio namento é disponibilizado no site da prefeitura A secretaria de segurança considera que uma esquina é segura se existem câmeras em funcionamento pelo menos duas de suas quatro esquinas Nesta cidade todas as quadras são quadrados de mesmo tamanho Sua tarefa é dado o mapa das câmeras em funcionamento nas esquinas indicar o status de todas as quadras da cidade Entrada A primeira linha da entrada tem um inteiro positivo N 1 N 100 Nas próximas N1 linhas existem N1 números que indicam para cada esquina a presença de uma câme ra em funcionamento ou de uma câmera defeituosa O número 1 indica que existe uma câmera funcionando na esquina enquanto o número zero indica que não há câmera fun cionando Saída A saída é dada em N linhas Cada linha tem N caracteres indicando se a quadra corres pondente é segura ou insegura Se uma quadra é segura mostre o caractere S caso con trário mostre o caractere U Após a última linha não se esqueça de saltar uma linha 128 Caso de Teste Entrada Saída 1 1 0 0 0 U Entrada Saída 2 1 0 0 1 1 0 0 0 1 SU SS Entrada Saída 3 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 SSS SUS SSS E723 Cadê Wally Wally costuma morar em um ambiente representado por uma matriz bidimensional de números inteiros de ordem n x m n linhas e m colunas Ele é único no ambiente e é representado na matriz por quatro números distribuídos da seguinte forma 4 0 1111 0 8 O número 1111 representa a camisa listrada em vermelho e branco e o número 4 re presenta seu gorro das mesmas cores Os números zero e oito representam suas extremi dades A matriz representa um ambiente bidimensional circular Para o índice i0 a celula à esquerda está no índice m1 Para o índice im1 a celula à direita está no índice 0 Para o índice j0 a celula superior está no índice n1 Para o índice jn1 a celula inferior está no índice 0 129 Crie um programa que permita imprimir os índices ij da matriz onde está a camisa do Wally Caso o Wally não estiver na matriz mostre a seguinte mensagem WALLY NAO ESTA NA MATRIZ Na seguinte matriz de 7 linhas e 6 colunas a camisa do Wally está nos índices i3 j0 0 1111 0 1 0 0 0 0 0 0 1111 0 4 0 1 3 45 53 1111 0 89 211 87 0 8 4 56 4 55 98 0 2222 0 11 0 5 0 8 23 8 66 3 Entrada Dois valores inteiros n e m seguidos dos elementos inteiros da matriz de ordem n x m com n3 e m3 Saída Se o Wally estiver na matriz o índice ij da localização do Wally Caso contrário WALLY NAO ESTA NA MATRIZ sem acentos Caso de Teste Entrada Saída 3 7 4 7 7 7 7 7 7 1111 0 7 7 7 7 0 8 7 7 7 7 7 7 1 0 Entrada Saída 5 4 5 5 8 5 5 5 5 5 5 5 5 5 5 5 4 5 5 0 1111 0 4 2 Entrada Saída 3 3 1 4 1 0 1111 0 1 8 1 1 1 130 73 Exercícios de Tipos de Dados heterogêneos E731 Tradutor do Papai Noel tirada de httpswwwurionlinejudgecombrjudgeptproblemsview1763 Nicolau já está bastante cansado e sua memória não é mais a mesma Você como na vegador deverá auxiliar o Papai Noel a gritar a frase Feliz Natal no idioma correto de cada país de que o trenó está sobrevoando Como você é um elfo muito esperto você já criou um pequeno app no seu celular sim elfos tem celular que irá lhe informar a frase no idioma correto dado o nome do país Como o trenó é moderno foi atualizado no ano 2000 ele exibe no painel de navegação o nome do país atual Os dados inseridos no seu app foram País Frase brasil alemanha austria coreia espanha grecia estadosunidos inglaterra australia portugal suecia turquia argentina chile mexico antardida canada irlanda belgica italia libia siria marrocos japao Feliz Natal Frohliche Weihnachten Frohe Weihnacht Chuk Sung Tan Feliz Navidad Kala Christougena Merry Christmas Merry Christmas Merry Christmas Feliz Natal God Jul Mutlu Noeller Feliz Navidad Feliz Navidad Feliz Navidad Merry Christmas Merry Christmas Nollaig Shona Dhuit Zalig Kerstfeest Buon Natale Buon Natale Milad Mubarak Milad Mubarak Merii Kurisumasu Para não correr o risco de informar o nome errado você decidiu testar o aplicativo mais algumas vezes Entrada Você irá testar o seu aplicativo com diversos nomes de países simulando os dados informados pelo painel de navegação do tremô A entrada termina por fim de arquivo Saída O seu aplicativo deverá mostrar na tela a frase no idioma correto Caso ela não esteja cadastrada você deverá exibir a mensagem NOT FOUND para que depois dos testes você possa completar o banco de dados Caso de Teste Entrada urionlinejudge alemanha brasil austria Saída NOT FOUND Frohe Weihnachten Feliz Natal Frohe Weihnachten E732 Ordenação de Dados Uma determinada professora deseja ordenar seus alunos em ordem crescente de idade Escreva um programa em C que leia os dados dos alunos entre eles a data de nascimento e ordene os alunos em ordem crescente de idade Para isso seu programa deve ter uma função ComparaDataNasc que recebe dois parâmetros O primeiro corresponde a uma struct ou um ponteiro para uma struct que contém o dia o mês e o ano de nascimento de uma aluno O segundo parâmetro tem o mesmo tipo de dado do primeiro e contém a data de nascimento do segundo aluno Essa função retorna 1 se o primeiro é mais novo ou tem a mesma idade do segundo aluno e retorna zero em caso contrário Essa função deve ser chamada pela função que ordena os alunos em ordem crescente de idade Entrada A entrada contém apenas um caso de teste A primeira linha da entrada contém um número 1 n 30 que corresponde ao número de alunos da turma Em seguida há n linhas contanto cada uma o nome de um aluno int dia de nascimento de um aluno int mês de nascimento de um aluno int ano de nascimento de um aluno int nome de um aluno no máximo 200 caracteres 132 Saída A saída é formada por n linhas cada uma correspondendo ao um aluno ordenadas em ordem crescente de idade dos alunos Cada linha deve ter o seguinte formato Matric m Nome n Data Nasc ddmmaa onde m é a matricula de um aluno n o seu nome e dd mm e aa são respectivamente o dia o mês e o ano do seu nascimento Caso de Teste Entrada Saída 5 12345 12 07 1978 Felizbina Freitas 23489 11 03 2009 Joao Feliz da Tristeza 98762 05 12 1976 Maria Batista de Souza 34561 11 07 1978 Roberto de Assis 34599 07 05 1976 Luiz Alberto Ferreira Matric 23489 Nome Joao Feliz da Tristeza Data Nasc 1132009 Matric 12345 Nome Felizbina Freitas Data Nasc 1271978 Matric 34561 Nome Roberto de Assis Data Nasc 1171978 Matric 98762 Nome Maria Batista de Souza Data Nasc 5121976 Matric 34599 Nome Luiz Alberto Ferreira Data Nasc 751976 Entrada Saída 10 12345 12 07 1978 Felizbina Freitas 23489 11 03 2009 Joao Feliz da Tristeza 98762 05 12 1976 Maria Batista de Souza 34561 11 07 1978 Roberto de Assis 34599 07 05 1976 Luiz Alberto Ferreira 43125 1 07 1978 Flavio Antonio 77889 11 07 2009 Luiz Antonio Silva 55443 12 07 1977 Laura Oliveira 98765 04 05 1997 Fernando Antonio 90891 08 06 2000 Luiza Maria Matric 77889 Nome Luiz Antonio Silva Data Nasc 1172009 Matric 23489 Nome Joao Feliz da Tristeza Data Nasc 1132009 Matric 90891 Nome Luiza Maria Data Nasc 862000 Matric 98765 Nome Fernando Antonio Data Nasc 451997 Matric 12345 Nome Felizbina Freitas Data Nasc 1271978 Matric 34561 Nome Roberto de Assis Data Nasc 1171978 Matric 43125 Nome Flavio Antonio Data Nasc 171978 Matric 55443 Nome Laura Oliveira Data Nasc 1271977 Matric 98762 Nome Maria Batista de Souza Data Nasc 5121976 Matric 34599 Nome Luiz Alberto Ferreira Data Nasc 751976 E733 Mercado tirado de httpswwwurionlinejudgecombrjudgeptproblemsview1281 Dona Parcinova costuma ir regularmente à feira para comprar frutas e legumes Ela pe diu então à sua filha Mangojata que a ajudasse com as contas e que fizesse um progra ma que calculasse o valor que precisa levar para poder comprar tudo que está em sua lis ta de compras considerando a quantidade de cada tipo de fruta ou legume e os preços destes itens Entrada A primeira linha de entrada contém um inteiro N que indica a quantidade de idas à fei ra de dona Parcinova que nada mais é do que o número de casos de teste que vem a se guir Cada caso de teste inicia com um inteiro M que indica a quantidade de produtos que estão disponíveis para venda na feira Seguem os M produtos com seus preços respectivos 133 por unidade ou Kg A próxima linha de entrada contém um inteiro P1 P M que indi ca a quantidade de diferentes produtos que dona Parcinova deseja comprar Seguem P li nhas contendo cada uma delas um texto com até 50 caracteres e um valor inteiro que indicam respectivamente o nome de cada produto e a quantidade deste produto Saída Para cada caso de teste imprima o valor que será gasto por dona Parcinova no seguin te formato R seguido de um espaço e seguido do valor com 2 casas decimais confor me o exemplo abaixo Caso de Teste Entrada 2 4 mamao 219 cebola 310 tomate 280 uva 273 3 mamao 2 tomate 1 uva 3 5 morango 670 repolho 112 brocolis 171 tomate 280 cebola 281 4 brocolis 2 tomate 1 cebola 1 morango 1 Saída R 1537 R 1573 134 PARA O PROFESSOR ACOMPANHAR Resolução dos problemas R711 Maior Elemento include stdioh include stdlibh int maiorint v int n int i iMaior foriMaior0 i1 in i ifvi viMaior iMaior i return iMaior int main int v n iMaior i scanfd n whilen0 v int mallocnsizeofint fori0 in i scanfd vi iMaior maiorv n printfd d iMaior viMaior freev scanfd n return 0 135 R712 Maior frequência de uma nota em um vetor include stdioh int main int n iMaior maior i v0 int vetFreq11 0 int iApareceu11 0 int apareceu11 0 scanfd n fori0 in i scanfd v ifapareceuv iApareceuv i apareceuv 1 vetFreqv fori10 i0 apareceui i printfNota d d vezes Nota d indice d v vetFreqv i iApareceui return 0 136 R713 Contagem de Elementos únicos em um vetor include stdioh define MAX 1000 int main int n i j int flag counter 0 int vecMAX scanfd n lendo os elementos for i 0 i n i scanfd veci iterando cada elemento do vetor pelo mesmo vetor de um elemen to a frente até o ultimo for i 0 i n i flag 1 for j 0 j n j agora verificaremos se existe algum elemento igual a veci se sim flag será igual a 0 if i j veci vecj flag 0 break if flag counter printfd counter return 0 137 R721 Ampulheta include stdioh include stdlibh int maiorAmpulheta int M6 int i j r n6 int max 97 a ampulheta eh formada por 7 elementos O menor valor para cada elemento eh 9 fori0 in2 ii1 forj0 jn2 jj1 r Mij Mij1 Mij2 Mi1j1 Mi2j Mi2j1 Mi2j2 ifmaxr maxr return max int main Leitura dos elementos da matriz int i j n6 max int M66 fori0 in ii1 forj0 jn jj1 scanfd Mij Processamento principal max maiorAmpulhetaM printfd max return 0 138 R722 Cidade Segura include stdioh include stdlibh int main int n i j int map scanfd n map int mallocn1 sizeofint fori 0 i n1 i mapi int mallocn1 sizeofint fori0 in1 i forj0 jn1 j scanfd mapij fori0 in i forj0 jn j ifmapijmapij1mapi1jmapi1j12 printfS else printfU printf return 0 139 R723 Cadê Wally include stdioh include stdlibh int limitar int indice int limite if indice1 return limite1 if indicelimite return 0 return indice void acharWally int M int n int m int i j wi1 wj1 for i0 in wi1 ii1 for j0 jm wj1 jj1 if Mij1111 Milimitarj1 m0 Milimitarj1 m0 Mlimitari1 nj4 Mlimi tari1 nj8 wi i wj j if wi1 printfd dwiwj else printfWALLY NAO ESTA NA MATRIZ int main Leitura dos elementos da matriz int i j M n m 140 scanfd d n m M int mallocn sizeofint fori 0 i n i Mi int mallocm sizeofint fori0 in ii1 forj0 jm jj1 scanfd Mij Processamento principal acharWallyM n m return 0 R731 Tradutor de Papai Noel include stdioh include stringh typedef struct char nome20 char traducao50 Pais int searchPais vint tamchar key retorna 1 se n achar a chavenome do pais e o índice do pais se achar int i fori0i24i ifstrcmpvinomekey0 break ifi24 return 1 return i 141 int main Pais paises24brasilFeliz Natal alemanhaFrohliche Weihnachten austriaFrohe Weihnacht coreiaChuk Sung Tan espanhaFeliz Navidad greciaKala Christougena estadosunidosMerry Christmas inglaterraMerry Christmas australiaMerry Christmas portugalFeliz Natal sueciaGod Jul turquiaMutlu Noeller argentinaFeliz Navidad chileFeliz Navidad mexicoFeliz Navidad antardidaMerry Christmas canadaMerry Christmas irlandaNollaig Shona Dhuit belgicaZalig Kerstfeest italiaBuon Natale libiaBuon Natale siriaMilad Mubarak marrocosMilad Mubarak japaoMerii Kurisumasu int i char chave20saida50 short verif while scanfschaveEOF verifsearchpaises24chave ifverif0 printf NOT FOUND else printfs paisesveriftraducao 142 R732 Ordenação de Datas include stdioh include mathh include stringh include stdlibh define NUMALUNOS 30 typedef struct data int dia int mes int ano TData typedef struct aluno int matricula char nome TData nascimento TAluno int comparaSeMaisNovoTAluno a1 TAluno a2 void ordenaTAluno vet int n int copiaNomechar buf TAluno aluno void imprimeTAluno vet int N int main char buffer1000 int N i0j TAluno vetNUMALUNOS scanfd N for i0iNi scanfd vetimatricula scanfd vetinascimentodia scanfd vetinascimentomes scanfd vetinascimentoano scanf buffergetchar Chama funcao para alocar espaco suficiente para arma zenar o nome e copialo do buffer para o campo nome da struct de um aluno if copiaNomebufferveti printfO programa nao pode ser executado por fal 143 ta de memoria exit1 ordenavet N imprimevet N return0 int comparaSeMaisNovoTAluno a1 TAluno a2 if a1nascimentoanoa2nascimentoano se ano do a1 ano do a2 a1 mais novo que a2 return1 ifa2nascimentoano a1nascimentoanoa1 nao e mais novo aque a2 return0 entao a1a2 if a1nascimentomesa2nascimentomes return 1 apesar de nascerem no mesmo ano a1 nasceu alguns meses depois de a2 if a2nascimentomesa1nascimentomes return 0 apesar de nascerem no mesmo ano a2 nasceu alguns meses depois de a1 entao a1 nao e o mais novo Nesse ponto do codigo a1 e a2 nasceram no mesmo ano e no mesmo mes o dia de nascimento vai desempatar ifa1nascimentodia a2nascimentodia a1 é mais novo ou tem a mesma idade de a2 return1 a2 e definitivamente mais novo return0 void ordenaTAluno vet int n 144 int ij indMenor TAluno aux for i0 in i indMenori for ji1 jn j ifcomparaSeMaisNovovetjvetindMenor indMenorj auxveti vetivetindMenor vetindMenoraux void imprimeTAluno vet int N int i for i0 iNi printfMatric d Nome s Data Nasc ddd vetimatri cula vetinome vetinascimentodia vetinascimentomes veti nascimentoano int copiaNomechar buf TAluno aluno alunonomecharmallocsizeofcharstrlenbuf1 if alunonome return0 strcpyalunonomebuf return1 145 R733 Mercado includestdioh includestringh define MAX 2000 struct prodFeira char prod51 float preco struct prodCompra char prod51 int quant float pesquisaProdstruct prodFeira f int tam char s int i for i0 itam i ifstrcmpsfiprod0 return fipreco return00 int main struct prodFeira feiraMAX struct prodCompra compra int icasos quantOferta quantCompra float valorTot scanfd casos getchar printfCasos d casos while casos scanfd quantOfertagetchar Le produtos a venda for i0 iquantOferta i scanfs feiraiprod scanff feiraipreco getchar printfs f feiraiprod feiraipreco scanfd quantCompra getchar 146 valorTot00 Le produtos a serem comprados printfquantOferta d quantOferta printfquantCompra d quantCompra for i0 iquantCompra i scanfs compraprod scanfd compraquant getchar printfCompras s d compraprod compra quant valorTot pesquisaProdfeira quantOferta com praprodcompraquant printfR 2f valorTot UNIDADE 6 FUNÇÕES 148 1 Introdução Nesta Unidade estaremos introduzindo o uso de Funções e Procedimentos de forma a ensinar a modularização de um programa Bem como trabalha com as passagens de pa râmetros e suas práticas reais Toda função ou procedimento são distintos pelo tipo de re turno no caso de procedimento não retorna nada inicia com void nomeprocedimen toparâmetros Já a função retorna um tipo de dados pré existente podendo ser um tipo primitivo ou um tipo criado pelo usuário Também iremos mostrar a funcionalidade de um programa com suas principais fun ções e procedimentos que servem para atender a demanda do usuário Uma funcionali dade é uma operação que será necessário no programa para suprir os requisitos estipula dos pelo usuário como cadastrar consultar exibir etc Leitura para entender esta Unidade Thomas Cornem e outros Algoritmos Teoria e Prática 3a Edição Editora LTC 2012 149 2 Funções São também denominadas subprogramas que tem o objetivo de retornar um deter minado valor ao final de sua execução para o subprograma chamador A função é uma forma de separar tipos de execução de funcionalidades únicas visando deixar o progra ma mais fácil de ser entendido Existem bibliotecas com várias funções que já utilizamos como por Exemplo na biblioteca mathh temos as funções x sqrtyac função que calcula a raiz quadrada de um valor x powery 2 função que potencializa o valor y em 2 ou outro valor Toda função pode ser chamada de um procedimento colocando a função na atribui ção de igualdade de uma variável do mesmo tipo que ela retorna ou em uma saída de re sultado como por exemplo printfO valor da área de um triangulo será 2f areatrianguloab Existem funções recursivas que resolvem problemas recursivamente como é o caso do Fatorial de n A recursividade é uma forma da função chamar ela própria durante a sua exe cução porém temos que tomar cuidado sempre que sua ordem de grandeza ultrapasse a Ordem quadrática pois pode dar estouro de pilha de execução No caso do calculo de Fa torial recai na ordem de n Exemplo de uma função recursiva int fatorialint n ifn1 return 1 else return nfatorialn1 Para cada função recursiva existe formas iterativas de executar caso seja menos com plexo No caso da função recursiva do calculo de fatorial de n sua execução é a mesma or dem de calculo de fatorial de maneira iterativa utilizando for A função deve resolver apenas um problema simples e que tenha que retornar um re sultado dessa resolução Toda função possui uma fórmula geral para ser declarada tipodedado nomedafuncaotipo parâmentro1tipo parâmetron comandos return valor de retorno do mesmo tiipodedado 150 Toda função deve ter um tipo de dado de retorno Os parâmetros podem complemen tar as operações de uma função Quando uma função não tem parâmetros basta colocar sem nada dentro Os parâ metros em geral são valores que transitam do local que chama a função para a função e podendo ter retorno pelo parâmetro quando o mesmo for passado por referência Uma função pode ser invocada em um determinado procedimento ou função da se guinte forma variávelint funçãoparâmetros onde essa função retorno valor inteiro Quando um parâmetro é passado por referência utilizamos ponteiro na invocação é passado a variável com um simbolo endereço de Caso seja passado apenas por valor o parâmetro é passado simplesmente com o nome da variável No corpo da função o mesmo acontece quando passamos um parâmetro por referên cia colocamos o simbolo que representa um ponteiro de uma variável Int funçaoint a comandos returnnvariavelint Na função se a variável a for modificada na função ela muda diretamente no procedi mento que a chamou por isso passamos a referência da variável Veremos mais exemplos nos exercícios 151 3 Procedimentos Um procedimento é um subprograma composto por uma sequência de comandos iniciando com as declarações das variáveis que serão utilizadas no procedimento inician do com o nome do procedimento um conjunto de parâmetros opcionais e pode reali zar qualquer tipo de processamento previsto em sua construção As variáveis os tipos e as constantes declaradas dentro de um procedimento só são acessíveis no corpo do pro cedimento São chamadas variáveis locais Em um Programa as variáveis tipos e constan tes declaradas logo após o identificador do programa são acessíveis e visíveis dentro de qualquer procedimento que esteja sendo usado pelo programa São chamadas variáveis Globais Ao se construir um procedimento evite o uso de variáveis globais procure refe renciar e utilizar apenas as variáveis locais e as variáveis passadas por parâmetros Isso con tribui com a manutenção do procedimento sem afetar outras partes do programa e da mesma forma as variáveis globais poderão ser modificadas sem que haja efeitos colaterais nos procedimentos quando necessário de seu uso Os procedimentos em C são semelhantes à função porém não existe retorno de valo res por isso usamos o tipo void para definir que não retorna nada O procedimento tem o papel de executar uma ação no programa e retornar com resultados se houver passa dos por parâmetros porém pode ser apenas a ação de executar uma tarefa sem necessi dade de ter valores modificados São muito característicos em programas completos para realizar tarefas como cadastrar remover consultar exibir entre outros Exemplo de proce dimento void MENU printf M E N U printf1 Cadastrar printf2 Remover printf8 Sair do Programa printfEntre com a opção 152 Em geral os procedimentos contribuem para diminuir os blocos de comandos no pro grama principal Também facilita muito a leitura do programa como um todo Contribui também com o reuso de código pois muitos procedimentos ou funções fazem uma tare fa específica e muitas vezes uma separação do programa em partes blocos que possam ser logicamente compreendidos de forma isolada As principais vantagens em utilizar procedimentos ou funções é tornar o código reuti lizável ou até fazer reuso de uma ou mais funções e procedimentos já feitos por outros de senvolvedores Facilitar muitas vezes na manutenção do software quando apenas um mó dulo do programa procedimento que deve ser modificado sem afetar os demais códigos E evitar que um determinado trecho de um código se repita várias vezes no programa Todo procedimento possui uma fórmula geral para ser declarada void nomedoprocedimentotipo parâmentro1tipo parâmetron comandos No caso de procedimento não existe um valor de retorno Os parâmetros em um pro cedimento podem ser por valor ou por referência Por referência é quando os seus valores sofrerem alteração no corpo do procedimento e tiver que levar essa alteração para o local que efetuou a chamada do procedimento No main o procedimento é chamado apenas com o nome do procedimento e seus respectivos parâmetros Ex int main Menu chamada de um procedimento return 0 Repare que a invocação do procedimento é apenas escrever o nome do procedimen to e passar seus respectivos parâmetros quando for o caso Não é necessário ter uma va riável para receber o valor passado 153 4 Funcionalidades de um programa Todos programas ao ser construído devem ter uma análise de requisitos do mesmo levantando quais serão os tipos de funcionalidades que serão necessárias para atender as necessidades do usuário As funcionalidades por exemplo são ações que o programa se propõem fazer Em geral as principais funcionalidades são ligadas às regras de negócio da empresa como Cadastrar consultar emitir relatório entre outros As funcionalidades de um programa são apresentadas em forma de Menu para que o usuário possa realizar determinadas tarefas Pode existir um requisito não funcional que deve ser desenvolvido para atender um requisito funcional Por exemplo verificar se um numero de CPF está correto é um requisito não funcional que é desenvolvido porém o usuário não vê no funcionamento deste Mas precisa entrar com o CPF válido para efetuar seu cadastro no sistema Portanto Efetuar o Cadastro do Cliente é um requisito funcional que usa o requisito não funcional de Validar CPF As funcionalidades do sistema ou programa são pré definidas no projeto do sistema UML ou em uma notação qualquer A mais utilizada é o diagrama de casos de usos que define os atores usuários e quais funcionalidades eles irão participar no sistema Após le vantar e descrever todas funcionalidades e fazer uma elicitação de seu significado no mun do real passa para a próxima etapa que é ageração das etapas que elas acontecem e sua sequência de execução que são detalhados no diagrama de sequência ou colaboração As funcionalidades são muito importante para determinarmos um sub projeto por exemplo em um sistema muito complexo podemos criar vários sub projetos como Admi nistrativo Financeiro Acadêmico Manutenção entre outros Dentro desses sub projetos podemos ter atores específicos para gerar modificações da informação em cada sub pro jeto e suas funcionalidades características de cada sub projeto como por exemplo no sis tema financeiro o pessoal da contabilidade efetua pagamentos da empresa recebe paga mentos de clientes já na parte administrativas o secretário ou administrador pode efetuar o cadastro de um empregado efetuar matricula dos alunos cadastrar os docentes em um determinado curso etc Já no sub projeto acadêmico o coordenador pode cadastrar dis ciplinas registrar um docente em uma ou mais disciplinas ou turmas cancelar a matricula 154 de uma aluno em uma determinada disciplina etc O docente poderá lançar notas faltas para os alunos emitir um plano de aula etc E assim todas as características de cada sub projeto são analisados na etapa inicial criando os seus respectivos Casos de Usos A Figura 61 apresenta um exemplo de caso de uso mostrando os atores usuários do sistema e suas respectivas funcionalidades Figura 61 Exemplo de Casos de Usos de um sistema de vendas As Funcionalidades View Items Make Purchase Complete Checkout Log in Atores Customer Authentication Identity Provider Credit Payment Service sistema e PayPal sistema de pagamento Para entender o uso da UML aconselho a leitura do Livro UML Linguagem de Modelagem Unificada Rumbaugh J Jacobson I Booch G The Unified Modeling Language Reference Manual AddisonWesley 1999 155 5 Exercícios Os Exercícios a seguir servem para ilustrar o uso de Funções e Procedimentos e um úl timo que seria para geração de um projeto mostrando suas principais funcionalidades 51 Funções E61 Quermesse Os alunos de Engenharia do último ano resolveram organizar uma quermesse para ar recadar fundos para a festa de formatura A festa prometia ser um sucesso pois o pai de um dos formandos Gustavo dono de uma loja de informática decidiu doar um compu tador para ser sorteado entre os que comparecessem Os alunos prepararam barracas de quentão pipoca doces ensaiaram a quadrilha e colocaram à venda ingressos numera dos sequencialmente a partir de 1 até 1000 O número do ingresso serviria para o sorteio do computador Ficou acertado que Teófilo decidiria o método de sorteio em princípio o sorteio seria claro computadorizado O local escolhido para a festa foi o ginásio da esco la A entrada dos participantes foi pela porta principal que possui uma roleta onde passa uma pessoa por vez Na entrada um funcionário inseriu em uma lista no computador da escola o número do ingresso na ordem de chegada dos participantes Depois da entra da de todos os participantes Gustavo começou a trabalhar no computador para preparar o sorteio Verificando a lista de presentes notou uma característica notável havia apenas um caso em toda a lista em que o participante que possuía o ingresso numerado com i havia sido a iésima pessoa a entrar no ginásio Teófilo ficou tão encantado com a coin cidência que decidiu que o sorteio não seria necessário esta pessoa seria o ganhador do computador Tarefa Conhecendo a lista de participantes por ordem de chegada sua tarefa é determinar o número do ingresso premiado sabendo que o ganhador é o único participante que tem o número do ingresso igual à sua posição de entrada na festa Você deve escrever uma fun ção do tipo int que retorne o índice da pessoa sorteada 156 Entrada A entrada é composta de vários conjuntos de teste A primeira linha de um conjunto de teste contém um número inteiro positivo N N 1000 que indica o número de parti cipantes da festa A linha seguinte contém a sequência em ordem de entrada dos N in gressos das pessoas que participaram da festa O final da entrada é indicado quando N 0 Para cada conjunto de teste da entrada haverá um único ganhador Saída Para cada conjunto de teste da entrada seu programa deve produzir três linhas A pri meira linha identifica o conjunto de teste no formato Teste n onde n é numerado a par tir de 1 A segunda linha deve conter o número do ingresso do ganhador conforme deter minado pelo seu programa A terceira linha deve ser deixada em branco A grafia mostrada no Exemplo de Saída abaixo deve ser seguida rigorosamente Casos de Testes Entrada 4 4 5 3 1 10 9 8 7 6 1 4 3 2 12 10 20 20 19 18 17 16 15 14 13 69 11 10 12 8 7 6 5 4 3 2 1 30 200 300 400 500 1 2 3 4 5 6 7 8 9 0 16 200 300 400 500 1 2 3 4 5 6 7 8 9 0 30 0 Saída Teste 1 3 Teste 2 10 Teste 3 12 Teste 4 30 157 E62 Fibonacci recursivo Faça um programa que dados os termos iniciais da sequência de Fibonacci calcule o nésimo número da sequência Uma sequência é denominada sequência de Fibonacci se gue todos os seus elementos são calculados pela soma de seus dois elementos anteces sores Exemplo Fn Fn1 Fn2 Para t1 1 e t2 1 temos Ft1 t2 F1 1 1 1 2 3 5 8 13 21 Por exemplo o quarto e o sétimo termos da sequência F1 1 são 3 e 13 respecti vamente Você deve implementar a função Retorna o nésimo termo da sequência de Fibonacci param t1 primeiro termo da sequência param t2 segundo termo da sequência param n a posição do termo desejado da sequência return o valor do nésimo termo da sequência int fibonacci int t1 int t2 int n Entrada O programa deve ler os dois termos iniciais t1 e t2 e a posição n do termo a ser retorna do pela função Saída O programa deve apresentar uma linha com o valor do nésimo termo da sequência Caso de teste Entrada Saída 3 8 5 30 10 10 5 50 2 2 19 8362 E63 Número Perfeito Dado um número n inteiro e positivo dizemos que n é perfeito se n for igual à soma de seus divisores positivos diferentes de n Construa um programa que leia um número inteiro n apresenta a soma dos divisores de n e verifica se o número informado é perfei to ou não 158 Escreva uma função somaDivisores que receba como parâmetro um número inteiro e retorne a soma dos divisores desse número excluindo o próprio número como divisor de si mesmo Seu programa deve chamar a função somaDivisores para resolver o problema Entrada O programa deve ler um número inteiro n Saída O programa deve apresentar uma linha contendo o texto n d1 d2 d3 dk x MENSAGEM onde n é o número lido di são os divisores de n em ordem crescente x é a soma dos divisores e MENSAGEM é a mensagem NUMERO PERFEITOou NUMERO NAO E PERFEITO Observação Suponha que o usuário sempre fornecerá um número maior que 1 Casos de Teste Entrada Saída 6 6 1 2 3 6 NUMERO PERFEITO 12 12 1 2 3 4 6 16 NUMERO NAO E PERFEITO E64 Valor em Notas e Moedas Escreva um algoritmo par ler um valor em reais e calcular qual o menor número pos sível de notas de R 100 R 50 R 10 e moedas de R 1 em que o valor lido pode ser de composto O programa deve escrever a quantidade de cada nota e moeda a ser utilizada Você deve escrever uma função converteEmNotasMoedas que possui 5 parâmetros O primeiro parâmetro corresponde ao valor inteiro a ser convertido em notas e moedas o segundo parâmetro corresponde ao número de notas de 100 o terceiro corresponde ao número de notas de 50 o quarto corresponde ao número de notas de dez e o quinto pa râmetro corresponde ao número de moedas de 1 Real Seu programa deve chamar essa função para resolver o problema proposto Entradas O programa deve ler uma única linha na entrada contendo um valor em Reais Consi dere que somente um número inteiro seja fornecido como entrada O programa deve imprimir quatro frases uma em cada linha NOTAS DE 100 X NOTAS DE 50 Y NOTAS DE 10 Z MOEDAS DE 1 W onde X Y Z e W correspondem às quantidades de cada nota ou moeda necessárias para corresponder ao valor em Reais dado como entrada Após cada quantidade o programa deve imprimir um caractere de quebra de linha Caso de Teste Entrada 46395 Entrada 463 NOTAS DE 100 463 NOTAS DE 50 1 NOTAS DE 10 4 MOEDAS DE 1 5 E65 Ordenação por dados Uma determinada professora quer ordenar seus alunos em ordem crescente de idade Escreva um programa em C que leia os dados dos alunos entre eles a data de nascimento e ordene os alunos em ordem crescente de idade Para isso seu programa deve ter uma função ComparaDataNasc que recebe dois parâmetros O primeiro corresponde a uma struct ou um ponteiro para uma struct que contém o dia o mês e o ano de nascimento de um aluno O segundo parâmetro tem o mesmo tipo de dado do primeiro e contém a data de nascimento do segundo aluno Essa função retorna 1 se o primeiro aluno é mais novo ou tem a mesma idade do segundo aluno e retorna zero em caso contrário Essa função deve ser chamada pela função que ordena os alunos em ordem crescente de idade Entradas A entrada contém apenas um caso de teste A primeira linha da entrada contém um número inteiro n 1 n 30 que corresponde ao número de alunos da turma Em seguida há n linhas contendo cada uma a matrícula de um aluno int o dia de nascimento de um aluno int o mês de nascimento de um aluno int o ano de nascimento de um aluno int o nome de um aluno no máximo 200 caracteres 160 Saída A saída é formada por n linhas cada uma correspondendo ao um aluno ordenadas em ordem crescente de idade dos alunos Cada linha deve ter o seguinte formato Matric m Nome n Data Nasc ddmmaa onde m é a matricula de um aluno n o seu nome e dd mm e aa são respectivamente o dia o mês e o ano do seu nascimento Caso de teste Entrada 5 12345 12 07 1978 Felizbina Freitas 23489 11 03 2009 Joao Feliz da Tristeza 98762 05 12 1976 Maria Batista de Souza 34561 11 07 1978 Roberto de Assis 34599 07 05 1976 Luiz Alberto Ferreira Saída Matric 23489 Nome Joao Feliz da Tristeza Data Nasc 1132009 Matric 12345 Nome Felizbina Freitas Data Nasc 1271978 Matric 34561 Nome Roberto de Assis Data Nasc 1171978 Matric 98762 Nome Maria Batista de Souza Data Nasc 5121976 Matric 34599 Nome Luiz Alberto Ferreira Data Nasc 751976 161 Resoluções dos Exercícios R61 Quermesse includestdioh includestdlibh includemathh int sorteadaint quant int main int i N teste1 scanfd N whileN printfTeste d teste printfd sorteadaN scanfdN return0 int sorteadaint quant int i achou n for i1 iquant i scanfdn if in achoui returnachou 162 R62Fibonacci include stdioh Retorna o nésimo termo da série de Fibonacci param t1 primeiro termo da série param t2 segundo termo da série param n a posição do termo desejado da série return o valor do nésimo termo da série int fibonacci int t1 int t2 int n int s ifn1 return t1 ifn2 return t2 whilen2 s t1t2 t1 t2 t2 s n return s int main int n t1 t2 scanfd d d t1 t2 n printfd fibonaccit1t2n return 0 163 R63 Valor em Notas e Moedas Procedimentos include stdioh void converteEmNotasMoedasint valor int n100 int n50 int n10 int m1 int resto n100valor100 restovalor100 n50resto50 restoresto50 n10resto10 m1resto10 return int main int valor n100 n50 n10 m1 scanfdvalor converteEmNotasMoedasvalor n100 n50 n10 m1 printfNOTAS DE 100 d n100 printfNOTAS DE 50 d n50 printfNOTAS DE 10 d n10 printfMOEDAS DE 1 d m1 return 0 164 R64 Ordenação por Datas include stdioh include mathh include stringh include stdlibh define NUMALUNOS 30 typedef struct data int dia int mes int ano TData typedef struct aluno int matricula char nome TData nascimento TAluno int comparaSeMaisNovoTAluno a1 TAluno a2 void ordenaTAluno vet int n int copiaNomechar buf TAluno aluno void imprimeTAluno vet int N int main char buffer1000 int N i0j TAluno vetNUMALUNOS scanfd N for i0iNi scanfd vetimatricula scanfd vetinascimentodia scanfd vetinascimentomes scanfd vetinascimentoano scanf buffergetchar Chama funcao para alocar espaco suficiente para arma zenar o nome e copialo do buffer para o campo nome da struct de um aluno if copiaNomebufferveti printfO programa nao pode ser executado por fal 165 ta de memoria exit1 ordenavet N imprimevet N return0 int comparaSeMaisNovoTAluno a1 TAluno a2 if a1nascimentoanoa2nascimentoano se ano do a1 ano do a2 a1 mais novo que a2 return1 ifa2nascimentoano a1nascimentoanoa1 nao e mais novo aque a2 return0 entao a1a2 if a1nascimentomesa2nascimentomes return 1 apesar de nascerem no mesmo ano a1 nasceu alguns meses depois de a2 if a2nascimentomesa1nascimentomes return 0 apesar de nascerem no mesmo ano a2 nasceu alguns meses depois de a1 entao a1 nao e o mais novo Nesse ponto do codigo a1 e a2 nasceram no mesmo ano e no mesmo mes o dia de nascimento vai desempatar ifa1nascimentodia a2nascimentodia a1 é mais novo ou tem a mesma idade de a2 return1 a2 e definitivamente mais novo return0 void ordenaTAluno vet int n 166 int ij indMenor TAluno aux for i0 in i indMenori for ji1 jn j ifcomparaSeMaisNovovetjvetindMenor indMenorj auxveti vetivetindMenor vetindMenoraux void imprimeTAluno vet int N int i for i0 iNi printfMatric d Nome s Data Nasc ddd vetimatri cula vetinome vetinascimentodia vetinascimentomes veti nascimentoano int copiaNomechar buf TAluno aluno alunonomecharmallocsizeofcharstrlenbuf1 if alunonome return0 strcpyalunonomebuf return1 UNIDADE 7 DESENVOLVIMENTO DE ALGORITMOS POR REFINAMENTOS SUCESSIVOS 168 1 Introdução Nesta Unidade iremos estudar como estruturar um programa complexo realizando refinamentos sucessivos de forma a tornar um problema complexo em pequenas par tes simples que resolve o problema maior em partes Por exemplo quando desejamos fa zer uma construção de um grande prédio podemos inicialmente analisar por etapas essa construção Como seriam cada cômodo e em que parte da obra iremos destacar com mais detalhes cada porta janela vitros etc Essa quebra pode tornar mais simples analisan do por etapas e buscando entender suas prioridades na sequência da execução Em um projeto de um sistema o refinamento sucessivo é uma maneira de quebrar mos o problemas por etapas calculando em um procedimento ou função pequenas fun cionalidades do sistema como um todo Iniciamos por exemplo em separar entras e saí das Depois separar os cálculos se houver em pequenas funções que só resolvem uma parte da operação e assim vamos construindo o resultado do todo até concluirmos a reso lução de todo problema Toda a divisão do problema em pequenos módulos de programa ajudará a melhorar o entendimento do sistema como um todo e ao mesmo tempo faci litará em futuros reuso do conteúdo dos módulos Atualmente as linguagens já possuem bibliotecas que trazem muitos procedimentos ou funções que já fazem tarefas específicas para facilitar na programação como um todo Para entender o uso de uma uma função ou procedimento em um programa de gran de porte e que tenha que fazer o uso do refinamento sucessivo é necessário entender também como os parâmetros devem ser colocados de forma a não perder informação nos fluxos de dados entre procedimentos que chamam uma função e no procedimen to ou função que foi chamada Para isso iremos falar da passagem de parâmetros por va lor quando não há necessidade de alterar o valor da variável que estamos passando para uma função ou procedimento e do uso de uma variável passada por referência que signi fica que toda modificação no módulo chamado altera diretamente no módulo chamador Variável global um identificador declarado externamente a todas as funções de um pro grama usar somente em casos muito bem justificados O uso de variáveis locais é mais interessante em programas muito grande Apontador ou ponteiro um endereço para um valor em outra local da memória Apontador pendente apontador para um bloco no heap já liberado 169 2 Refinamento sucessivo Conforme a complexidade de problemas vai aumentando mais e mais difícil fica resol vêlos Para contornar a complexidade de determinados problemas e resolvêlos de forma clara e mais fácil são aplicadas técnicas específicas Uma técnica bastante popular deno minase dividirparaconquistar Ela consiste em dividir problemas em subproblemas menores e mais tratáveis e a partir das soluções obtidas com a resolução dos subproble mas constróise a solução do problema como um todo Se a resolução de um subproble ma ainda é muito complexa ele pode ser dividido em subproblemas ainda menores e as sim sucessivamente Em todas as linguagens de programação possuem suporte em termos de constru ções de linguagem para o uso de tal técnica no desenvolvimento de programas Um tipo de suporte bastante comum é prover facilidades para a construção de subprogramas considerados procedimentos ou funções Um subprograma não pode ser executado diretamente como um programa Ele pre cisa ser invocado ou chamado de algum ponto do código do programa como um todo do qual faz parte Se durante a execução o fluxo de controle ordem em que os coman dos são executados atingir um ponto de invocação então o fluxo de controle da execu ção passa para o subprograma e ao ser concluída a execução do subprograma o fluxo de controle é retomado imediatamente após o ponto de invocação que provocou o redire cionamento do fluxo para o subprograma em questão Um subprograma pode eventualmente invocar outro subprograma e assim sucessi vamente Muitas linguagens de programação permitem também que um subprograma invoque a si próprio Nestes casos dizemos que ocorreu uma invocação ou chamada recursiva Conforme explanado a técnica de construção de subprogramas privilegia es sencialmente questões de fluxo de controle Uma forma de flexibilizar mais o uso de subprogramas eles podem ser parametrizados isto é o seu funcionamento pode ser codificado em termos de parâmetros cujos valores são definidos no instante da invocação Assim podese reaproveitar um subprograma em situações em que os conjuntos de dados a serem processados diferem mas a forma de processálos é a mesma 170 Os parâmetros utilizados tornam a base na definição de um subprograma e são deno minados parâmetros formais e os utilizados em um ponto de invocação parâmetros reais No instante da invocação são determinados os valores dos parâmetros reais e ligados aos parâmetros formais Uma vez efetuada tal ligação ocorre então o desvio do fluxo de exe cução para o subprograma O uso de parâmetros portanto representa um mecanismo de passar dados do ponto de invocação para o contexto de execução do subprograma Alguns subprogramas ao terminar a sua execução redirecionam simplesmente o flu xo de controle para o ponto de invocação provocando possivelmente apenas efeitos co laterais como mudanças na apresentação da interface de usuário ou a escrita de um valor em um arquivo Um subprograma desta natureza é muitas vezes chamado de procedi mento Outros subprogramas além de redirecionar o fluxo de controle podem retornar um dado Um subprograma com tais características é frequentemente denominado função Um procedimento deve então ser invocado em algum ponto em que não é esperado como resposta um valor e uma função sim como em uma expressão da qual a sua invo cação é parte integrante por exemplo Um programa organizado em termos de subprogramas é comumente referenciado como sendo um programa estruturado Ao fragmentarmos um programa em subprogra mas colocase a questão sobre o contexto de variáveis e constantes entre outros Isto é em que trechos de código pode ou não pode ser manipulada uma particular variável ou constante Os trechos em que pode ser manipulada denominamos como sendo o seu es copo e dizemos que ela é visível em tais trechos Formas de controles de visibilidade va riam de linguagem para linguagem de programação As terminologias para uso de Passagem de parâmetros são dados a seguir Passagem por valor recebimento por um parâmetro formal de uma cópia do va lor do parâmetro real correspondente Ex int calculamediaint a int b a e b são passa dos por valor Passagem por referência recebimento por um parâmetro formal da localização endereço de memória do parâmetro real correspondente Ex int calculamediaint a int b a e b são passados por referência Escopo região do código do programa onde a referência uso a um identificador é válida Exemplo forint i0 ini soma i neste caso o escopo de i só vale no laço do for Fora do laço i não existirá mais 171 Tempo de vida período de tempo durante a execução de um programa em que um identificador tem memória alocada Variável local uma variável declarada em um bloco e não acessível fora de tal bloco Um exemplo de um refinamento sucessivo por exemplo ao realizar uma calculado ra que faz várias operações matemáticas podemos quebrar cada operação em peque nos subprogramas e no programa principal termos um MENU que gerencia as operações conforme solicitação do usuário Por exemplo a entrada de dados é a e b sendo dois valo res float e as operações que devem ser realizadas são soma subtração multiplicação di visão cálculo do resto entre outras include stdioh include mathh float somafloat a float b return a b float subtracaofloat a float b return a b float multiplicacaofloat a float b return a b float divisaofloat a float b return a b int restodivisaoint a int b return ab float quadradofloat a return powa2 float raizquadradafloat a return sqrta 172 void MENU printf O P E R A C O E S C A L C U L A D O R A printf1 Soma printf2 Subtracao printf3 Nultiplicacao printf4 Divisao printf5 Resto da Divisao printf6 Quadrado de um numero printf7 Raiz quadrada de um numero printf8 Sair printfOpcao int main float a b c int op do MENU scanfdop switch op case 1 printfEntre com os números que deseja somar scanff fab c somaab printfA soma entre 2f e 2f 2f a b c break case 2 printfEntre com os números que deseja subtrair scanff fab c subtracaoab printfA subtracao entre 2f e 2f 2f a b c break case 3 printfEntre com os números que deseja multiplicar scanff fab c multiplicacaoab printfA multiplicacao entre 2f e 2f 2f a b c break case 4 printfEntre com os números que deseja dividir scanff fab c divisaoab printfA divisao entre 2f e 2f 2f a b c break case 5 printfEntre com os números que deseja o resto da divisao scanff fab 173 c restodivisaoab printfO resto da divisao entre 2f e 2f 2f a b c break case 6 printfEntre com o número que deseja calcular o seu quadrado scanffa c quadradoa printfA quadrado de 2f 2f a c break case 7 printfEntre com o número que deseja calcular a raiz quadrada scanffa c raizquadradaa printfA raiz quadrada de 2f 2f a c break default printfEntre com um valor da opcao entre 1 e 8 break whileop8 return 0 Observe que no programa do exemplo anterior as variáveis de parâmetros foram to das utilizadas com passagem apenas por valor o resultado foi realizado pela função que devolve o resultado da operação No programa principal que chama as funções no swit ch case foram separadas pelo seu nome se a função precisar ser melhorada ou amplia da seus cálculos ficam mais fácil de efetuar essa modificação A seguir vamos conhecer as passagens de parâmetros por valor e por referência 174 3 Passagens de Parâmetros por valor A passagem por valor é apenas colocada nos parâmetros do subprograma real confor me mostra no programa exemplo anterior onde cada subprograma soma subtração mul tiplicação etc somente os valores das variáveis a e b foram passadas Neste caso dizemos que a passagem de parâmetro apenas passa os valores das variáveis para serem utilizadas nos subprogramas chamados As variáveis passadas por parâmetros quando é o caso de passar apenas por valor elas não podem sofrer alterações no fluxo do subprograma se houver alguma alteração em seus valores no subprograma essa alteração fica apenas no escopo do subprograma Exemplo vamos supor que temos que enviar um valor inteiro para uma função fazer a in versão de um numero inteiro com 3 dígitos Int invertenumeroint n int u d c u n100 n nu100 d n10 n n d10 u n returnu100d10c Observe que no exemplo anterior apesar de n ter sido passado somente por valor ele sofreu alteração local apenas no escopo da função invertenumero onde essa modifi cação não afeta o valor passado pelo subprograma chamador main Já se a variável n passada por parâmetro fosse passado por referência o valor de n re tornaria igual ao valor da unidade Veremos a seguir exemplos de passagem de parâme tros por referência 175 4 Passagens de Parâmetros por referência A passagem de parâmetro por referência acontece sempre que a variável passada po derá sofrer alteração no subprograma chamado A alteração ocorrida no escopo do sub programa acontece diretamente no local do endereço da variável passada por parâme tro no mesmo escopo do subprograma chamador main Vamos ver um exemplo típico que temos que passar por referência pois o valor da variável passada deverá sofrer algu ma modificação pelo subprograma chamado include stdioh void inverternumeroint n int udc u n10 c n100 dn1010 nu100d10c int main int n scanfdn printfO número inverso de d n inverternumeron chamada do subprograma com passagem por referência printfd n return 0 A passagem por referência acontece quando desejase que a variável passada por pa râmetro em uma chamada de subprograma tenha que sofrer alteração no subprograma chamado Somente o caso de vetor ou matriz é que passamos por parâmetro apenas o nome do vetor ou da matriz sem uso de endereço da memória da variável e também não usamos no subprograma formal o ponteiro na variável vetor ou matriz 176 Isso ocorre por no caso de um vetor de tamanho 20 por exemplo de inteiros se for mos passar por parâmetro para efetuar a leitura dele no subprograma chamado ele já pas sa automaticamente por referência conforme mostra o exemplo a seguir include stdioh define N 100 void lervetorint v int n int i fori0ini scanfdvi int main int in vetorN printfEntre com a dimensão do vetor 2 até 100 scanfdn lervetorvetorn quem é vetor é o mesmo que vetor0 printfvalores do vetor de tamanho d n fori0in1i printfd vetori imprime de 0 a n2 printfd vetori imprime o n1 valor do vetor return 0 A passagem vetor e matriz representam sempre o endereço do primeiro elemento quando for vetor vetor0 quando for uma matriz seria o endereço de matriz00 por isso só passamos o nome da variável vetor ou matriz Como um bom uso de passagem de parâmetro e uso de refinamentos sucessivos em um problema real vamos propor um exercício para construir com a estrutura de vários subprogramas para resolver cada funcionalidade do problema 177 5 Exercícios E71 Elabore um programa que controle uma venda de passagens de um ônibus com 48 poltronas sendo que as poltronas do ônibus são distribuídas da seguinte forma as poltronas impares são janelas e as pares são corredores Em cada informação de uma ven da de uma poltrona deverá conter o Nome do passageiro O RG Telefone Email e Data de nascimento Também deverá conter a Origem e destino de seu bilhete o valor de sua via gem paga um nome e telefone de uma pessoa para contato em caso de acidente O Oni bus deverá conter o Código da Viagem Origem e Destino final da viagem horário de par tida e data da viagem bem como um controle do valor arrecado na viagem Toda venda de uma passagem deverá conter a exibição das poltronas do ônibus dizendo se a poltro na está livre X ou ocupada será marcada com V que representará o estatus da poltrona Dica usar a definição de tipos Passageiro e Onibus da seguinte forma typedef struct char RG20 char nomepass40 char telpass15 char emailpass50 char nomecontato40 char telcontato15 char statos float valorpassagem char cidorigem20 char ciddestino20 char dataviagem12 char horembarque10 Passageiro typedef struct Passageiro poltrona48 char codviagem10 char cidadeorigem20 char cidadedestino20 char datapartida15 char horariosaida15 float valorarrecadado Onibus 178 Resposta R71 Vendas de Passagem de Ônibus include stdioh include stringh typedef struct char RG20 char nomepass40 char datanasc15 char telpass15 char emailpass50 char nomecontato40 char telcontato15 char status float valorpassagem char cidorigem20 char ciddestino20 char dataviagem15 char horembarque10 Passageiro typedef struct Passageiro poltrona48 char codviagem10 char cidadeorigem20 char cidadedestino20 char datapartida15 char horariosaida15 float valorarrecadado int qtdpassageiro Onibus void inicializaronibusOnibus o int i fori0 i48 i opoltronaistatusX ovalorarrecadado 00 oqtdpassageiro 0 printfEntre com o codigo da viagem fgetsocodviagem 10 stdin printfEntre com o nome da cidade origem da viagem fgetsocidadeorigem 20 stdin 179 printfEntre com o nome da cidade destino da viagem fgetsocidadedestino 20 stdin printfEntre com a data da viagem fgetsodatapartida 15 stdin printfEntre com o horario da viagem fgetsohorariosaida 15 stdin void lerpassageiroPassageiro p printfEntre com o RG do Passageiroa fgetspRG20stdin printfEntre com o nome do Passageiroa fgetspnomepass40stdin printfEntre com a data de nascimento do Passageiroa fgetspdatanasc15stdin printfEntre com o telefone do Passageiroa fgetsptelpass15stdin printfEntre com email do Passageiroa fgetspemailpass50stdin printfEntre com o nome do contado do Passageiroa fgetspnomecontato40stdin printfEntre com o telefone do contado do Passageiroa fgetsptelcontato15stdin printfEntre com a cidade de origem do passageiroa fgetspcidorigem20stdin printfEntre com a cidade de destino do passageiroa fgetspciddestino20stdin printfEntre com a data da viagem do passageiroa fgetspdataviagem15stdin printfEntre com horario de embarque do passageiroa fgetsphorembarque10stdin printfEntre com o valor da passagem do passageiroa scanffpvalorpassagem getchar pstatus V 180 void exibironibusOnibus o int i printfEXIBICAO DO ONI BUS fori0i48ii4 printf2d c 2d c i1opoltronai statusi2opoltronai1status printf 2d c 2d c i4opoltronai3 statusi3opoltronai2status void cadastrarpassagemOnibus o Passageiro p int pol opoltronapol1 p ovalorarrecadado pvalorpassagem void totalarrecadadoOnibus o printfO valor total arrecadado 2f ovalorarrecadado void detalheviagemOnibus o printf Codigo da Viagem s ocodviagem printf Data da Viagem s Horario da viagem s o datapartidaohorariosaida printf Origem s Destino s ocidadeorigemocida dedestino printf 2d passageiros oqtdpassageiro void emitirpassagemOnibus o int pol printf RG s opoltronapol1RG printfNome do Passageiroa s opoltronapol1nomepass 181 printfIdade do Passageiroa s opoltronapol1datanasc printfTelefone do Passageiroa s opoltronapol1telpass printfEmail do Passageiroa s opoltronapol1emailpass printfContato em caso de emergencia s opoltronapol1 nomecontato printfCodigo do Onibus s ocodviagem printfCidade de Partida s opoltronapol1cidorigem printfCidade de Destino s opoltronapol1ciddestino printfHorario de Partida s opoltronapol1horembarque printfData da viagem s opoltronapol1dataviagem printfValor da Passagem 2f opoltronapol1valorpassa gem printf void consultarpoltronaOnibus O int pol ifOpoltronapol1statusV printfPoltrona d esta vazia pol else printfPoltrona d esta ocupada pol void Menu printfMENU ONIBUS printf1 Detalhes da Viagem printf2 Comprar uma passagem printf3 Visualizar o status do onibus printf4 Consultar uma determinada poltrona printf5 Emitir uma passagem printf6 Exibir valor total arrecadado printf7 Sair do Aplicativo printfOpcao void CarregaronibusOnibus O FILE fp fp fopen Onibusdat rb if fp NULL inicializaronibusO else 182 freadOsizeofOnibus1fp fclosefp void GravarOnibus Onibus O FILE fp fp fopen Onibusdat wb arquivo para escrita binE1ria if fp NULL printf Erro ao abrir o arquivo return else printf Arquivo Binario criado com sucesso fwriteO sizeofOnibus 1 fp fclose fp int main Passageiro P Onibus O int op pol CarregaronibusO doMenu scanfd op getchar switchop case 1 detalheviagemO break case 2 lerpassageiroP exibironibusO printfEscolha uma poltrona nao ocupada scanfd pol getchar cadastrarpassagemO P pol break case 3exibironibusO break case 4 printfEntre com o numero da poltrona scanfd pol 183 getchar consultarpoltronaO pol break case 5 printfEntre com a poltrona do passageiroa scanfdpol ifOpoltronapol1status V emitirpassagemO pol else printfA poltrona d ainda esta desocupada pol break case 6 totalarrecadadoO break case 7 printfObrigado por utilizar nosso aplicativo GravarOnibusO break default printfEntre com a opcao correta de 1 a 7 break whileop7 return 0 UNIDADE 8 ASPECTOS DE IMPLEMENTAÇÃO DE ALGORITMOS 185 1 Introdução Um programa pode ser classificado de acordo com seu propósito de implementa ção podendo ter formas recursivas ou iterativas que devem ser analisados qual maneira é menos complexo seu entendimento e sua execução Existem também programas basea dos em lógicas que utilizam padrões para resolver seus problemas muito usado em Inte ligência Artificial que faz uma classificação em um conjunto de padrões e que posterior mente seus objetivos é classificar novos resultados comparados com esses padrões Para isso existem linguagens próprias para auxiliar na sua programação Existem também pro gramas sequencial ou serial que são construídos para execução de suas tarefas em series como se fosse uma lista de etapas de sua execução cujas etapas são pré definidas e uma compõem a execução da outra etapa Existem também programação paralela cujas ta refas podem estar em diferentes máquinas e ser executada em paralelo sem interferir em outra etapa como por exemplo uma tarefa é execução de relatórios que está em uma máquina que acessa uma determinada impressora outra tarefa está em uma máquina que faz busca em um banco de dados trazendo as informações quando terminada E as sim várias tarefas podem ser executadas simultaneamente com um controle de proces sos determinísticos muito comum em programação de alto desempenho ou programa ção de sistemas distribuídos Outros tipos de algoritmos como determinísticos que resolvem problemas com resul tados exatos e algoritmos não determinístico que é diferente de sua contraparte determi nista em sua capacidade de chegar a resultados usando diversas rotas Se um algoritmo determinístico representa um único caminho de uma entrada para um resultado um al goritmo não determinístico representa um caminho resultante em muitos caminhos al guns dos quais podem chegar ao mesmo resultado e alguns dos quais podem chegar a resultados únicos Esses algoritmos são muitos usados em problemas de grafos Por último existem algoritmos exato e aproximados que são muito utilizados em proble mas de otimização Os algoritmos de aproximação são usados para problemas NP difíceis que são problemas que não podem ser resolvidos em tempo polinomial Os algoritmos exa tos também servem para trabalhar com problemas NP difíceis mas quando o problema re quer uma solução exata em tempo de execução exponencial também utilizado em proble mas de otimização Aqui faremos apenas uma introdução para conhecer que existem tipos de programas algoritmos que possuem essas dependências em suas execuções 186 2 Classificação por implementação Um programa de computador é essencialmente um algoritmo que diz ao computador os passos específicos e em que ordem eles devem ser executados como por exemplo os passos a serem tomados para calcular as notas que serão impressas nos boletins dos alu nos de uma escola Logo o algoritmo pode ser considerado uma sequência de operações que podem ser simuladas por uma máquina de Turing completa Quando os procedimentos de um algoritmo envolvem o processamento de dados a informação é lida de uma fonte de entrada processada e retornada sob novo valor após processamento o que geralmente é realizado com o auxílio de uma ou mais estruturas de dados Para qualquer processo computacional o algoritmo precisa estar rigorosamente defi nido especificando a maneira que ele se comportará em todas as circunstâncias A correti vidade do algoritmo pode ser provada matematicamente bem como a quantidade assin tótica de tempo e espaço complexidade necessários para a sua execução Estes aspectos dos algoritmos são alvo da análise de algoritmo A maneira mais simples de se pensar um algoritmo é por uma lista de procedimentos bem definida na qual as instruções são executadas passo a passo a partir do começo da lista uma ideia que pode ser facilmente visualizada através de um fluxograma Tal formali zação adota as premissas da programação imperativa que é uma forma mecânica para vi sualizar e desenvolver um algoritmo Concepções alternativas para algoritmos variam em uma programação funcional ou programação Lógica Término do algoritmo Alguns autores restringem a definição de algoritmo para procedimentos que even tualmente terminam Marvin Minsky constatou que se o tamanho de um procedimento não é conhecido de antemão tentar descobrilo é um problema indecidível já que o pro cedimento pode ser executado infinitamente de forma que nunca se terá a resposta Alan Turing provou em 1936 que não existe máquina de Turing para realizar tal análise para to 187 dos os casos logo não há algoritmo para realizar tal tarefa para todos os casos Tal condi ção é conhecida atualmente como problema da parada Para algoritmos intermináveis o sucesso não pode ser determinado pela interpretação da resposta e sim por condições impostas pelo próprio desenvolvedor do algoritmo du rante a sua execução Para isso existe uma classificação de tipos de algoritmos que são considerados com plexos por resolver problemas altamente difíceis denominados de NPdifíceis 188 3 Iterativo ou recursivo Um algoritmo recursivo possui a característica de invocar a si mesmo repetidamen te até que certa condição seja satisfeita e ele é terminado que é um método comum em programação funcional Algoritmos iterativos usam estruturas de repetição tais como la ços ou ainda estruturas de dados adicionais tais como pilhas para resolver problemas Cada algoritmo recursivo possui um algoritmo iterativo equivalente e viceversa mas que pode ter mais ou menos complexidade em sua construção Como um exemplo de um bom uso de um algoritmo recursivo seria o cálculo do fatorial de n onde a recursividade possui uma ordem de chamada da pilha de execução n vezes no máximo Também para o caso de resolução de maneira iterativa utilizando um for iremos entrar no laço n vezes no máximo Neste caso tanto faz utilizarmos a implementação utilizando recursividade quan to usarmos de forma iterativa Outro exemplo seria o uso do cálculo de Fibonacci de n onde Fibonacci de n é dado pela fórmula fibn fibn1 fibn2 para n 2 sabendo que fib1 1 e fib2 1 Neste caso para fazer a função recursiva temos double fibdouble f iff1 return 1 else if f2 return 2 else f fibf1fibf2 cada chamada ele chama 2x returnf Neste caso no módulo recursivo cada vez que ele entra numa chamada ele chama 2x até alcançar 1 ou 2 Desta forma recai em uma ordem exponencial 2n Já na forma iterati va a ordem de chamada é On Por isso é melhor implementar esse algoritmo no modo iterativo 189 include stdioh int main float fib1000 f 0 int i n printfEntre com o valor de n scanfdn fib1 1 fib2 2 fori3ini fibi fibi1 fibi2 f fibi1 printfFibonacci de d 2f nf return 0 190 4 Lógico Um algoritmo pode ser visto como uma dedução lógica controlada O componente lógico expressa os axiomas usados na computação e o componente de controle determi na a maneira como a dedução é aplicada aos axiomas Tal conceito é base para a progra mação lógica A programação Lógica é um paradigma de programação que faz uso da ló gica matemática John McCarthy 1958 foi o primeiro a publicar uma proposta de uso da lógica matemática para a programação A primeira linguagem de programação lógica foi a Planne a qual permitia a invoca ção orientada a padrões de planos procedimentais de asserções e de objetivos Com a ne cessidade de adaptação aos sistemas de memória muito limitada que eram disponíveis quando ela foi desenvolvida A linguagem Planner usava estruturas de controle de back tracking de tal forma que apenas um único caminho computacional tinha que ser arma zenado por vez Em seguida a linguagem Prolog foi desenvolvida como uma simplifica ção do Planner que permitia a invocação orientada a padrões apenas a partir de objetivos também baseado em backtracking A partir do Planner foram desenvolvidas as linguagens de programação QA4 Popler Conniver e QLISP As linguagens de programação Mercury Visual PrologOz e Frill foram desenvolvidas a partir do Prolog Atualmente existem linguagens de programação lógica concorrente não baseadas em backtracking derivadas do Planner por exemplo a Ether e derivadas do Prolog e a Linguagem Shapiro 1989 para um apanhado geral A linguagem de programação Prolog foi explicitamente apresentada como baseada na lógica matemática A base dessa alegação era que um programa Prolog podia literal mente ser lido como um conjunto de fórmulas em um fragmento da lógica de primeira ordem herdando o modelo de teoria e demonstração da lógica de primeira ordem Prolog foi desenvolvida em 1972 por Alain Colmerauer Ela veio de uma colaboração entre Colmerauer em Marselha e Robert Kowalski em Edinburgo Colmerauer estava tra balhando na compreensão da linguagem natural usando lógica para representar semân ticas e usando resolução para questionamentoresposta Durante o verão de 1971 Col merauer e Kowalski descobriram que a forma clausal da lógica poderia ser usada para representar gramáticas formais e que demonstrações do teorema da resolução poderia 191 ser usado para análise gramatical Eles observaram que algumas demonstrações de teore mas como o da hiperresolução comportavamse como analisadores ascendentes e ou tros como resoluçãoSL 1971 comportavamse como analisadores descendentes Durante a seguinte versão de 1972 Kowalski novamente trabalhando com Col merauer observou que resoluçãoSL trata cláusulas universalmente quantificadas na for ma declarativa de implicações B1 e e Bn implica H como procedimentos de objetivoredução para mostrarresolver H mostrarresolver B1 e e Bn Essa interpretação dupla declarativaprocedimental depois foi formalizada na notação do Prolog H B1 Bn que pode ser lida e usada tanto declarativamente como procedimentalmente Tornouse também claro que tais cláusulas poderiam ser restringidas para definir cláusulas ou cláu sulas de Horn em que H B1 Bn são todos os predicados atômicos e que resoluçãoSL poderia ser restrita e gerada para LUSH ou resoluçãoSLD Lógica predicativa usada pelas linguagens prolog Os elementos básicos da lógica de predicados são símbolos que se referem a obje tos funções e relações Variáveis Se referem a objetos ou conjunto de objetos Exemplo x x é humano Constantes Se referem a instâncias específicas de objetos Exemplo Bob é hu mano b b é humano bBob Predicados Se referem a relações entre objetos Exemplo bBob mMaria Maexy x é mãe de y Maemb Maria é mãe de Bob Funções Se referem a funções do objeto Exemplo x x é humano x Bob Alu nox x é aluno AlunoBob Bob é aluno Termos expressões lógicas que se referem a um objeto A relação próxima entre interpretação declarativa e processual resulta numa ca racterística típica das linguagens de programação lógica embora a relação se torne mais complexa quando há negação disjunção e outros quantificadores são permitidos em pro gramas Nessas linguagens de programação lógicas constroem uma lógica predicativa juntamente com regras e padrões fazendo que os resultados são construídos por essas 192 lógicas até adquirir todos resultados possíveis Outras linguagens foram melhorando a forma de geração dos padrões hoje a área de Inteligência artificial utiliza modelos mais avançados de padrões com machine learning e deep learning ocorrendo uma evolução com a linguagem Swift for Tensorflowf ou S4TF Existem outras linguagens utilizadas para essa área como a linguagem Python Java CC e outras Mas é preciso estudar os conceitos dessa tecnologia e aprimorar os conhecimentos que são necessários para avan çar em determinadas áreas Referência McCarthy J 1959Programs with Common Sense In Proceedings of the Teddington Conference on the Mechanization of Thought Processes 75691 London Her Majestys Stationery Office 193 5 Serial ou Paralelo Algoritmos Serial são geralmente assumidos por serem executados instrução a instru ção individualmente como uma lista de execução o que constitui um algoritmo serial Tal conceito é base para a programação imperativa Por outro lado existem algoritmos exe cutados paralelamente que levam em conta as arquiteturas de computadores e um pro cessador para executar mais de uma instrução ao mesmo tempo Tais algoritmos dividem os problemas em subproblemas e o delegam a quantos processadores estiverem disponí veis agrupando no final o resultado dos subproblemas em um resultado final ao algorit mo Tal conceito é base para a programação paralela De forma geral algoritmos iterativos são paralelizáveis por outro lado existem algoritmos que não são paralelizáveis chamados então problemas inerentemente seriais A partir dos algoritmos sequenciais ou seriais foi possível evoluir para execução de partes do algoritmos em paralelo quanto mais processador existir mais rápido fica a sua execução tendo partes do algoritmos que podem trabalhar isoladamente das demais fa cilitando assim o uso da execução em paralelo Muito utilizado em sistemas distribuídos e de alto desempenho Ao invés de um processador vários processadores cada processa dor executa uma parte do sistema simultaneamente compartilhando muitas vezes seus resultados por um controlador O mundo evolui para o processamento paralelo de vários aplicativos que utilizamos no dia a dia e que estão em execução simultaneamente em todos lugares São algoritmos que são utilizados para resolver problemas de otimização como programação linear dinâmica e outras São algoritmos determinísticos que resolvem o problema com uma decisão exata a cada passo enquanto algoritmos nãodeterminísticos resolvem o problema ao deduzir os melhores passos através de estimativas sob forma de heurísticas A convergência do resultado pode demorar horas ou dias dependendo do tamanho das equações Desta forma um algoritmo determinístico é um algoritmo em que dada uma certa entrada ela produzirá sempre a mesma saída com a máquina responsável sempre passando pela mesma sequência de estados Algoritmos determinísticos são de longe o tipo mais estudado e conhecido de algoritmo assim como um dos mais práticos uma vez que podem ser executados em máquinas reais de forma eficiente Formalmente um algoritmo determinístico computa uma função matemática uma função que tem um valor único para cada entrada dada e o algoritmo é um processo que produz este valor em particular como saída Algoritmos determinísticos podem ser definidos em termos de uma máquina de estados um estado descreve o que uma máquina está fazendo em um instante específico no tempo Máquinas de estado passam de maneira discreta de um estado para outro Imediatamente depois de colocarmos a entrada a máquina está no que chamamos estado inicial Se a máquina é determinística isto significa que deste ponto em diante seu estado atual determinará qual será o seu próximo estado seu caminho através do conjunto de estados é predeterminado Note que uma máquina pode ser determinística e ainda assim nunca parar para terminar e portanto deixar de retornar um resultado 196 7 Exato ou Aproximado Enquanto alguns algoritmos encontram uma resposta exata algoritmos de aproxima ção procuram uma resposta próxima a verdadeira solução seja através de estratégia de terminística ou aleatória Possuem aplicações práticas sobretudo para problemas muito complexos do qual uma resposta correta é inviável devido à sua complexidade computa cional Ordem de execução A área de complexidade de algoritmo trata desses detalhes Os algoritmos exatos ou aproximados são utilizados para resolver problemas de progra mação linear inteira dinâmica entre outros Alguns problemas a resposta tem que ter um resultado exato para ter sucesso em seu objetivo Outros podem ter uma aproximação do resultado a partir de regras e ge ração de aproximação heurísticas Para isso são algoritmos muito utilizados em várias apli cação matemática grafos e otimização de empresas A mais encontrada é em Programa ção Linear Inteira como cortes de papel borracha entre outros tentando otimizar o uso do produto nesses cortes para obter o produto final Existem métodos como Simplex Dual Simplex e outros que utilizam a ideia de um al goritmo Exato Em um grafo por exemplo o algoritmo só vai encontrar uma solução que melhor atende uma determinada demanda Já o Algoritmos de aproximação são geralmente associados com problemas NP difí ceis já que estes problemas não podem ser resolvidos em tempo polinomial Também em alguns problemas resolvidos em tempo polinomial no qual o tamanho da entrada pode fazer com que mesmo algoritmos polinomiais sejam custosos estão sendo cada vez mais usados algoritmos de aproximação Na prática podemos não precisar da solução ótima do problema uma solução boa ob tida por um algoritmo de aproximação pode ser suficientemente e mais fácil de ser obtida Uma outra saída para estes problemas são as Heurísticas entretanto essas normalmen te encontram soluções razoavelmente boas com uma velocidade não muito boa Ideal mente a aproximação é ótima até um pequeno fator constante geralmente de 5 da so lução ótima Diferentes problemas NPdifíceis possuem níveis diferentes de aproximação Por exem plo o problema pode ser aproximado com qualquer fator maior que 1 já outros não po Se ele opera de uma maneira sensível ao tempo Por exemplo se ele tiver vários processadores escrevendo em um mesmo conjunto de dados ao mesmo tempo a ordem específica na qual cada processador escreve seus dados vai afetar o resultado Se um erro de hardware causa uma mudança de estado inesperada Embora programas reais raramente sejam puramente determinísticos é mais simples para seres humanos assim como para outros programas trabalhar com programas que o sejam Por esta razão a maioria das linguagens de programação especialmente as linguagens funcionais fazem esforços para evitar que os eventos acima ocorram exceto sob condições controladas A prevalência de processadores multimídia resultou em um aumento no interesse em determinismo em programação paralela e desafios do nãodeterminismo têm sido bem documentados para lidar com deadlocks e condições de corrida 197 dem ser aproximados dentro de qualquer constante ou fator polinomial ao menos que P NP como por exemplo o problema clique Um grupo de algoritmos de aproximação são chamados de Esquema de aproximação em tempo polinomial ou PTAS Nem todos os algoritmos de aproximação são usuais na prática Eles costumam usar estruturas de dados complexos ou sofisticadas técnicas algorítmicas que dificultam sua implementação Além disso alguns algoritmos de aproximação tem tempos de execução não viáveis embora sejam de tempo polinomial por exemploOn2000 No entanto o es tudo de alguns algoritmos mesmo muito caros podem fornecer conhecimentos valiosos Um exemplo clássico é o PTAS para o problema do caixeiro viajante euclidiano pro blema do Caixeiro Viajante PCV utilizando distâncias euclidianas que possui um tempo de execução longa redefinindo os conceitos de algoritmo de tempo linear Esses algoritmos são úteis em algumas aplicações onde os tempos de execução e de custo podem ser jus tificados como por exemplo biologia computacional engenharia financeira planejamen to transporte e gerenciamento de inventário 198 8 Conclusão final Este material teve o objetivo de passar para o Estudante os conceitos de Algoritmos de programação bem como a linguagem C como linguagem básica de estudo dos pro blemas Todo material atendeu a disciplina de Algoritmos e Linguagem de Programação para os estudantes da disciplina As informações finais postadas na última Unidade é apenas para o conhecimento dos tipos de algoritmos existentes na prática dos programadores de Sistemas computacionais A Referência bibliográfica que devem ser utilizadas foram postadas em cada Unida de conforme necessidades Porém é importante avançar em mais leituras de outros livros mais atualizados em em Programação C Java e outras linguagens