Prévia do material em texto
1 Modularização Programação 2/27 Modularização � A medida que abordamos problemas mais complexos, os algoritmos também apresentarão uma maior complexidade. � A complexidade não está relacionada a quantidade de comandos existentes, e sim às diversas combinações possíveis dos comandos à disposição. � Os comandos que possuímos são poucos, mas podemos realizar diversas combinações com os mesmos. � A complexidade de um problema pode dificultar a construção do algoritmo de sua solução � Devemos tentar dividi-lo em partes menores, resolvendo cada um dos subproblemas separadamente. 3/27 Modularização de algoritmos � Consiste em dividir um algoritmo em etapas, fazendo com que cada etapa seja parte da solução de um problema maior. � Se um subproblema ainda parecer muito complexo, podemos tentar dividi-lo em partes menores, para facilitar sua solução, e assim sucessivamente. � “Dividir para conquistar” � Nós temos dificuldade de resolver problemas quando os mesmos possuem uma grande quantidade de elementos inseridos. � A modularização é a forma humilde de reconhecermos esta dificuldade, mas ainda assim resolvermos o problema. � Basicamente, os sub-algoritmos permitem dividir grandes tarefas de computação em tarefas menores. � A criação de sub-algoritmos evita a repetição de código. � Um bloco de código que está sendo (ou poderá ser) repetido é transformado num sub-algoritmo, este último, então, será (ou poderá ser) facilmente chamado diversas vezes dentro do programa. � Toda a programação em C é baseada em funções (o próprio programa principal é uma função: a função main() ). � A estrutura da linguagem é bastante simples e boa parte das operações é realizada por funções da biblioteca padrão. 4/27 Modularização de algoritmos 5/21 Modularização: funções e procedimentos � Também chamados de funções e procedimentos. Todo programa escrito em C/C++ possui pelo menos uma função ( a função main). � Todas as funções precisam ser chamadas para ser executadas. A única exceção é a função main, que é invocada automaticamente pelo sistema quando o programa é executado. � Ao encontrar uma chamada para uma função ou procedimento, o fluxo de execução do programa desvia para o local onde a função existe, e executa a mesma. Ao terminar a execução da função, o fluxo de execução retorna para o local onde a função foi chamada. � A execução do programa é reiniciada na linha seguinte à linha onde a função foi acionada. 6/27 Modularização 2 7/27 Modularização em C/C++ � Todas as funções devem indicar se retornam um valor para quem chamou a função ou não. Caso não seja necessário retornar um valor, deve-se declarar o retorno como void. Caso a função retorne um valor, devemos usar o comando return seguido de uma variável ou constante para retornar esse valor para quem chamou a função. � C/C++ possui uma grande quantidade de funções disponíveis para uso imediato pelo programador. (Usando a diretiva #include) � O nome da função, em conjunto com os parâmetros que ela recebe identificam a assinatura da função. 8/27 Criando funções em C/C++ � A sintaxe que usaremos para criar uma função é: � Para chamar uma função, basta inserirmos em algum ponto do programa o nome da mesma, junto com a lista de parâmetros (se houver) que a mesma recebe. � <nome_função>(parametro1, parametro2); [TipoRetorno ou void] <nome_função>([Parâmetro1],..., [ParâmetroN]) { <comando1>; <comando2>; ... <comandoN>; } 9/27 Criando funções em Java � A sintaxe que usaremos para criar uma função é: � Para chamar uma função, basta inserirmos em algum ponto do programa o nome da mesma, junto com a lista de parâmetros (se houver) que a mesma recebe. � <nome_função>(parametro1, parametro2); public static [Retorno] <nome_função>([Parâmetro1],..., [ParâmetroN]) { <comando1>; <comando2>; ... <comandoN>; } 10/27 Criando funções em C/C++ (sem retorno e sem parâmetros) � Exemplo de uma função que imprime uma “linha” na tela: � Para chamar essa função, basta inserirmos em algum ponto do programa o nome da mesma. void linha() { printf("----------------------------------------\n"); } 11/27 Exemplo #include <stdio.h> void linha() { printf("----------------------------------------\n"); } int main() { linha(); printf("Teste de Linha\n"); linha(); return 0; } 12/27 Compartilhando variáveis entre funções � Caso seja necessário acessar ou alterar o valor de uma variável dentro de mais de uma função, devemos declarar a variável fora de qualquer função (antes das funções). � As variáveis criadas dentro de funções recebem o nome de variáveis LOCAIS, e só existem dentro das funções onde foram criadas. � As variáveis criadas fora das funções são chamadas de variáveis GLOBAIS. 3 13/27 Exemplo #include <stdio.h> char v='C'; void exibe_v() { printf("Imprimindo a variável (exibe_v) v => %c\n", v); } int main() { exibe_v(); linha(); printf("Imprimindo a variável (main) v => %c\n", v); linha(); return 0; } 14/27 Exemplo Imprimindo a variável (exibe_v) v => C Imprimindo a variável (main) v => C Process returned 0 (0x0) execution time : 0.362 s Press any key to continue. Função em C/C++ (Sem retorno e com parâmetros) #include <stdio.h> void linha2(int n) { for (int i=0; i<n; i++) printf("-"); printf("\n"); } int main() { linha2(10); printf("Teste de Linha2\n"); linha2(20); return 0; } 15/27 Função em C/C++ (Sem retorno e com parâmetros (2)) #include <stdio.h> void linha3(int n, char c) { for (int i=0; i<n; i++) printf("%c",c); printf("\n"); } int main() { linha3(10, ’*’); printf("Teste de Linha3\n"); linha3(20, ’#’); return 0; } 16/27 Função em C/C++ (Com retorno e com parâmetros (2)) #include <stdio.h> int soma (int x, int y) { return (x+y); } int main() { int a, b, s; printf("Dig. 1o. número: "); scanf("%d", &a); printf("Dig. 2o. número: "); scanf("%d", &b); s = soma(a,b); printf("A soma é %d\n",s); return 0; } 17/27 Como modularizar? � Um bom começo é realizar o desenvolvimento top-down: � Parte-se de uma descrição geral do algoritmo (descreva- o em passos gerais); � Gradativa e sucessivamente, refina-se cada passo, dividindo-o em partes menores; � A partir daí, deve-se atacar os detalhes de cada um dos sub-passos, criando novos refinamentos (não há uma regra: desdobre aquilo que melhor lhe convier); � Os sucessivos desdobramentos irão gerar pequenos trechos de código que delimitam poucos contextos do problema que se está atacando; 18/27 4 Como modularizar? � Desenvolvimento top-down (continuação): � O desenvolvimento top-down permite uma boa integração dos módulos, uma vez que cada módulo é desenvolvido quando já se sabe claramente o contexto onde ele vai atuar; � Mas lembre-se: cada módulo deve ser validado (testado) independentemente dos demais; 19/27 Exemplo 1: � Elabore um programa para calcular a média final do aluno baseada em três notas. Exibir a média e a situação do aluno (Aprovado ou Reprovado). � Usar modularização! 20/27 Top-down: passo 01 - identificação dos passos gerais... #include <stdio.h> void main(){ // capturar os dados do aluno // calcular sua média final // exibir algum resultado } 21/27 Top-down: passo 02 – primeiros desdobramentos... void main(){ // capturar os dados do aluno // ler a primeira nota // ler a segunda nota // ler a última nota // calcular sua média final // somar as três notas e dividí-las por três // exibir algum resultado // Exibir média // se média >= 7 emita aprovado senão reprovado } 22/27 Solução (C/C++) [1/3] #include <stdio.h> float n1, n2, n3, media; void captura_dados() { printf("Dig. a 1a. nota: "); scanf("%f", &n1); printf("Dig. a 2a. nota: "); scanf("%f", &n2); printf("Dig. a 3a. nota: "); scanf("%f", &n3); } 23/27 Solução (C/C++) [2/3] float calcula_media( float a, float b, float c) { return (a+b+c)/3; } void exibe_resultado(float m) { printf("A média foi %.2f\n",m); if (m>=7) printf("Aprovado!\n"); else printf("Reprovado!\n"); } 24/27 5 Solução (C/C++) [3/3] int main() { // capturar os dados do aluno captura_dados(); // calcular sua média final media = calcula_media(n1, n2, n3); // exibir algum resultado exibe_resultado(media); reurn 0; } 25/27 26/27 Exemplo 2 � Exemplos � Numa loja de materiais de construção, um azulejo estampado custa R$2,50. Faça um algoritmo para ler o comprimento e a altura de uma parede (em metros), e depois escrever o valor a ser gasto com a compra de azulejos. Considere que um metro quadrado é formado por 9 azulejos. � Solução � A saída é o valor total gasto com azulejos. � O computador precisa saber o comprimento e a altura da parede. � Quais são os cálculos necessários? 27/27 Exemplo 2 � Solução (cont.) � Multiplicando a altura pelo comprimento, teremos a área da parede (considerando uma parede retangular); � Multiplicando a área pelo número 9, teremos a quantidade de azulejos necessários para preencher esta área; � Uma vez que um azulejo custa R$2,50 (um valor constante), podemos multiplicar a quantidade de azulejos por 2,5 para chegar ao total gasto. 28/27 Exemplo 2 � Solução sem uso de modularização: Variáveis gasto_azulejos, comprimento, altura, area, azulejos: real; Início escrever “Digite o comprimento em metros: ”; ler comprimento; escrever “Digite a altura em metros”; ler altura; area = comprimento * altura; azulejos = area * 9; gasto_azulejos = azulejos * 2.5; escrever “Quantidade de azulejos necessária: “, azulejos; escrever “Valor gasto com azulejos: R$ “, gasto_azulejos; Fim 29/27 Exemplo 2 � Solução (cont.) � Pensando em termos de algoritmo, podemos imaginar três etapas: Variáveis ? ? ?; Início “Obter as dimensões da parede e calcular a área”; “Calcular o valor gasto com azulejos”; “Escrever o resultado calculado”; Fim 30/27 Exemplo 2 � Solução (cont.) � Detalhando o cálculo do valor gasto. Variáveis gasto_azulejos, comprimento, altura, area, qtd_azulejos: real; Início LER_DIMENSOES_E_OBTER_AREA; CALCULAR_VALOR_GASTO; ESCREVER_GASTO; Fim. Módulo CALCULAR_VALOR_GASTO; [[...]]; Módulo LER_DIMENSOES_E_OBTER_AREA; [[...]]; Módulo ESCREVER_GASTO; [[...]]; 6 31/27 Vantagens do uso de funções � Facilita a resolução de problemas complexos; � Viabiliza a divisão do trabalho entre a equipe de desenvolvimento (cada programador ou grupo de programadores pega um pedaço do problema para resolver e trabalha de forma independente); � Desenvolvimento mais rápido de programas (várias funções podem ser escritas em paralelo pelos membros da equipe). 32/27 Vantagens do uso de funções � Incentiva a divisão de responsabilidades; � Reuso de funções desenvolvidas em projetos anteriores ou obtidas externamente diminui o tempo de desenvolvimento de novos programas; � Aumento de qualidade pelo uso de funções cujo funcionamento foi validado em projetos anteriores. 33/27 Exercícios � Implementar o Exemplo 2 � Escreva uma função que receba um número inteiro positivo e retorne o fatorial desse número. � A fábrica de refrigerantes Meia-Cola vende seu produto em três formatos: lata de 350ml, garrafa de 600ml e garrafa de 2 litros. Se um comerciante compra uma determinada quantidade de cada formato, faça um programa para calcular quantos litros de refrigerante ele comprou. Resolva o problema utilizando funções. Dúvidas ?