o d´ıgito verificador. Implemente o seguinte algoritmo para gerar o d´ıgito verificador: Conforme o esquema abaixo, cada d´ıgito do nu´mero, comec¸ando da direita para a esquerda (menos significativo para o mais significativo) e´ multiplicado, na ordem, por 2, depois 1, depois 2, depois 1 e assim sucessivamente. Nu´mero exemplo: 261533-4 +---+---+---+---+---+---+ +---+ | 2 | 6 | 1 | 5 | 3 | 3 | - | 4 | +---+---+---+---+---+---+ +---+ | | | | | | x1 x2 x1 x2 x1 x2 | | | | | | =2 =12 =1 =10 =3 =6 +---+---+---+---+---+-> = (16 / 10) = 1, resto 6 => DV = (10 - 6) = 4 Ao inve´s de ser feita a somato´ria das multiplicac¸o˜es, sera´ feita a somato´ria dos d´ıgitos das multiplicac¸o˜es (se uma multiplicac¸a˜o der 12, por exemplo, sera´ somado 1 + 2 = 3). A somato´ria sera´ dividida por 10 e se o resto (mo´dulo 10) for diferente de zero, o d´ıgito sera´ 10 menos este valor. 5. Escreva um programa Pascal que leia dois valores inteiros positivos A e B. Se A for igual a B, devem ser lidos novos valores ate´ que sejam informados valores distintos. Se A for menor que B, o programa deve calcular e escrever a soma dos nu´meros ı´mpares existentes entre A(inclusive) e B(inclusive). Se A for maior que B, o programa deve calcular e escrever a me´dia aritme´tica dos mu´ltiplos de 3 existentes entre A(inclusive) e B(inclusive). 6. Fac¸a um programa em Pascal que dado uma sequeˆncia de nu´meros inteiros terminada por zero (0), determinar quantos segmentos de nu´meros iguais con- secutivos compo˜em essa sequeˆncia. Ex.: A sequeˆncia 2,2,3,3,5,1,1,1 e´ formada por 4 segmentos de nu´meros iguais. 7. Fac¸a um programa em Pascal que imprima a seguinte sequeˆncia de nu´meros: 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, . . . 8. Fac¸a um programa em Pascal que receba como entrada um dado inteiro N e o imprima como um produto de primos. Exemplos: 45 = 3 × 3 × 5. 56 = 2× 2× 2× 7. 106 CAPI´TULO 8. REFINAMENTOS SUCESSIVOS 9. Fac¸a um programa em Pascal que, dado um nu´mero inteiro N , escreva o maior divisor de N que e´ uma poteˆncia de um dos nu´meros primos fatorados. Ex: N = 45 = 32.51 escreve 9 = 32 N = 145 = 52.71 escreve 25 = 52 N = 5616 = 24.33.13 escreve 27 = 33 Cap´ıtulo 9 Func¸o˜es e procedimentos Ate´ agora vimos as noc¸o˜es ba´sicas de algoritmos, fundamentalmente como funciona o computador de verdade (modelo Von Neumann) e como isto pode ter uma repre- sentac¸a˜o em um n´ıvel mais alto, guardadas as limitac¸o˜es da ma´quina. A maneira de se resolver problemas do ponto de vista algoritmico envolve a ela- borac¸a˜o de construc¸o˜es com apenas quatro tipos de estruturas de controle de fluxo: comandos de entrada e sa´ıda, comandos de atribuic¸a˜o, comandos de repetic¸a˜o e co- mandos de desvio condicional, ale´m do uso de expresso˜es lo´gicas e aritme´ticas. Para a efetiva programac¸a˜o ainda e´ necessa´rio dominar a arte de escrever os algoritmos em func¸a˜o das limitac¸o˜es dos compiladores. O problema e´ que a` medida em que os problemas exigem co´digos com muitas linhas, os programas gerados va˜o se tornando cada vez mais complexos tanto para serem desenvolvidos quanto para serem mantidos em funcionamento. O exemplo do final do cap´ıtulo anterior da´ uma ideia dessa dificuldade. Por isto, os programas devem ser constru´ıdos de maneira a facilitar o trabalho dos programadores e analistas. E´ preciso que os co´digos sejam elaborados com partes bem definidas, em mo´dulos que contenham pedac¸os coerentes do problema geral que se esta´ tentando modelar. As noc¸o˜es de func¸o˜es e procedimentos sa˜o o caminho para se construir co´digos elegantes, robustos e de fa´cil manutenc¸a˜o. 9.1 Motivac¸a˜o Os procedimentos e func¸o˜es sa˜o nada mais do que subprogramas, isto e´, pedac¸os de programas dentro de programas. Mas, bem explorados, permitem a construc¸a˜o de co´digos altamente elaborados. Existem treˆs motivac¸o˜es para se usar subprogramas: • modularidade; • reaproveitamento de co´digo; • legibilidade do co´digo. Vamos detalhar cada to´pico nos pro´ximos itens. 107 108 CAPI´TULO 9. FUNC¸O˜ES E PROCEDIMENTOS 9.1.1 Modularidade A noc¸a˜o de modularidade e´ relacionada com a capacidade de se escrever programas em pedac¸os de co´digo que executam operac¸o˜es bem definidas. Cada mo´dulo possui varia´veis e estruturas pro´prias, independentes do restante do programa. A ideia e´ que modificac¸o˜es em trechos de co´digo (necessa´rias para manutenc¸a˜o e continuidade de desenvolvimento) na˜o causem reflexos no comportamento do resto do programa. E´ fa´cil conceber um programa dividido em treˆs partes: entrada de dados, ca´lculos e impressa˜o dos resultados. Uma entrada de dados textual poderia ser modificada para outra em modo gra´fico sem que o pedac¸o que faz os ca´lculos perceba a modificac¸a˜o. Idem para a sa´ıda de dados. Mesmo nos ca´lculos, pode-se mudar toda uma estrutura do programa e garantir que a entrada e sa´ıda va˜o continuar a se comportar como antes. Isto e´ tarefa a´rdua sem o uso de func¸o˜es e procedimentos. E´ importante notar que a linguagem Pascal na˜o fornece todos os meios para se implementar um programa totalmente modular, mas e´ o suficiente para os estudantes em primeiro curso de computac¸a˜o perceberem a importaˆncia do conceito. Na verdade, a evoluc¸a˜o destas ideias deu origem ao conceito de Programac¸a˜o Orientada a Objetos, hoje na moda. Mas isto e´ tema para outras disciplinas. 9.1.2 Reaproveitamento de co´digo Vez por outra nos deparamos com situac¸o˜es onde temos que escrever co´digos muito, mas muito, parecidos em trechos diferentes do programa. As vezes a diferenc¸a de um para outro e´ questa˜o de uma ou outra varia´vel que muda. Ocorre frequentemente que o trecho e´ exatamente o mesmo. Enta˜o faz sentido que possamos estruturar o co´digo repetido de maneira a cons- tituir um subprograma e, no programa propriamente dito, fazer o co´digo do subpro- grama ser executado para diferentes valores de varia´veis. Isto provoca uma grande economia de co´digo escrito, ao mesmo tempo em que facilita a manutenc¸a˜o do pro- grama. 9.1.3 Legibilidade Os dois aspectos acima, somados com o bom uso de nomes apropriados para os iden- tificadores, endentac¸a˜o e uso racional de comenta´rios no co´digo, implicam necessari- amente em um co´digo leg´ıvel, isto e´, compreens´ıvel para quem o leˆ e ate´ mesmo para quem o escreveu.1 De fato, e´ comum algue´m fazer um programa, as vezes simples, e depois de alguns meses ler o co´digo e na˜o entender o que la´ esta´ escrito. Um co´digo leg´ıvel permite uma ra´pida compreensa˜o e viabiliza sua manutenc¸a˜o, correc¸a˜o e expansa˜o, seja pelo pro´prio programador ou por outras pessoas. 1Recomendamos a leitura do mini-guia da linguagem Pascal, dipon´ıvel no site oficial da disciplina CI055. 9.2. NOC¸O˜ES FUNDAMENTAIS 109 9.1.4 Comenta´rio adicional Nesta sec¸a˜o, vamos tentar convencer o aprendiz a usar bem e a dar valor a estas noc¸o˜es, estudando exemplos simples, mas dida´ticos. 9.2 Noc¸o˜es fundamentais Existem treˆs conceitos que devem ser dominados pelo estudante: 1. quando usar func¸a˜o e quando usar procedimento? 2. quando usar varia´veis locais ou varia´veis globais? 3. quando usar passagem de paraˆmetros por valor ou por refereˆncia? Nas pro´ximas sec¸o˜es vamos detalhar cada um destes itens. 9.2.1 Exemplo ba´sico Vamos tomar como base um programa bem simples, estudado nas primeiras aulas desta disciplina. Trata-se do problema de se ler uma sequeˆncia de valores inteiros terminada por zero e que imprima somente aqueles que sa˜o pares. Quando resolvemos este problema, o co´digo foi escrito como na figura 9.1. program imprime pares ; var a: integer ; begin read (a) ; while a <> 0 do begin if a mod 2 = 0 then writeln (a) ; read (a) ; end; end. Figura 9.1: