30
IAED, 2014/2015 1 Mesmas estruturas são usadas com vários tipos de dados O procedimento para inserir um inteiro, real, uma string ou uma estrutura numa lista é similar O código pode (e deve) ser re-utilizado Abstracção dos detalhes de implementação ADTs (Abstract Data Types): Motivação Listas Pilhas Amontoado FIFOs Inteiros Reais Strings Estruturas

ADTs (Abstract Data Types): Motivação · • Cada módulo providencia um conjunto de funcionalidades bem definido e coerente, incluindo a especificação, a documentação e os

Embed Size (px)

Citation preview

IAED, 2014/2015 1

•  Mesmas estruturas são usadas com vários tipos de dados

•  O procedimento para inserir um inteiro, real, uma string ou uma estrutura numa lista é similar

•  O código pode (e deve) ser re-utilizado •  Abstracção dos detalhes de implementação

ADTs (Abstract Data Types): Motivação

Listas

Pilhas

Amontoado

FIFOs

Inteiros

Reais

Strings

Estruturas

IAED, 2014/2015 2

ADT e Colecções de Objectos

•  ADTs são úteis para manipular colecções de objectos

•  Operações típicas –  Comparações entre objectos –  Operações de entrada e saída (leitura e escrita) –  Inserção em colecções –  Apagamento de colecções –  Alteração de propriedades (e.g., prioridade)

•  ADTs deste tipo são denominados filas generalizadas

IAED, 2014/2015 3

Vantagens do Uso de ADTs

•  Solução elegante •  Separa os problemas:

–  Alto nível: interface de operações sobre tipo de dados –  Baixo nível: como manter as estruturas de dados

•  Permite comparar diferentes implementações •  Permite re-utilizar o código

•  Para utilizarmos ADTs, vamos aprender um pouco mais de C…

IAED, 2014/2015

Regras de Scope

IAED, 2014/2015 5

Organização de Programas

•  Programas normalmente dividos em vários ficheiros •  Cada ficheiro permite implementar conjunto de

funcionalidades relacionadas

aritmetica.c

trigonom.c

estatistica.c

calculadora.c

IAED, 2014/2015 6

Regras de Scope

•  Em C todas as variáveis têm um scope, i.e., um âmbito de acessibilidade & visibilidade, que podem tomar 1 de 4 (na realidade 3) estados: –  Bloco (variáveis locais) –  Função

–  Ficheiro (variáveis globais apenas visíveis dentro do ficheiro onde são declaradas)

–  Programa (variáveis globais visíveis em múltiplos ficheiros)

IAED, 2014/2015 7

Block scope

•  Em C todas as variáveis têm um scope, i.e., um âmbito de acessibilidade & visibilidade –  Bloco

int soma(int v[], int n) { int i, soma=0; for (i=0 ; i<n; i++) soma+=v[i]; return soma;

}

IAED, 2014/2015 8

Block scope

•  Em C todas as variaveis tem um scope, i.e., um âmbito de acessibilidade & visibilidade –  Bloco

•  A utilização do qualificador static permite manter o valor da variável entre chamadas à função

int soma(int v[], int n) { int i,

static int soma=0; for (i=0 ; i<n; i++) soma+=v[i]; return soma;

}

IAED, 2014/2015 9

Block scope

•  Em C todas as variaveis tem um scope, i.e., um âmbito de acessibilidade & visibilidade –  Bloco

void bubble(int a[], int l, int r){ int i, j; for (i = l; i < r; i++) for (j = r; j > i; j--) if (a[j-1]>a[j]){ int t = a[j-1]; a[j-1]=a[j]; a[j]=t; };

}

IAED, 2014/2015 10

File & Program scope: “variáveis globais”

•  Um programa C pode ser composto por um conjunto de objectos externos, que podem ser variáveis ou funções

•  Podem ser utilizadas por qualquer função, ao contrário de variáveis internas/locais, que apenas podem ser utilizadas dentro da uma função ou bloco

int acumulador; void soma(int valor) { acumulador += valor; }

IAED, 2014/2015 11

File scope: “variáveis globais estáticas”

•  Variáveis globais definidas como estáticas permitem limitar o seu scope ao ficheiro em que são definidas

•  Funções também podem ser definidas como estáticas: –  Limita scope da função entre ponto da definição e o fim do

ficheiro onde definição ocorre

static int acumulador; void soma(int valor) { acumulador += valor; }

IAED, 2014/2015 12

Program scope: “variáveis externas”

•  Uma variável externa é definida quando são indicadas as propriedades da variável, e quando são especificados os seus requisitos em termos de memória

•  Uma variável externa é declarada quando apenas são indicadas as suas propriedades

•  extern int b; •  Uma variável apenas pode ter uma definição, embora

possa ser declarada várias vezes –  Dimensão de um array obrigatória na definição do array, mas

opcional na declaração –  Inicialização de uma variável externa apenas pode ter lugar na

definição da variável

int a;

extern int a;

IAED, 2014/2015

De uma forma geral, temos que…

•  Os programas são divididos em vários módulos

•  Cada módulo providencia um conjunto de funcionalidades bem definido e coerente, incluindo a especificação, a documentação e os testes de validação necessários.

•  No caso da programação em C, cada um desses

módulos é em geral implementado em ficheiros diferentes e, de facto, cada módulo pode ser subdividido também por vários ficheiros.

IAED, 2014/2015

De uma forma geral, temos que…

•  Existem em geral dois tipos de ficheiros:

–  header files, ou ficheiros de cabeçalho, onde devem ser incluídas todas as declarações partilhadas para um dado módulo, incluindo o cabeçalho das funções e os tipos de dados;

–  source files, ou ficheiros fonte, onde devem ser

implementadas todas as funções.

IAED, 2014/2015 15

calculadora.h

Header Files (Ficheiros de Cabeçalho)

•  São utilizados para incluirem todas as declarações partilhadas por mais de um ficheiro.

aritmetica.c

trigonom.c

estatistica.c

calculadora.c

IAED, 2014/2015 16

Exemplo 1: “variáveis externas”

•  Variáveis externas –  utilizadas antes de serem definidas, ou definidas noutro ficheiro,

deverão ser declaradas com a palavra-chave extern

main.c

#include “stuff.h” int x; int main() { x=2; print(); return 0; }

stuff.h

#include <stdio.h> void print(); extern int x;

stuff.c

#include “stuff.h” void print() { printf(“%d\n”,x); }

#ifndef _STUFF_ #define _STUFF_ #endif

IAED, 2014/2015 17

Exemplo 1: “variáveis externas”

•  Variáveis externas –  utilizadas antes de serem definidas, ou definidas noutro ficheiro,

deverão ser declaradas com a palavra-chave extern

main.c

#include “stuff.h” int x; int main() { x=2; print(); return 0; }

stuff.h

#include <stdio.h> void print(); extern int x;

stuff.c

#include “stuff.h” void print() { printf(“%d\n”,x); }

#ifndef _STUFF_ #define _STUFF_ #endif

Aqui estou a definir x e a reservar memoria para um inteiro

Aqui não estou a reservar memória.

IAED, 2014/2015

Exemplo 2: Módulo para números complexos

•  complexos.h

#ifndef COMPLEXOS_H #define COMPLEXOS_H typedef struct { float real, img; } complexo; complexo soma(complexo a, complexo b); complexo le_complexo(); void escreve_complexo(complexo a); #endif

Garante que este ficheiro é apenas incluído uma vez.

IAED, 2014/2015

Exemplo 2: Módulo para números complexos •  complexos.c #include <stdio.h>

#include "complexos.h"

complexo soma(complexo a, complexo b) { a.real += b.real; a.img += b.img; return a; }

complexo le_complexo() { complexo a; char sign; scanf("%f%c%fi", &a.real, &sign, &a.img); if (sign == '-’) a.img *= -1;

return a; } void escreve_complexo(complexo a) { if (a.img >= 0) printf("%f+%fi", a.real, a.img); else printf("%f%fi", a.real, a.img); }

IAED, 2014/2015

Exemplo 2: Módulo para números complexos •  main.c #include <stdio.h>

#include "complexos.h"

int main() { complexo x, y, z; x = le_complexo(); y = le_complexo(); z = soma(x, y);

escreve_complexo(x); printf(" + "); escreve_complexo(y); printf(" = "); escreve_complexo(z);

printf("\n"); return 0; }

$ gcc -Wall -ansi -pedantic -o complexos main.c complexos.c

Compilação!

IAED, 2014/2015

I/O Operações sobre ficheiros

IAED, 2014/2015 24

Operações sobre ficheiros

•  Até este momento fizemos sempre leituras do stdin e escrevemos sempre para o stdout. Vamos ver agora como realizar estas operações sobre ficheiros.

•  Como abrir um ficheiro?

FILE *fp; fp=fopen(”tests.txt", "r");

Modo de abertura do ficheiro. Neste caso estamos a abrir o ficheiro em modo de leitura

Ponteiro para ficheiro

IAED, 2014/2015 25

Operações sobre ficheiros

•  Até este momento fizemos sempre leituras do stdin e escrevemos sempre para o stdout. Vamos ver agora como realizar estas operações sobre ficheiros.

•  Como abrir um ficheiro?

r – abre para leitura (read) w – abre um ficheiro vazio para escrita (o ficheiro não precisa de existir) a – abre para acrescentar no fim (“append” ; ficheiro não precisa de existir) r+ – abre para escrita e leitura; começa no início; o ficheiro tem de existir w+ – abre para escrita e leitura (tal como o “w” ignora qualquer ficheiro que

exista com o mesmo nome, criando um novo ficheiro) a+ – abre para escrita e leitura (output é sempre colocado no fim) …mas há mais

Modos de abertura

IAED, 2014/2015 26

Exemplo #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("teste.txt", "r"); if (fp == NULL) { printf(“teste.txt: No such file or directory\n”); exit(1);

} return 0; }

Se não conseguir abrir fp fica igual a NULL

IAED, 2014/2015 27

Exemplo #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("teste.txt", "r"); if (fp == NULL) { perror(“teste.txt”); exit(1);

} return 0; }

Escreve a mesma mensagem de erro.

IAED, 2014/2015 28

Exemplo 2 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("teste.txt", "r"); if (fp == NULL) { perror(“teste.txt”); exit(1);

} fclose(fp); return 0; }

Fecha o ficheiro

IAED, 2014/2015 29

Exemplo 3 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("teste.txt", ”w"); if (fp == NULL) { perror(“teste.txt”); exit(1);

} fprintf(fp, "Hi file!\n"); fclose(fp); return 0; }

Escreve para um ficheiro

IAED, 2014/2015 30

Exemplo 3 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; fp = fopen("teste.txt", ”w"); if (fp == NULL) { perror(“teste.txt”); exit(1);

} fputs("Hi file!”, fp); fclose(fp); return 0; }

Escreve para um ficheiro (alternativa)

IAED, 2014/2015 31

Exemplo 4 #include <stdio.h> #include <stdlib.h> int main() { FILE *myfile; int i; float mydata[100]; myfile = fopen(”info.dat", ”r"); if (myfile== NULL) { perror(“info.dat”); exit(1);

} for (i=0;i<100;i++) fscanf(myfile,”%f”,&mydata[i]); fclose(myfile); return 0; }

Lê um conjunto de 100 floats guardados num ficheiro

IAED, 2014/2015 32