Você está na página 1de 10

A decomposio hierrquica,

ou decomposio do topo para a base (top-down),

Programao II
2011/2012
Beatriz Carmo DI-FCUL Engenharia Geogrfica Estatstica Aplicada Outros
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 1

consiste em decompor um problema complexo num conjunto de problemas mais pequenos. Ao avanar na anlise de cada um dos problemas estes vo sendo refinados passo a passo (stepwise refinement) aplicada a estratgia dividir para conquistar
Na recurso tambm aplicada esta estratgia, mas cada subproblema mais simples semelhante ao problema inicial
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 2

Paradigma da programao procedimental


Algumas linguagens de programao, como o C, tm funes que permitem isolar pequenas solues as quais podem ser usadas na construo de solues mais complexas (funes que usam funes)

Abstraco procedimental
Cada funo ou cada subprograma pode ser visto como uma caixa preta. Quem os usa no precisa de saber como funciona o algoritmo basta saber o que faz e que argumentos precisa Objectivo: separar o propsito da funo/subprograma da sua implementao

Usam o paradigma da programao procedimental


Nesta estratgia temos uma estrutura de dados centralizada. Os problemas elementares so concretizados por funes ou subprogramas que realizam tarefas bem definidas
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 3

H um nfase nas operaes e no encapsulamento dos algoritmos (abstraco procedimental)


bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 4

Paradigma da programao modular


A estrutura de dados necessria para a resoluo de um problema complexo pode ser difcil de gerir como um todo sendo necessrio decompor a estrutura em diversas subestruturas

Abstraco dos dados


Para alm do encapsulamento do algoritmo da programao procedimental, na programao modular h o encapsulamento da estrutura de dados

Decompe-se a aplicao a desenvolver num conjunto de mdulos que cooperam entre si As estruturas de dados so encapsuladas em mdulos
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 5

A abstraco dos dados tem por objectivo separar a definio do mdulo da sua implementao

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

O mdulo:
funciona como uma caixa preta que esconde, quer a estrutura de dados, quer os algoritmos usados nas operaes que os manipulam tem uma interface com o exterior (define/condiciona) deve fornecer um conjunto de operaes to completo quanto possvel - contendo todas as funes necessrias e coerentes para realizar um determinado servio - funcionalidade coesa (highly cohesive) deve ser independente de outros mdulos (loosely coupled),
permitindo a sua substituio por outro, sem afectar os restantes confinando as consequncias de um erro de implementao
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 7

Mdulo
Num mdulo existe informao pblica e informao privada. No C possvel separar o anncio dos servios (informao pblica) ficheiro
com extenso .h

da sua implementao (informao privada) ficheiro


com extenso .c (com o mesmo nome)

O ficheiro com extenso .h composto por tipos pblicos cabealhos/prottipos das funes pblicas constantes (#defines) necessrias ao cliente (exemplo,
PI ou ERRO_OK)
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 8

Exemplo
teste.h #ifndef _TESTE #define _TESTE /* Devolve o factorial de n. * pre: n>=0 e n<=12 */ int fact(int n); #endif
bc@di.fc.ul.pt

Bibliotecas do C (libraries) vs Mdulos


teste.c #include "teste.h" #include <stdio.h> /* Devolve o factorial de n. * pre: n>=0 e n<=12 */ int fact(int n){ . }
9

#include <stdio.h> #include "teste.h" <file> indica ao compilador que deve procurar file na directoria onde esto as bibliotecas do C, normalmente, \usr\include file indica ao compilador que deve procurar file na directoria corrente

GU-ProgII-OL-2011/2012-4 programao modular

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

10

Programao defensiva vs programao por contrato


Cada funo pode ter pr-condies que explicitam as condies que devem ser verificadas para que funcionem como esperado. Na programao defensiva, algumas/todas as prcondies podem/devem ser verificadas no incio da respectiva funo, resultando em eventuais mensagens de erro. Isto implica:
juntar ao cdigo a verificao das pr-condies escrever mensagens de erro independentes do contexto de utilizao
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 11

Programao defensiva vs programao por contrato


Na programao por contrato pressupe-se que h uma separao de papis:
o cliente da funo quem a utiliza e deve us-la de acordo com o contrato estabelecido, o fornecedor da funo quem a implementa e documenta, devendo respeitar o que prometido no contrato.

Assim,
cabe ao cliente verificar que est nas condies de usar a funo de modo a garantir o seu funcionamento correcto, ie, testar se as pr-condies se verificam antes de invocar a funo E adequar a aco a realizar e/ou as mensagens de erro de acordo com o contexto de utilizao
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 12

Ps-condies
Cada funo poder tambm ter uma ps-condio, que informa o cliente sobre o que ela promete fazer, se a pr-condio for satisfeita. As ps-condies fazem parte da descrio do servio Mas a verificao das ps-condies no implementada.

Tipo de Dados Abstracto:


Coleco de dados (usualmente estruturados) com um conjunto de operaes sobre esses dados. Um TDA pode era implementado por um mdulo que inclui a estrutura de dados juntamente com as funes necessrias para manipular os valores dessa estrutura. A implementao fica separada da aplicao que a usa A aplicao no acede directamente estrutura de dados A aplicao independente da implementao do TDA

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

13

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

14

A concretizao de um TDA composta por duas partes: uma interface pblica ficheiro com extenso .h que
descreve as operaes disponveis, tipos pblicos, constantes

Tipo pblico na interface


Para anunciar um tipo pblico deve colocar-se no ficheiro de extenso .h o typedef da estrutura definida no ficheiro de extenso .c (encapsulamento do tipo). No caso de uma estrutura de dados definida com struct, o cliente no deve ter acesso aos seus elementos internos, mas deve poder manipul-los atravs de funes pblicas que manipulem, estas sim, a informao interna do tipo.

uma implementao privada ficheiro com extenso .c


que define a estrutura de dados e implementa as operaes

A interface a forma do cliente usar o TDA.


quem usa

A implementao criada pelo fornecedor e tem de respeitar o que prometido na interface. Uma biblioteca/mdulo no necessariamente um TDA, ela pode conter conjuntos de funes apenas indirectamente relacionadas (como o math.h) e que no definem tipos.
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular

quem implementa

15

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

16

Exemplo
polinomio.h #ifndef _POLINOMIOS #define _POLINOMIOS /* tipos de dados */ /* tipos de dados */ /* polinomio */ typedef struct pol *Polinomio; /* operacoes */ ... #endif
bc@di.fc.ul.pt

Funes tpicas num TDA:


polinomio.c #include "polinomio.h" #include <stdlib.h> #include <math.h>

Construtor cria um novo valor do tipo. Destrutor elimina na memria um dado valor desse tipo. Cpia cria uma cpia idntica de um valor dado. Igualdade verifica se dois valores so iguais. Descritor converte um valor desse tipo numa string.

/* polinomio */ struct pol { double *coefs; int grau; }; /* operacoes */ ...

GU-ProgII-OL-2011/2012-4 programao modular

17

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

18

Compilao envolvendo vrios ficheiros (usando linha de comandos)


Compilar separadamente o ficheiro com extenso .c para criar um ficheiro objecto do mdulo (polinomio.o): gcc -Wall -ansi -c polinomio.c Este objecto no pode ser consultado nem modificado pelo cliente, mas pode ser includo na aplicao final. Criar o ficheiro executvel (usaPolinomio) da aplicao com o comando gcc -Wall -ansi usaPolinomio.c polinomio.o -o usaPolinomio usaPolinomio.c e polinomio.c incluem polinomio.h
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 19

Tratamento de erros
Os erros podem ocorrer quando
as pr-condies no so satisfeitas no foi possvel ter recursos (normalmente, memria) para executar a funo.

Para controlar os erros pode usar-se um conjunto de constantes simblicas para servirem de identificadores do erro ocorrido Estas constantes so definidas no ficheiro de extenso .h e podem ser consultadas pelo cliente atravs de uma funo prpria para esse efeito.

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

20

polinomio.h

polinomio.c

Tratamento de erros
Cada TDA ter duas funes para controlar os erros: erro() que devolve qual o erro devolvido pela ltima funo invocada reset_erro() que inicializa o erro a ausncia de erro
(ver em [Rocha08] uma terceira funo para obter uma mensagem elucidativa sobre o erro)

#ifndef _POLINOMIOS #define _POLINOMIOS

#include "polinomio.h ...


/* erro */ static int erro = POL_OK; /* devolve o erro associado as operacoes sobre polinomios */ int pol_erro (void) { return erro; } /* reinicia o erro associado as operacoes sobre polinomios */ void pol_reset_erro (void) { erro = POL_OK; }
22

...
/* constantes usadas no controlo de erros */ /* operacao correu sem erros */ #define POL_OK 0 /* erro ao reservar memoria para o polinomio */ #define POL_MEM_ERROR 1 #endif

Para implementar estas funes utiliza-se uma varivel privada (uso do modificador/qualificativo static) designada erro (que declarada no ficheiro .c).

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

21

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

Polinomio.c ... Polinomio pol_criar_nulo (int g) { Polinomio p = (Polinomio) malloc (sizeof (struct pol)); if (p != NULL) { p -> grau = g; p -> coefs = calloc (g + 1, sizeof (double)); if (p -> coefs != NULL) return p; /*criou com sucesso estrutura para guardar polinmio*/ /* elimina o polinomio que ja havia reservado*/ free (p); } erro = POL_MEM_ERROR; return NULL; }
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 23 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 24

Principais TDA
Elementos matemticos e operaes associadas:
nmeros complexos polinmios vectores matrizes conjuntos

Armazenamento de coleces de dados:


lista pilha fila fila com prioridade rvore binria

ficheiro polinomio.h

Interface para o TDA Polinmio


/** * Interface para o tipo de dados abstracto Polinomio */ #ifndef _POLINOMIOS #define _POLINOMIOS /* tipos de dados */ /* polinomio, apt para struct pol */ typedef struct pol *Polinomio;

/* operacoes */ /* criar um polinomio nulo com o grau indicado */ /* pre: g >= 0 */ Polinomio pol_criar_nulo (int g); /* escrever um coeficiente num polinomio */ /* pre: pos <= pol_grau(p) */ void pol_escrever_coef (Polinomio p, int pos, double valor); /* ler um coeficiente de um polinomio */ /* pre: pos <= pol_grau(p) */ double pol_ler_coef (Polinomio p, int pos); /* apagar um polinomio */ Polinomio pol_apagar (Polinomio p); /* criar uma copia de um polinomio */ Polinomio pol_copiar (Polinomio p); /* determinar o grau de um polinomio */ int pol_grau (Polinomio p);

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

25

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

26

/* verificar se um polinomio e nulo */ int pol_e_nulo (Polinomio p); /* somar dois polinomios */ Polinomio pol_somar (Polinomio p1, Polinomio p2); /* obter o simetrico de um polinomio */ Polinomio pol_simetrico (Polinomio p); /* subtrair dois polinomios */ Polinomio pol_subtrair (Polinomio p1, Polinomio p2); /* multiplicar dois polinomios */ Polinomio pol_multiplicar (Polinomio p1, Polinomio p2); /* verificar se dois polinomios sao identicos */ int pol_sao_iguais (Polinomio p1, Polinomio p2); /* avaliar um polinomio num ponto */ double pol_avaliar (Polinomio p, double valor); /* operacoes auxiliares para controlo do erro*/ /* devolve o erro associado as operacoes sobre polinomios */ int pol_erro (void); /* reinicia o erro associado as operacoes sobre polinomios */ void pol_reset_erro (void); /* constantes */ /* constantes usadas no controlo de erros */ /* operacao correu sem erros */ #define POL_OK 0 /* erro ao reservar memoria para o polinomio */ #define POL_MEM_ERROR 1 #endif
27 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 28

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

ficheiro polinomio.c
/** Uma implementao do TDA Polinmio * respeitando a interface polinomio.h */ #include "polinomio.h" #include <stdlib.h> #include <math.h> /* tipos de dados */ /* polinomio */ struct pol { double *coefs; int grau; }; /* erro */ static int erro = POL_OK;
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 29

/* operacoes */ /* criar um polinomio nulo com o grau indicado */ /* pre: g >= 0 */ Polinomio pol_criar_nulo (int g) { Polinomio p = malloc (sizeof (struct pol)); if (p != NULL) { p -> grau = g; p -> coefs = calloc (g + 1, sizeof (double)); /* tudo zeros */ if (p -> coefs != NULL) return p; /* elimina o polinomio que ja havia reservado */ free (p); } erro = POL_MEM_ERROR; return NULL; }
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 30

Porqu #include polinomio.h ?

/* operacoes auxiliares para controlo do erro*/ /* escrever um coeficiente num polinomio */ /* pre: pos <= pol_grau(p) */ void pol_escrever_coef (Polinomio p, int pos, double valor) { p -> coefs [pos] = valor; } /* avaliar um polinomio num ponto */ double pol_avaliar (Polinomio p, double valor) { double resultado = 0; int i; int g = pol_grau (p); for (i = 0; i <= g; i++) resultado += p -> coefs [i] * pow (valor, i); } return resultado;
GU-ProgII-OL-2011/2012-4 programao modular 31

/* devolve o erro associado as operacoes sobre polinomios */ int pol_erro (void) { return erro; } /* reinicia o erro associado as operacoes sobre polinomios */ void pol_reset_erro (void) { erro = POL_OK; }

/* ver a implementao das restantes operaes no ficheiro colocado na pgina da disciplina*/


bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 32

bc@di.fc.ul.pt

ficheiro usaPolinomio.c Aplicao que usa o TDA polinmio


/** * Utiliza o modulo _POLINOMIOS para representar um polinomio * de um dado grau e para calcular o valor deste polinomio * em pontos a indicar pelo utilizador. */ #include "polinomio.h" #include <stdio.h> Polinomio ler_polinomio ();

int main (void) { int i; Polinomio p = ler_polinomio (); double x; if (pol_erro () == POL_OK) for (i = 0; i < 3; i++) { printf ("indique o ponto onde calcular o polinomio: "); scanf ("%lf", &x); printf ("o valor do polinomio em %lf e %lf\n", x, pol_avaliar (p, x)); } else printf ("Memoria insuficiente. Fim da execucao."); return 0; }

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

33

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

34

Polinomio ler_polinomio () { int g, i; double v; Polinomio p; printf ("Qual o grau do polinomio a trabalhar? "); scanf ("%d", &g);

Output: Qual o grau do polinomio a trabalhar? 2 Introduza o coeficiente de grau 0: 1 Introduza o coeficiente de grau 1: 0 Introduza o coeficiente de grau 2: 2 indique o ponto onde calcular o polinomio: 1.0 o valor do polinomio em 1.000000 e 3.000000 indique o ponto onde calcular o polinomio: 2.0 o valor do polinomio em 2.000000 e 9.000000 indique o ponto onde calcular o polinomio: 3.0 o valor do polinomio em 3.000000 e 19.000000
35 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular 36

p = pol_criar_nulo (g); if (pol_erro () == POL_OK) for (i = 0; i <= g; i++) { printf ("Introduza o coeficiente de grau %d: ", i); scanf ("%lf", &v); pol_escrever_coef (p, i, v); } H alguma restrio ao valor de i? return p; Como resolver? }
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-4 programao modular

H alguma restrio ao valor de g? Como resolver?

Bibliografia
Estruturas de Dados e Algoritmos em C Antnio Adrego da Rocha, FCA, 2008 Programao II, Notas Tericas, Prof. Joo Neto, LTIC 09/10 Slides de Programao II 08/09, Prof. Carlos Loureno Programao, Algoritmos e Estruturas de Dados, 2 edio, Joo Neto, Escolar Editora, 2008

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-4 programao modular

37

Você também pode gostar