Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Departamento
Informtica
de
Engenharia
Relatrio de Laboratrios de
Informtica III
GereVendas
(Trabalho Prtico de C)
Grupo 1:
Joo Martins (A68646)
ndice
1.
Mdulos de dados......................................................................................................3
Bool................................................................................................................................3
Venda.............................................................................................................................3
AVL................................................................................................................................3
Tipos enumerados......................................................................................................3
Typedefs de funes....................................................................................................4
Estruturas de dados e tipos exportados......................................................................5
Funes da API..........................................................................................................6
Cliente............................................................................................................................7
Estruturas de dados....................................................................................................7
Funes da API..........................................................................................................8
Produto...........................................................................................................................8
Estruturas de dados....................................................................................................9
Funes da API..........................................................................................................9
LStrings........................................................................................................................10
Estruturas de dados..................................................................................................10
Nmero de Strings por pgina..................................................................................11
Funes da API.........................................................................................................11
CatalogoClientes..........................................................................................................12
Estruturas de dados..................................................................................................12
Funes da API........................................................................................................14
CatalogoProds..............................................................................................................15
Estruturas de dados..................................................................................................15
Funes da API........................................................................................................16
FaturacaoGlobal...........................................................................................................17
Macros......................................................................................................................17
Estruturas de dados..................................................................................................17
Definio de tipos....................................................................................................19
Funes da API........................................................................................................19
Filial.............................................................................................................................22
MemUtils.....................................................................................................................23
Funes da API........................................................................................................23
Leitura..........................................................................................................................23
Macros......................................................................................................................23
Funes da API........................................................................................................24
Estruturas de dados......................................................................................................24
Leitura dos ficheiros e invocao das queries.............................................................25
Ficheiros lidos por omisso......................................................................................25
1. Mdulos de dados
Bool
O standard C89 (tambm conhecido como ANSI C) no define o tipo bool, pelo que
optamos por criar um pequeno ficheiro designado por bool.h, onde inclumos as
seguintes definies:
Este tipo foi utilizado em todos os mdulos em que existem variveis, parmetros ou
valores de retorno que s podem tomar os valores lgicos TRUE ou FALSE.
Venda
Para evitar que o utilizador tenha que utilizar valores numricos ao se referir a cada um
dos tipos de venda, optamos por criar um pequeno mdulo de dados, designado por
venda.h, onde colocamos as seguintes definies:
AVL
A necessidade de ler e consultar grandes volumes de dados tornou indispensvel a
utilizao de estruturas de dados nas quais a insero e a procura sejam eficientes. Por
esse motivo, optamos pela utilizao de rvores AVL genricas para armazenar a maior
parte da informao lida a partir dos ficheiros de dados, garantindo assim que cada
operao de insero ou procura seja realizada em tempo O(log n) .
Tipos enumerados
Para assinalar o fator de balano de cada nodo de uma AVL, definimos o tipo
enumerado FatorBalanco. Note-se que o utilizador do mdulo de AVLs no necessita
de ter informao relativa ao fator de balano dos nodos da AVL que est a utilizar, pelo
que a definio deste tipo enumerado foi colocada em AVL.c, sendo expressa por:
3
Funo usada para criar uma cpia do valor armazenado num dado nodo de uma
AVL:
typedef void* (*Duplicador) (void *);
Funo que liberta a memria alocada para o valor guardado no nodo de uma
AVL:
typedef void (*LibertarNodo) (void *);
AVL_NODO:
typedef struct nodoAVL{
void* valor;
FatorBalanco fatorBalanco;
struct
nodoAVL
*esquerda,
*direita;
} AVL_NODO;
Funes da API
AVL criaAVL (
Atualizador atualiza,
Comparador compara,
Duplicador duplica,
LibertarNodo liberta
)
Cria uma AVL vazia, que vai utilizar a funo de comparao 'compara'. A funo
de comparao obrigatria. As restantes funes so opcionais. Se no for
fornecida uma funo de atualizao, a AVL criada admite repeties. Se no for
passada uma funo de libertao de nodos, a AVL criada utiliza a funo free()
para libertar cada nodo.
AVISO: Se o utilizador no passar uma funo de duplicao, no criada uma
cpia aquando da insero de um valor na AVL e as funes inorderAVL() e
procuraAVL() devolvem o contedo da prpria AVL!
Retorna:
Em caso de sucesso retornada a AVL criada. Quando no fornecida uma
funo de comparao ou h uma falha de alocao, devolvido NULL.
Insere um valor numa AVL previamente criada. Caso tenha sido passado um
duplicador aquando da criao da arvore, o valor inserido uma cpia do
original. Caso contrrio, o original.
Retorna:
rvore com o valor inserido em caso de sucesso. NULL em casos de falha de
alocao.
Retorna:
Altura da AVL passada como parmetro.
void** inorderAVL(const AVL arvore)
Retorna:
Em caso de sucesso, devolvido um array com os valores dos nodos (cpias
se a funo de duplicao tiver sido passada durante a criao da AVL)
resultante da travessia inorder da AVL. Caso contrrio, devolvido NULL.
Nota: o tipo AVL o nico tipo acessvel ao exterior e as funes da API no fazem
qualquer referncia a TCD_AVL.
Cliente
O tipo Cliente foi definido para esconder do utilizador a representao interna do
cdigo de cada cliente, permitindo ao mesmo tempo que a API dos restantes mdulos
que lidam com clientes seja mais sugestiva e agradvel.
Estruturas de dados
No ficheiro cliente.c podemos encontrar a definio da estrutura de dados ilustrada a
seguir:
Cliente:
struct cliente {
char* codigoCliente;
};
codigoCliente apontador para o
cdigo do cliente. Sendo declarado
como um char*, o cdigo de
cliente pode ter qualquer dimenso,
uma vez que aponta para uma
String alocada com a funo
Embora a nica informao armazenada na struct cliente seja um apontador para o
cdigo do cliente, o utilizador da API no tem que saber o que est guardado dentro
desta struct, pelo que no ficheiro cliente.h temos apenas:
typedef struct cliente* Cliente;
Deste modo, garantimos que o tipo Cliente opaco, o que leva a que o utilizador s o
possa manipular atravs das funes da API que passamos a descrever.
Funes da API
Retorna:
1 letra do cdigo do cliente passado como parmetro.
int comparaCodigosCliente (Cliente c1, Cliente c2)
Compara os cdigos de dois clientes.
Retorna:
devolvido um valor < 0 se o cdigo de c1 for menor que o de c2, = 0 se os
cdigos de c1 e c2 forem iguais e > 0 se o cdigo de c1 for maior que o de
c2.
Produto
O tipo Produto , em termos estruturais, semelhante ao tipo Cliente e tambm foi
definido pelas mesmas razes que o tipo Cliente, i.e.: esconder a representao interna
do cdigo de cada produto e tornar a API dos restantes mdulos que lidam com
produtos mais sugestiva.
Estruturas de dados
No ficheiro produto.c encontra-se a definio da estrutura de dados a seguir ilustrada:
Produto:
struct produto {
char* codigoProduto;
};
codigoProduto apontador para o
cdigo
do
produto.
Sendo
declarado como um char*, o
cdigo de produto pode ter
qualquer dimenso, uma vez que
aponta para uma String alocada
Analogamente struct cliente, a nica informao armazenada na struct produto um
apontador para o cdigo do produto, mas o utilizador, tendo apenas acesso ao ficheiro
produto.h s conhece a seguinte definio do tipo abstrato de dados Produto:
typedef struct produto* Produto;
Logo o tipo produto tambm opaco.
Funes da API
10
LStrings
A grande quantidade de dados na forma de Strings, devolvidos por algumas das funes
das APIs que sero apresentadas a seguir, tornou necessrio o desenvolvimento de uma
estrutura de dados navegvel com a noo de ndice e de pgina. Como a estrutura
descrita no fundo uma lista de Strings genrica, o grupo designou-a por LStrings.
Uma vez criada, uma LStrings permite que o utilizador decida se pretende ir para a
pgina seguinte, para a pgina anterior, para uma pgina sua escolha ou ento para a
primeira ou ltima pgina. Estando na pgina pretendida, o utilizador pode ento pedir
para obter uma cpia dos contedos dessa pgina e em seguida pode obter os contedos
dessa pgina, linha a linha.
Estruturas de dados
No ficheiro LStrings.c, encontram-se as definies dos tipos concretos de dados
utilizados para implementar a lista de Strings e o tipo pgina:
LStrings:
Pagina:
struct lStrings{
int total;
char** strings;
int pag;
int ndice;
};
struct pagina{
int total;
char** strings;
int ndice;
};
11
Mais uma vez, a implementao de cada uma das estruturas de dados apresentada foi
escondida do utilizador declarando no ficheiro .h os tipos abstratos de dados como
apontadores para os respetivos tipos concretos de dados, i.e.:
typedef struct lStrings* LStrings;
typedef struct pagina* Pagina;
Ficando assim assegurada a opacidade dos tipos LStrings e Pagina.
Nmero de Strings por pgina
O nmero de Strings por pgina de cada LStrings criada fixo e est definido no
ficheiro LStrings.h, da seguinte forma:
Funes da API
12
Retorna:
sempre retornado NULL.
13
CatalogoClientes
O mdulo catalogoClientes tem todas as funes e estruturas de dados utilizadas para
guardar, por ordem alfabtica, todos os clientes lidos a partir do ficheiro clientes.txt.
Estruturas de dados
Tendo em considerao o facto de cada cdigo de cliente comear por uma letra
maiscula e de existirem 26 iniciais possveis, o grupo optou por estruturar o catlogo
de clientes como um array de 26 AVLs que na posio de ndice 0 tem uma AVL com
todos os clientes cujo cdigo comea por A, na posio de ndice 1 tem uma AVL com
todos os clientes cujo cdigo comea por B e assim sucessivamente. Estruturar o
catlogo de clientes desta forma tem a vantagem de permitir inseres e procuras
bastante mais eficientes, dado que em vez de termos uma AVL com todos os cdigos de
clientes temos 26 AVLs em que cada uma relativamente pequena. Esta estruturao
tambm facilita a obteno de todos os cdigos de cliente comeados por uma dada
14
letra.
Partindo da anlise exposta no pargrafo anterior, o grupo declarou a struct
catClientes-no ficheiro catalogoClientes.c, cuja ilustrao passamos a apresentar:
struct catClientes {
AVL catalogo[MAX_AVL];
};
MAX_AVL macro que
corresponde ao valor 26;
catalogo array de 26 AVLs. A
AVL na posio de ndice 0 tem os
clientes cujo cdigo comea por
A, a posio de ndice 1 tem os
clientes com cdigo comeado por
B e assim sucessivamente;
[0]
Clientes cujo cdigo
comea por A
[1]
Clientes cujo cdigo
comea por B
[25]
Clientes cujo cdigo
comea por Z
"A2652
"
"A1319"
"A1300"
"A3938"
"A2646"
"A3984"
16
Funes da API
CatClientes criaCatClientes ()
Aloca espao e inicializa um novo catlogo de clientes.
Retorna:
Um catlogo de clientes vazio em caso de sucesso. NULL em caso de falha de alocao.
17
CatalogoProds
O mdulo catalogoProds semelhante ao mdulo catalogoClientes, visto que contm
as estruturas que permitem guardar, por ordem alfabtica, todos os produtos lidos a
partir do ficheiro produtos.txt.
Estruturas de dados
Os cdigos de produto, tal como os cdigos de cliente, comeam por uma das 26 letras
maisculas do alfabeto. Alm disso, o tipo de operaes que se pretende realizar sobre
um catlogo de produtos idntico ao tipo de operaes efetuadas sobre um catlogo de
clientes, logo a estruturao que escolhemos para o catlogo de produtos idntica
que j foi apresentada para o catlogo de clientes.
A nica diferena relativamente ao catlogo de clientes que neste caso estamos a
guardar cdigos de produtos e portanto temos uma estrutura designada por struct
catProds-no ficheiro catalogoProdutos.c, que pode ser ilustrada por:
struct catProds{
AVL catalogo[MAX_AVL];
};
MAX_AVL macro que
corresponde ao valor 26;
catalogo array de 26 AVLs. A
AVL na posio de ndice 0 tem os
produtos cujo cdigo comea por
A, a posio de ndice 1 tem os
produtos com cdigo comeado
por B e assim sucessivamente;
[0]
Produtos cujo cdigo
comea por A
[1]
Produtos cujo cdigo
comea por B
[25]
Produtos cujo cdigo
comea por Z
Nota: cada nodo das AVLs da struct catProds tem apenas uma String correspondente
ao cdigo de um determinado produto.
A definio do tipo abstrato de dados do catlogo de produtos tambm semelhante s
restantes definies de TADs apresentadas anteriormente, pelo que temos, no ficheiro
catalogoProdutos.h, a linha:
typedef struct catProds* CatProds;
18
Funes da API
CatProds criaCatProds ()
Aloca espao e inicializa um novo catlogo de produtos.
Retorna:
Um catlogo de produtos vazio em caso de sucesso. NULL em caso de falha de alocao.
19
FaturacaoGlobal
O mdulo FaturacaoGlobal permite obter informaes relativas s vendas mensais
e/ou anuais dos vrios produtos, como:
O total de vendas e total faturado com um produto num dado ms, em modo
Normal (N) e em Promoo (P) (query 3);
A lista ordenada dos cdigos de produtos que ningum comprou (query 4);
Total de vendas e total faturado num intervalo fechado de meses (query 6);
Quais foram os N produtos mais vendidos do ano (query 10);
A faturao global possibilita tambm a distino das vendas/faturao de cada filial e
referencia todos os produtos, mesmo os no vendidos, de forma a garantir uma resposta
eficiente query 4. Note-se, contudo, que no feita qualquer referncia a clientes e
qualquer informao relativa aos mesmos deve ser obtida no mdulo Filial.
Macros
No ficheiro faturcaoGlobal.c definimos as seguintes macros:
Estruturas de dados
Ao analisarmos as queries a que a faturao global deve ser capaz de responder
constatamos que duas delas (as queries 3 e 6) tm como chave de pesquisa o ms,
enquanto que as outras duas (as queries 4 e 10) requerem informaes sobre as vendas
do ano. Tendo estes aspetos em considerao, optamos por ter duas estruturas principais
distintas na faturao global:
Uma estrutura em que so referenciados todos os produtos e que permite obter
informao relativa s vendas anuais de cada um deles, para cada filial;
Uma estrutura que tem informao sobre as vendas de cada ms e que permite
distinguir compras N de compras P, bem como as vendas/faturao de cada
filial;
20
Partindo da anlise acima descrita, optamos pela seguinte estruturao dos dados:
FaturacaoGlobal:
FatAnualProd
todosProdutos)
(nodo
da
AVL
struct fatGlobal{
AVL todosProdutos; struct fatAnualProd{
FatMes
char* prod;
fatMensal[N_MESES+1];
int
};
totalUnids[N_FILIAIS+1];
todosProdutos
AVL }; com
informao sobre as vendas anuais de
todos os produtos;
prod String com o cdigo de um
fatMensal array de estruturas
produto;
com
informao relativas faturao
totalUnids
de
array que na posio
cada ms;
de ndice i tem o nmero de unidades
do produto prod vendidas durante o
Nota: o array fatMensal
ano na
temfilial i;
comprimento N_MESES+1 para que
o possamos comear a indexar a
partir da posio de ndice 1.
FatMes:
struct fatMes{
int totalVendas;
double totalFaturado;
AVL fatProds;
};
totalVendas total de vendas do ms;
totalFaturado total faturado no ms;
fatProds AVL com informao sobre a faturao de cada um dos produtos
vendidos no ms;
21
Definio de tipos
Tipos auxiliares (i.e.: definidos em faturacaoGlobal.c)
As structs fatMes e fatAnualProd so estruturas auxiliares. O utilizador no necessita
de ter conhecimento das mesmas para obter as vrias informaes que possa desejar
sobre a faturao dos produtos. Por esse motivo, a definio dos tipos FatMes e
FatAnualProd foi colocada no ficheiro faturacaoGlobal.c, sendo expressa por:
typedef struct fatMes* FatMes;
typedef struct fatAnualProd* FatAnualProd;
Tipos exportados (i.e.: definidos em faturacaoGlobal.h)
O utilizador ter naturalmente que conhecer o tipo abstrato de dados FaturacaoGlobal,
logo no ficheiro faturacaoGlobal.h temos:
typedef struct fatGlobal FaturacaoGlobal;
O grupo optou tambm por exportar o tipo abstrato FatProdMes, que no mais do que
a referncia da struct fatProdMes, cuja implementao o utilizador desconhece. Assim,
no ficheiro faturacaoGlobal.h temos tambm:
typedef struct fatProdMes FatProdMes;
A razo para exportamos este tipo est relacionada com a query 3, uma vez que nesta
query o utilizador precisa de obter, para um dado produto e um dado ms, o total
faturado em modos N e P (podendo optar por obter resultados globais ou por filial).
Ora, a struct fatProdMes tem todas essas informaes, portanto optamos por permitir
que o utilizador obtenha, com a funo obterFatProdMes(), a referncia da struct
fatProdMes para o produto e ms que pretende. Posto isto, o utilizador pode, com
algumas das funes da API da faturao global, obter informao relativa aos campos
que pretende. importante notar que o tipo FatProdMes opaco, logo o utilizador no
tem conhecimento sobre a sua implementao, no consegue desreferenci-lo e tem
obrigatoriamente que usar as funes disponibilizadas na API de forma a conseguir as
informaes que deseja.
Funes da API
FaturacaoGlobal criaFaturacaoGlobal ()
22
FaturacaoGlobal registaVenda (
FaturacaoGlobal fg,
Produto p,
double precoUnit,
int quantidade,
TipoVenda tipo,
int filial,
int ms
)
Regista uma venda na faturao global.
Retorna:
A faturao global aps a insero, em caso de sucesso. NULL em caso de
falha de alocao.
23
Retorna:
Cpia da faturao do produto p, no ms especificado, em caso de sucesso.
NULL
em caso de falha de alocao..
24
25
Filial
O mdulo Filial permite obter informaes relativas s compras realizadas
por cada cliente, discriminando os cdigos dos produtos comprados por
cada cliente, o ms e a filial onde foram comprados, os tipos de compras
que foram realizados (P e/ou N), o total gasto na compra desses produtos e
o total de unidades compradas desse produto por ms. Este mdulo foi
estruturado com o objetivo de ter uma resposta eficiente s seguintes
queries:
Estruturas de dados
Analisando as queries, rapidamente se percebe que a chave principal de pesquisa neste
26
mdulo o cdigo de clientes, uma vez que 5 das 6 queries que fazem uso deste mdulo
tm como uma das chaves o cdigo de cliente. Atendendo a isto, estruturamos a Filial
da seguinte forma:
Definies dos tipos:
Como vimos anteriormente, existem 2 tipos(alias) para AVL's de forma a clarificar o
tipo dos nodos:
typedef AVL AVL_ComprasPorCliente;
typedef AVL AVL_ComprasDoProduto;
Estes tipos esto definidos no ficheiro filial.c e no faz sentido que estejam no ficheiro
filial.h porque o utilizador da API no precisa sequer de saber que estamos a
implementar o mdulo custa de AVLs.
O nico tipo exportado deste mdulo o tipo Filial, definido como:
typedef struct filial* Filial;
Como o ficheiro filial.h no revela a constituio das estruturas, mantemos o tipo Filial
completamente opaco aos utilizadores da API. Atravs das funes da API definidas
abaixo, conseguimos obter toda a informao que precisamos para as queries, a partir de
uma varivel do tipo Filial.
Funes da API
Filial criaFilial ()
Filial registaCompra (
Filial filial,
Cliente cliente,
Produto produto,
int mes,
TipoVenda tipoVenda,
int unidades,
double preco
)
Regista os dados de uma compra numa filial.
Retorna:
A filial resultante, em caso de sucesso. NULL em caso de falha de alocao.
27
Retorna:
Nmero total de clientes que compraram na filial passada como parmetro.
void comprou (Filial filial, Cliente cliente, Produto produto, bool *comprouN, bool *comprouP)
Dado um cliente, uma Filial e um produto, verifica se o cliente comprou em modo Normal e se
comprou em modo de promoo. Os resultados so guardados em cada uma das variveis passadas
por referncia.
28
29
Funes da API
int leInt ()
L um valor inteiro do stdin e faz o flush do mesmo, se necessrio.
Retorna:
Inteiro lido. Se no for possvel converter os carateres introduzidos para um
valor interiro, devolvido 0.
double leDouble ()
L um double do stdin e faz o flush do mesmo, se necessrio.
Retorna:
Double lido. Se no for possvel converter os carateres introduzidos para um
double, devolvido 0.
int leChar ()
L um carater do stdin e faz o flush do mesmo, se necessrio.
Retorna:
devolvido o carater lido, em caso de sucesso. Em caso de erro ou de end of
file, devolvido EOF.
Estruturas de dados
Todas as estruturas de dados utilizadas no ficheiro main.c so importadas dos vrios
mdulos de dados expostos at agora. Assim sendo, antes da funo main() temos:
30
32
33
Navegao
Antes de apresentarmos a query 2, convm primeiro referir como navegamos na
quantidade considervel de Strings produzida por vrias queries (nomeadamente a
query 2).
Como j foi visto anteriormente, a API de LStrings j tem todas as funes necessrias
para navegar numa lista de Strings e obter pginas da mesma. Assim sendo, no ficheiro
main.c bastou definir uma funo navega() que recebe uma LStrings (a que
chamaremos lStr).
Se lStr for uma lista vazia, apresentada a mensagem Lista vazia e no feito
qualquer tipo de navegao.
Se lStr tiver pelo menos uma String, chamada a funo auxiliar
imprimeInformacaoLStrings() para imprimir no ecr o nmero de entradas, o nmero
total de pginas e o nmero de entradas por pgina de lStr. Em seguida entramos no
ciclo que:
1. Limpa o ecr;
2. Invoca a funo obterPag(), para obter a pgina atual de lStr;
3. Passa a pgina obtida para a funo auxiliar apresentaPag() que vai invocar
ciclicamente obterLinha(), seguida de puts() para apresentar cada uma das
linhas da pgina recebida;
4. Apresenta o menu da navegao:
34
35