Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do...

165
Aula 13 Tipos Abstractos de Dados IV

Transcript of Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do...

Page 1: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

Aula 13

Tipos Abstractos de Dados IV

Page 2: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação2

Estrutura global do programa (I)

#include <iostream>#include <cassert>

using namespace std;

/** Devolve o máximo divisor comum dos inteiros passados como argumento. @pre m ≠ 0 ou n ≠ 0. @post mdc = mdc(m, n). */int mdc(int const m, int const n) {…}

class Racional {…};

Racional::Racional(int const n) {…}

Racional::Racional(int const n, int const d) {…}

int Racional::numerador() {…}

int Racional::denominador() {…}

void Racional::escreve() {…}

(continua)(continua)

Construtores

Inspectores

Page 3: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação3

Estrutura global do programa (II)

(continuação)(continuação)

void Racional::lê() {…}

Racional& Racional::operator++() {…}

Racional& Racional::operator--() {…}

Racional& Racional::operator*=(Racional const& r2) {…}

Racional& Racional::operator/=(Racional const& r2) {…}

Racional& Racional::operator+=(Racional const& r2) {…}

Racional& Racional::operator-=(Racional const& r2) {…}

void Racional::reduz() {…}

bool Racional::cumpreInvariante() {…}

(continua)(continua)

Modificadores

Auxiliares

Page 4: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação4

Estrutura global do programa (III)

(continuação)(continuação)

/** Produto de dois racionais. @pre V. @post operator* = r1 × r2. */Racional const operator*(Racional r1, Racional const& r2) {…}

/** Divisão de dois racionais. @pre r2 ≠ 0. @post operator/ = r1 / r2. */Racional const operator/(Racional r1, Racional const& r2) {…} /** Soma de dois racionais. @pre V. @post operator+ = r1 + r2. */Racional const operator+(Racional r1, Racional const& r2) {…}

/** Subtracção de dois racionais. @pre V. @post operator- = r1 - r2. */Racional const operator-(Racional r1, Racional const& r2) {…}

(continua)(continua)

Operadores aritméticos

não-membro

Page 5: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação5

Estrutura global do programa (IV)

(continuação)(continuação)

/** Indica se dois racionais são iguais.

@pre V.

@post operator== = (r1 = r2). */bool operator==(Racional const& r1, Racional const& r2) {…} /** Indica se dois racionais são diferentes.

@pre V.

@post operator!= = (r1 ≠ r2). */bool operator!=(Racional const& r1, Racional const& r2) {…}

int main() {…}

Operadores de igualdade e

diferençanão-membro

Page 6: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação6

TAD Racional (construtores)

/** Representa números racionais.

@invariant 0 < denominador_ mdc(numerador_, denominador_) = 1. */class Racional { public: /** Constrói racional com valor inteiro.

@pre V.

@post *this = valor. */ Racional(int const valor = 0);

/** Constrói racional correspondente a numerador/denominador.

@pre denominador ≠ 0.

@post *this = numerador/denominador. */ Racional(int const numerador, int const denominador);

(continua)(continua)

Page 7: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação7

TAD Racional (inspectores)

(continuação)(continuação) /** Devolve numerador da fracção mínima correspondente ao racional. @pre V. @post numerador/denominador() = *this. */ int numerador();

/** Devolve denominador da fracção mínima correspondente ao racional. @pre V. @post 0 < denominador (E n : V : n/denominador = *this mdc(n, denominador) = 1). */ int denominador();

/** Escreve um racional no ecrã no formato de uma fracção. @pre V. @post cout.fail() ou cout contém n/d (ou simplesmente n, se d = 1) em que n e d são os valores de numerador e denominador. */ void escreve(); (continua)(continua)

Page 8: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação8

TAD Racional (modificadores)

(continuação)(continuação) /** Lê do teclado um racional, na forma de dois inteiros sucessivos. @pre *this = r. @post Se cin.good() cin tem dois inteiros n e d disponíveis para leitura, com d <> 0, então *this = n/d cin.fail(), senão *this = r cin.fail(). */ void lê();

/** Incrementa o racional. @pre *this = r. @post operator++ ≡ *this *this = r + 1. */ Racional& operator++();

/** Decrementa o racional. @pre *this = r. @post operator-- ≡ *this *this = r - 1. */ Racional& operator--(); (continua)(continua)

Page 9: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação9

TAD Racional (modificadores)

(continuação)(continuação) /** Multiplica por um racional.     @pre *this = r.     @post operator*= ≡ *this *this = r × r2. */ Racional& operator*=(Racional const& r2);

/** Divide por um racional.     @pre *this = r r2 ≠ 0.     @post operator/= ≡ *this *this = r / r2. */ Racional& operator/=(Racional const& r2);

/** Adiciona de um racional.     @pre *this = r.     @post operator+= ≡ *this *this = r + r2. */ Racional& operator+=(Racional const& r2);

/** Subtrai de um racional.     @pre *this = r.     @post operator-= ≡ *this *this = r - r2. */ Racional& operator-=(Racional const& r2);(continua)(continua)

Page 10: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação10

TAD Racional (implementação)

(continuação)(continuação) private: /** Indica se a CIC se verifica.      @pre V.      @post  cumpreInvariante = 0 < denominador_ mdc(numerador_, denominador_) = 1. */ bool cumpreInvariante();

/** Reduz a fracção que representa o racional. @pre denominador_ ≠ 0 *this = r. @post denominador_ ≠ 0 mdc(numerador_, denominador_) = 1 *this = r. */ void reduz();

    int numerador_;    int denominador_; };

Page 11: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação11

Constantes de TAD

Possível definir constantes de TAD:

Racional const um_terço(1, 3);

Mas é necessário ter alguns cuidados:

cout << um_terço.numerador() << endl;

Porque não

Racional const um_terço(1 / 3);

?

Dá erro!

Page 12: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação12

Constantes de TAD

Compilador admite, por omissão, que as operações alteram a instância implícita

Se a instância implícita for constante, não se podem invocar operações??

Podem, mas apenas as operações que declararem explicitamente que não alteram a instância implícita, pois a tratam como constante

Page 13: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação13

Operações que garantem constância: Sintaxe

class Classe { …

tipo operação(parâmetros) const; …

};

tipo Classe::operação(parâmetros) const { …

}

Page 14: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação14

Operações que garantem constância: Semântica

Podem ser invocadas usando constantes:

Classe const constante;

constante.operação(argumentos);

Proibido para operações não constantes.

Page 15: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação15

Operações que garantem constância: Semântica

Compilador impede método de fazer alterações aos atributos:

tipo Classe::operação(parâmetros) const{ …

atributoatributo = = ……;; …

} Proibido!

Page 16: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação16

Operações que garantem constância: Semântica

Métodos não-constantes

*this é Classe&

Métodos constantes

*this é Classe const&

Page 17: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação17

TAD Racional (construtores)

/** Representa números racionais.

@invariant 0 < denominador_ mdc(numerador_, denominador_) = 1. */class Racional { public: /** Constrói racional com valor inteiro.

@pre V.

@post *this = valor. */ Racional(int const valor = 0);

/** Constrói racional correspondente a numerador/denominador.

@pre denominador ≠ 0.

@post *this = numerador/denominador. */ Racional(int const numerador, int const denominador);

(continua)(continua)

Construtores não podem ser const, pois instância implícita é por eles inicializada!

Page 18: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação18

TAD Racional (inspectores)

(continuação)(continuação) /** Devolve numerador da fracção mínima correspondente ao racional. @pre V. @post numerador/denominador() = *this. */ int numerador() const;

/** Devolve denominador da fracção mínima correspondente ao racional. @pre V. @post 0 < denominador (E n : V : n/denominador = *this mdc(n, denominador) = 1). */ int denominador() const;

/** Escreve um racional no ecrã no formato de uma fracção. @pre V. @post cout.fail() ou cout contém n/d (ou simplesmente n, se d = 1) em que n e d são os valores de numerador e denominador. */ void escreve() const; (continua)(continua)

Inspectores são sempre const!

Aos inspectores também se chama interrogações (queries)

Page 19: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação19

TAD Racional (modificadores)

(continuação)(continuação) /** Lê do teclado um racional, na forma de dois inteiros sucessivos. @pre *this = r. @post Se cin.good() cin tem dois inteiros n e d disponíveis para leitura, com d <> 0, então *this = n/d cin.fail(), senão *this = r cin.fail(). */ void lê();

/** Incrementa o racional. @pre *this = r. @post operator++ ≡ *this *this = r + 1. */ Racional& operator++();

/** Decrementa o racional. @pre *this = r. @post operator-- ≡ *this *this = r - 1. */ Racional& operator--(); (continua)(continua)

Page 20: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação20

TAD Racional (modificadores)

(continuação)(continuação) /** Multiplica por um racional.     @pre *this = r.     @post operator*= ≡ *this *this = r × r2. */ Racional& operator*=(Racional const& r2);

/** Divide por um racional.     @pre *this = r r2 ≠ 0.     @post operator/= ≡ *this *this = r / r2. */ Racional& operator/=(Racional const& r2);

/** Adiciona de um racional.     @pre *this = r.     @post operator+= ≡ *this *this = r + r2. */ Racional& operator+=(Racional const& r2);

/** Subtrai de um racional.     @pre *this = r.     @post operator-= ≡ *this *this = r - r2. */ Racional& operator-=(Racional const& r2);(continua)(continua)

Modificadores nunca são const!

Page 21: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação21

TAD Racional (implementação)

(continuação)(continuação) private: /** Indica se a CIC se verifica.      @pre V.      @post  cumpreInvariante = 0 < denominador_ mdc(numerador_, denominador_) = 1. */ bool cumpreInvariante() const;

/** Reduz a fracção que representa o racional. @pre denominador_ ≠ 0 *this = r. @post denominador_ ≠ 0 mdc(numerador_, denominador_) = 1 *this = r. */ void reduz();

    int numerador_;    int denominador_; };

Page 22: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação22

Métodos afectados

int Racional::numerador() const {…}

int Racional::denominador() const {…}

void Racional::escreve() const {…}

bool Racional::cumpreInvariante() const {…}

Page 23: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação23

Métodos afectados

void Racional::escreve() const { assert(cumpreInvariante());

cout << numerador(); if(denominador() != 1) cout << '/' << denominador();

assert(cumpreInvariante());} Desnecessário! Num método

constante, se o invariante se verifica no início (para a instância implícita), também se verifica no fim.

(Hmmm… Há excepções. )

Page 24: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação24

Métodos afectados

void Racional::escreve() const { assert(cumpreInvariante());

cout << numerador(); if(denominador() != 1) cout << '/' << denominador(); }

Page 25: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação25

Atenção!

Utilização sistemática de const tem grandes vantagens: Obriga programador a pensar

(menos erros) Programador explicita informação acerca do

programa, que o compilador usa para detectar incoerências (erros detectados mais facilmente)

Erros ocorrem mais cedo, durante compilação (erros detectados mais cedo)

Page 26: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação26

Desafio

Quantas invocações de rotinas estão envolvidas em

Racional r(1, 3);

Racional s = r + 2;

ignorando asserções?

Dica:

Quando se constrói um racional à custa de outro, é invocado um construtor por cópia, fornecido automaticamente pelo compilador, e que se limita a copiar os atributos um a um.

Page 27: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação27

Construtor Racional::Racional()Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); assert(cumpreInvariante());

assert(numerador() == n * denominador());assert(numerador() == n * denominador());}

Page 28: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação28

Construtor Racional::Racional()Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Page 29: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação29

Inspector Racional::numerador()int Racional::numerador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return numerador_; }

Page 30: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação30

Inspector Racional::denominador()int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Page 31: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação31

Operador Racional::operator+=()Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Page 32: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação32

Método auxiliar Racional::reduz()void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Page 33: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação33

Operador Racional::operator+()Racional const operator+(Racional r1, Racional const& r2) { r1 += r2;

return r1; }

Page 34: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação34

Operador Racional::operator==()bool operator==(Racional const& r1, Racional const& r2) { return r1.numerador() == r2.numerador() and r1.denominador() == r2.denominador(); }

Page 35: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação35

Traçado

Racional r(1, 3);

Racional s = r + 2;

Número de invocações:

0

Page 36: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação36

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 37: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação37

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 38: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação38

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 39: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação39

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 40: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação40

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 41: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação41

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

1

Page 42: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação42

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

2

Page 43: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação43

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

2

Page 44: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação44

Traçado

int mdc(int const m, int const n){ …

}

Número de invocações:

3

Page 45: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação45

Traçado

int mdc(int const m, int const n){ …

}

Número de invocações:

3

Page 46: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação46

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

3

Page 47: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação47

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

3

Page 48: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação48

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

3

Page 49: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação49

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

3

Page 50: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação50

Traçado

Racional::Racional(int const n, int const d){ assert(d != 0); assert(d != 0);

if(d < 0) { numerador_ = -n; denominador_ = -d; } else { numerador_ = n; denominador_ = d; }

reduz();

assert(cumpreInvariante());assert(cumpreInvariante()); assert(numerador() * d == n * denominador());assert(numerador() * d == n * denominador());}

Número de invocações:

3

Page 51: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação51

Traçado

Racional r(1, 3);

Racional s = r + 2;

Número de invocações:

3

Page 52: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação52

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); assert(cumpreInvariante());

assert(numerador() == n * denominador());assert(numerador() == n * denominador());}

Número de invocações:

4

Page 53: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação53

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); assert(cumpreInvariante());

assert(numerador() == n * denominador());assert(numerador() == n * denominador());}

Número de invocações:

4

Page 54: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação54

Traçado

Racional r(1, 3);

Racional s = r + 2;

Número de invocações:

4

Page 55: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação55

Traçado

Racional const operator+(Racional r1, Racional const& r2) { r1 += r2;

return r1; }

Passagem por valor implica cópia!

Número de invocações:

5

Page 56: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação56

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Construtor por cópia fornecido automaticamente pelo compilador.

Número de invocações:

6

Page 57: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação57

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Número de invocações:

6

Page 58: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação58

Traçado

Racional const operator+(Racional r1, Racional const& r2) { r1 += r2;

return r1; }

Número de invocações:

6

Page 59: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação59

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

7

Page 60: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação60

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

7

Page 61: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação61

Traçado

int Racional::numerador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return numerador_; }

Número de invocações:

8

Page 62: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação62

Traçado

int Racional::numerador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return numerador_; }

Número de invocações:

8

Page 63: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação63

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

8

Page 64: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação64

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

9

Page 65: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação65

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

9

Page 66: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação66

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

9

Page 67: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação67

Traçado

int Racional::numerador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return numerador_; }

Número de invocações:

10

Page 68: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação68

Traçado

int Racional::numerador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return numerador_; }

Número de invocações:

10

Page 69: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação69

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

10

Page 70: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação70

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

11

Page 71: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação71

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

11

Page 72: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação72

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

11

Page 73: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação73

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

11

Page 74: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação74

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

12

Page 75: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação75

Traçado

int Racional::denominador() const{ assert(cumpreInvariante()); assert(cumpreInvariante());

return denominador_; }

Número de invocações:

12

Page 76: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação76

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

12

Page 77: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação77

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

12

Page 78: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação78

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

13

Page 79: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação79

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

13

Page 80: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação80

Traçado

int mdc(int const m, int const n){ …

}

Número de invocações:

14

Page 81: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação81

Traçado

int mdc(int const m, int const n){ …

}

Número de invocações:

14

Page 82: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação82

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

14

Page 83: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação83

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

14

Page 84: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação84

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

14

Page 85: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação85

Traçado

void Racional::reduz(){ assert(denominador_ != 0); assert(denominador_ != 0);

int const divisor = mdc(numerador_, denominador_);

numerador_ /= divisor; denominador_ /= divisor;

assert(denominador_ != 0);assert(denominador_ != 0);

assert(mdc(numerador_, denominador_) == 1);assert(mdc(numerador_, denominador_) == 1);}

Número de invocações:

14

Page 86: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação86

Traçado

Racional& Racional::operator+=(Racional const& r2) { assert(cumpreInvariante());assert(cumpreInvariante()); assert(r2.cumpreInvariante()); assert(r2.cumpreInvariante());

numerador_ = numerador() * r2.denominador() + r2.numerador() * denominador(); denominador_ *= r2.denominador();

reduz();

assert(cumpreInvariante()); assert(cumpreInvariante());

return *this; }

Número de invocações:

14

Page 87: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação87

Traçado

Racional const operator+(Racional r1, Racional const& r2) { r1 += r2;

return r1; }

Devolução por valor implica cópia!

Número de invocações:

14

Page 88: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação88

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Número de invocações:

15

Page 89: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação89

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Número de invocações:

15

Page 90: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação90

Traçado

Racional r(1, 3);

Racional s = r + 2;

Número de invocações:

15

Page 91: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação91

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Número de invocações:

16

Page 92: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação92

Traçado

Racional::Racional(Racional const& original) : numerador_(original.numerador_), denominador_(original.denominador_){}

Número de invocações:

16

Page 93: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação93

Traçado

Racional r(1, 3);

Racional s = r + 2;

// Fim!

Número de invocações:

16

Page 94: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação94

Conclusão

Há muito mais invocações do que suspeitávamos: 16!

Cada invocação implica: Colocar endereço de retorno na pilha Construir parâmetros na pilha Executar corpo Destruir parâmetros da pilha Construir instância de devolução (se for o caso) Retornar ao local de invocação

Ok, ok… Uma das cópias provavelmente não seria feita…

Page 95: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação95

Eficiência

Dados Programa passa 80% do tempo em 20% do

código 20% críticos desconhecidos a priori

Conclusões Esforços de optimização antecipados são perda

de tempo

Page 96: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação96

Mas…

Há hábitos que contribuem para eficiência do programa e não têm qualquer desvantagem:

1. Usar passagem de argumentos por referência constante onde apropriado

2. Usar a palavra chave inline onde apropriado

Já se lá irá, já se lá irá…

Page 97: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação97

Rotinas em-linha (inline)

Corpo não existe num único local, sendo executado sempre que desejado

Corpo é substituído pelo compilador em todos os locais onde a rotina é invocada

Rotinas curtas e sem ciclos devem ser em-linha!

Duas ou três linhas, digamos, excluindo asserções.

Page 98: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação98

Exemplo

inline int soma(int const a, int const b){ return a + b; }

int x1 = 10;int x2 = 30;int x3 = 50;int r = 0;

int main(){ r = soma(x1, x2); r = soma(r, x3); }

int x1 = 10;int x2 = 30;int x3 = 50;int r = 0;

int main(){ r = x1 + x2; r = r + x3; }

Geram mesmo código máquina!Geram mesmo código máquina!

Usar variáveis globais é má ideia! Isto é só um

exemplo!

Page 99: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação99

Exemplo em MAC-1

int soma(int const a, int const b){ return a + b; }

int x1 = 10;int x2 = 30;int x3 = 50;int r = 0;

int main(){ r = soma(x1, x2); r = soma(r, x3); }

jump main # Variáveis: x1 = 10 x2 = 30 x3 = 50 r = 0 # Aqui faz-se a soma:main: lodd x1 # Carrega variável x1 no acumulador. push # Coloca acumulador no topo da pilha. lodd x2 # Carrega variável x2 no acumulador. push # Coloca acumulador no topo da pilha. # Aqui a pilha tem os dois argumentos x1 e x2: call soma # Invoca a função soma. insp 2 # Repõe a pilha (limpeza da casa). # Aqui o acumulador tem o valor devolvido. stod r # Guarda o acumulador na variável r. lodd r # Carrega variável r no acumulador. push # Coloca acumulador no topo da pilha. lodd x3 # Carrega variável x3 no acumulador. push # Coloca acumulador no topo da pilha. # Aqui a pilha tem os dois argumentos r e x3: call soma # Invoca a função soma. insp 2 # Repõe a pilha (limpeza da casa). # Aqui o acumulador tem o valor devolvido. stod r # Guarda o acumulador na variável r. haltsoma: lodl 2 addl 1 retn

Sem inline (nem optimização).

compilação

Page 100: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação100

jump main1030500

lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

????????

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

0pc

?ac

100sp

10099989796959493

pilha

Instruções executadas:

0

Page 101: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação101

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

5pc

?ac

100sp

10099989796959493

3050

????????

Instruções executadas:

1

Page 102: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação102

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

6pc

10ac

100sp

10099989796959493

3050

????????

Instruções executadas:

2

Page 103: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação103

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

10

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

7pc

10ac

99sp

10099989796959493

3050

??????

?

Instruções executadas:

3

Page 104: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação104

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

10

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

8pc

30ac

99sp

10099989796959493

3050

??????

?

Instruções executadas:

4

Page 105: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação105

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 1addl 2retn

3010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

9pc

30ac

98sp

10099989796959493

3050

?????

?

Instruções executadas:

5

Page 106: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação106

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

20pc

30ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

6

Page 107: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação107

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

21pc

10ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

7

Page 108: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação108

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

22pc

40ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

8

Page 109: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação109

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

10pc

40ac

98sp

10099989796959493

3050

????

?

Instruções executadas:

9

Page 110: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação110

jump main10

0lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

11pc

40ac

100sp

10099989796959493

3050

????

?

Instruções executadas:

10

Page 111: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação111

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

12pc

40ac

100sp

10099989796959493

3050

????

?

Instruções executadas:

11

Page 112: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação112

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103010

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

13pc

40ac

100sp

10099989796959493

3050

????

?

Instruções executadas:

12

Page 113: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação113

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

14pc

40ac

99sp

10099989796959493

3050

????

?

Instruções executadas:

13

Page 114: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação114

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

103040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

15pc

50ac

99sp

10099989796959493

3050

????

?

Instruções executadas:

14

Page 115: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação115

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

105040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

16pc

50ac

98sp

10099989796959493

3050

????

?

Instruções executadas:

15

Page 116: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação116

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

20pc

50ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

16

Page 117: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação117

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

21pc

40ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

17

Page 118: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação118

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

22pc

90ac

97sp

10099989796959493

3050

????

?

Instruções executadas:

18

Page 119: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação119

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

17pc

90ac

98sp

10099989796959493

3050

????

?

Instruções executadas:

19

Page 120: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação120

jump main10

40lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

18pc

90ac

100sp

10099989796959493

3050

????

?

Instruções executadas:

20

Page 121: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação121

jump main10

90lodd x1push

lodd x2push

call somainsp 2stod rlodd rpush

lodd x3push

call somainsp2stod rhalt

lodl 2addl 1retn

175040

soma: 202122

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

10111213141516171819

19pc

90ac

100sp

10099989796959493

3050

????

?

Instruções executadas:

21

Page 122: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação122

Exemplo em MAC-1

inline int soma(int const a, int const b){ return a + b; }

int x1 = 10;int x2 = 30;int x3 = 50;int r = 0;

int main(){ r = soma(x1, x2); r = soma(r, x3); }

jump main # Variáveis: x1 = 10 x2 = 20 x3 = 30 r = 0 # Aqui faz-se a soma:main: lodd x1 # Carrega variável x1 no acumulador. addd x2 # Adiciona variável x2 ao acumulador. stod r # Guarda o acumulador na variável r. lodd r # Carrega variável r no acumulador. addd x3 # Adiciona variável x3 ao acumulador. stod r # Guarda o acumulador na variável r. halt

Com inline.

compilação

Page 123: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação123

jump main1030500

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

0pc

?ac

100sp

10099989796959493

pilha

Instruções executadas:

0

Page 124: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação124

jump main1030500

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

5pc

?ac

100sp

10099989796959493

Instruções executadas:

1

Page 125: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação125

jump main1030500

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

6pc

10ac

100sp

10099989796959493

Instruções executadas:

2

Page 126: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação126

jump main1030500

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

7pc

40ac

100sp

10099989796959493

Instruções executadas:

3

Page 127: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação127

jump main10305040

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

8pc

40ac

100sp

10099989796959493

Instruções executadas:

4

Page 128: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação128

jump main10305040

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

9pc

40ac

100sp

10099989796959493

Instruções executadas:

5

Page 129: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação129

jump main10305040

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

10pc

90ac

100sp

10099989796959493

Instruções executadas:

6

Page 130: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação130

jump main10305090

lodd x1addd x2stod rlodd r

addd x3stod rhalt

????????

0x1: 1x2: 2x3: 3

r: 4main: 5

6789

1011

11pc

90ac

100sp

10099989796959493

Instruções executadas:

7Sem inline eram 21…

Page 131: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação131

Comparação

Sem inline:

jump main # Variáveis: x1 = 10 x2 = 30 x3 = 50 r = 0 # Aqui faz-se a soma:main: lodd x1 # Carrega variável x1 no acumulador. push # Coloca acumulador no topo da pilha. lodd x2 # Carrega variável x2 no acumulador. push # Coloca acumulador no topo da pilha. # Aqui a pilha tem os dois argumentos x1 e x2: call soma # Invoca a função soma. insp 2 # Repõe a pilha (limpeza da casa). # Aqui o acumulador tem o valor devolvido. stod r # Guarda o acumulador na variável r. lodd r # Carrega variável r no acumulador. push # Coloca acumulador no topo da pilha. lodd x3 # Carrega variável x3 no acumulador. push # Coloca acumulador no topo da pilha. # Aqui a pilha tem os dois argumentos r e x3: call soma # Invoca a função soma. insp 2 # Repõe a pilha (limpeza da casa). # Aqui o acumulador tem o valor devolvido. stod r # Guarda o acumulador na variável r. haltsoma: lodl 2 addl 1 retn

Com inline:

jump main # Variáveis: x1 = 10 x2 = 20 x3 = 30 r = 0 # Aqui faz-se a soma:main: lodd x1 # Carrega variável x1 no acumulador. addd x2 # Adiciona variável x2 ao acumulador. stod r # Guarda o acumulador na variável r. lodd r # Carrega variável r no acumulador. addd x3 # Adiciona variável x3 ao acumulador. stod r # Guarda o acumulador na variável r. halt

Sempre mais rápido!

Sempre mais curto?

Não! Por vezes é mais longo. Depende da dimensão do código das rotinas, do número de invocações, etc.

Código demasiado longo pode tornar a execução mais lenta, pois obriga a recorrer à memória virtual.

Page 132: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação132

Sintaxe

Colocar a palavra chave inline antes do cabeçalho na definição da rotina:

inline tipo nome(parâmetros) … { … }

ou

inline tipo Classe::nome(parâmetros) … { … }

Page 133: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação133

Estrutura global do programa (I)

#include <iostream>#include <cassert>

using namespace std;

/** Devolve o máximo divisor comum dos inteiros passados como argumento. @pre m ≠ 0 ou n ≠ 0. @post mdc = mdc(m, n). */int mdc(int const m, int const n) {…}

class Racional {…};

inline Racional::Racional(int const n) {…}

inline Racional::Racional(int const n, int const d) {…}

inline int Racional::numerador() const {…}

inline int Racional::denominador() const {…}

inline Racional::escreve() const {…}

(continua)(continua)

Construtores

Inspectores

Page 134: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação134

Estrutura global do programa (II)

(continuação)(continuação)

void Racional::lê() {…}

inline Racional& Racional::operator++() {…}

inline Racional& Racional::operator--() {…}

inline Racional& Racional::operator*=(Racional const& r2) {…}

inline Racional& Racional::operator/=(Racional const& r2) {…}

inline Racional& Racional::operator+=(Racional const& r2) {…}

inline Racional& Racional::operator-=(Racional const& r2) {…}

inline void Racional::reduz() {…}

inline bool Racional::cumpreInvariante() const {…}

(continua)(continua)

Modificadores

Auxiliares

Page 135: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação135

Estrutura global do programa (III)

(continuação)(continuação)

/** Produto de dois racionais. @pre V. @post operator* = r1 × r2. */inline Racional const operator*(Racional r1, Racional const& r2) {…}

/** Divisão de dois racionais. @pre r2 ≠ 0. @post operator/ = r1 / r2. */inline Racional const operator/(Racional r1, Racional const& r2) {…} /** Soma de dois racionais. @pre V. @post operator+ = r1 + r2. */inline Racional const operator+(Racional r1, Racional const& r2) {…}

/** Subtracção de dois racionais. @pre V. @post operator- = r1 - r2. */inline Racional const operator-(Racional r1, Racional const& r2) {…}

(continua)(continua)

Operadores aritméticos

não-membro

Page 136: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação136

Estrutura global do programa (IV)

(continuação)(continuação)

/** Indica se dois racionais são iguais.

@pre V.

@post operator== = (r1 = r2). */inline bool operator==(Racional const& r1, Racional const& r2) {…} /** Indica se dois racionais são diferentes.

@pre V.

@post operator!= = (r1 ≠ r2). */inline bool operator!=(Racional const& r1, Racional const& r2) {…}

int main() {…}

Operadores de igualdade e

diferença

Page 137: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação137

Operadores em falta

Aritméticos: Unários: + e -

Relacionais: <, <=, > e >=

Incrementação: Sufixo: ++ e --

Inserção e extracção de canais: << e >>

Começamos aqui.

Fica por fazer...

Page 138: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação138

Incrementação prefixa

class Racional { public: …

/** Incrementa o racional. @pre *this = r. @post operator++ ≡ *this *this = r + 1. */ Racional& operator++();

};

Racional& Racional::operator++() { assert(cumpreInvariante());

numerador_ += denominador();

assert(cumpreInvariante());

return *this; }

Page 139: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação139

Incrementação sufixa

?

Page 140: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação140

Incrementação sufixa: a solução

/** Incrementa o racional, devolvendo o seu valor antes de incrementado. @pre r = r. @post operator++ = r r = r + 1. */inline Racional const operator++(Racional& r, int){ Racional const cópia = r; ++r;

return cópia;}

Devolve-se por valor um racional com o valor antes de incrementado, i.e., devolve-se a cópia do racional r.

Faz-se uma cópia de r antes de se incrementar, recorrendo à incrementação prefixa, já definida.

Aha! Cá está a diferença! Trata-se o operador como se fosse binário, recebendo como argumento um inteiro com valor não especificado e irrelevante.

Page 141: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação141

Decrementação sufixa: a solução

/** Decrementa o racional, devolvendo o seu valor antes de decrementado. @pre r = r. @post operator-- = r r = r - 1. */inline Racional const operator--(Racional& r, int){ Racional const cópia = r; --r;

return cópia;}

Page 142: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação142

Operador - unário: operação

/** … */class Racional { public: …

/** Devolve simétrico do racional. @pre V. @post operator- = -*this. */ Racional const operator-() const;

private: …};

Page 143: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação143

Operador - unário: método

inline Racional const Racional::operator-() const{ assert(cumpreInvariante());

Racional r;

r.numerador_ = -numerador(); r.denominador_ = denominador();

assert(r.cumpreInvariante());

return r;}

Não é fundamental usar uma rotina membro, mas permite código mais eficiente, pois pode-se mudar o sinal do numerador directamente, evitando-se invocações espúrias do redutor de fracções.

Page 144: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação144

Operador + unário

/** Devolve o racional. @pre V. @post operator+ ≡ r. */inline Racional const& operator+(Racional const& r){ return r;}

Page 145: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação145

Operador <

/** Devolve verdadeiro se o primeiro racional for menor que o segundo. @pre V. @post operator< = r1 < r2. */inline bool operator<(Racional const& r1, Racional const& r2){ return r1.numerador() * r2.denominador() <  r2.numerador() * r1.denominador();}

Como 0 < r1.d 0 < r2.d,

r1.n / r1.d < r2.n / r2.d r1.n x r2.d < r2.n * r1.d

Page 146: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação146

Operadores <=, > e >=

Podem-se definir à custa do operador <

Como?

Page 147: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação147

Operador >

/** Devolve verdadeiro se o primeiro racional for maior que o segundo. @pre V. @post operator> = r1 > r2. */inline bool operator>(Racional const& r1, Racional const& r2){ return r2 < r1;}

Page 148: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação148

Operador <=

/** Devolve verdadeiro se o primeiro racional for menor ou igual ao segundo. @pre V. @post operator<= = r1 <= r2. */inline bool operator<=(Racional const& r1, Racional const& r2){ return not (r1 > r2);}

Page 149: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação149

Operador >=

/** Devolve verdadeiro se o primeiro racional for menor ou igual ao segundo. @pre V. @post operator>= = r1 >= r2. */inline bool operator>=(Racional const& r1, Racional const& r2){ return not (r1 < r2);}

Page 150: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação150

Outro desafio (fácil)

Definir o operador == à custa do operador <

Page 151: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação151

Último problema

Operador /= usa o operador !=, definido mais tarde

Melhor solução: concentrar declarações de rotinas não-membro

após definição da classe Definir rotinas não-membro mais tarde

Page 152: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação152

Preâmbulo e definição da classe C++

#include <iostream>#include <cassert>

using namespace std;

/** Devolve o máximo divisor comum dos inteiros passados como argumento.

@pre m ≠ 0 ou n ≠ 0.

@post mdc = mdc(m, n). */int mdc(int const m, int const n) {…}

class Racional {…};

Page 153: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação153

Declaração de rotinas não-membro (I)

/** Incrementa o racional, devolvendo o seu valor antes de incrementado.

@pre r = r.

@post operator++ = r r = r + 1. */Racional const operator++(Racional& r, int);

/** Decrementa o racional, devolvendo o seu valor antes de decrementado.

@pre r = r.

@post operator-- = r r = r - 1. */Racional const operator--(Racional& r, int);

Incrementação e decrementação

sufixas

Page 154: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação154

Declaração de rotinas não-membro (II)

/** Produto de dois racionais. @pre V. @post operator* = r1 × r2. */Racional const operator*(Racional r1, Racional const& r2);

/** Divisão de dois racionais. @pre r2 ≠ 0. @post operator/ = r1 / r2. */Racional const operator/(Racional r1, Racional const& r2); /** Soma de dois racionais. @pre V. @post operator+ = r1 + r2. */Racional const operator+(Racional r1, Racional const& r2);

/** Subtracção de dois racionais. @pre V. @post operator- = r1 - r2. */Racional const operator-(Racional r1, Racional const& r2);

Operadores aritméticos

binários

Page 155: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação155

Declaração de rotinas não-membro (III)

/** Devolve o racional.

@pre V.

@post operator+ ≡ r. */Racional const& operator+(Racional const& r);

/** Indica se dois racionais são iguais.

@pre V.

@post operator== = (r1 = r2). */bool operator==(Racional const& r1, Racional const& r2); /** Indica se dois racionais são diferentes.

@pre V.

@post operator!= = (r1 ≠ r2). */bool operator!=(Racional const& r1, Racional const& r2);

Operadores de igualdade e

diferença

Operador identidade

Page 156: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação156

Declaração de rotinas não-membro (IV)/** Devolve verdadeiro se o primeiro racional for menor que o segundo. @pre V. @post operator< = r1 < r2. */bool operator<(Racional const& r1, Racional const& r2);

/** Devolve verdadeiro se o primeiro racional for maior que o segundo. @pre V. @post operator> = r1 > r2. */bool operator>(Racional const& r1, Racional const& r2);

/** Devolve verdadeiro se o primeiro racional for menor ou igual ao segundo. @pre V. @post operator<= = r1 <= r2. */bool operator<=(Racional const& r1, Racional const& r2);

/** Devolve verdadeiro se o primeiro racional for maior ou igual ao segundo. @pre V. @post operator>= = r1 >= r2. */bool operator>=(Racional const& r1, Racional const& r2);

Operadores relacionais

Page 157: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação157

Definição de métodos (I)

inline Racional::Racional(int const n) {…}

inline Racional::Racional(int const n, int const d) {…}

inline int Racional::numerador() const {…}

inline int Racional::denominador() const {…}

inline void Racional::escreve() const {…}

inline Racional const Racional::operator-() const {…}

void Racional::lê() {…}

inline Racional& Racional::operator++() {…}

inline Racional& Racional::operator--() {…}

inline Racional& Racional::operator*=(Racional const& r2) {…}

inline Racional& Racional::operator/=(Racional const& r2) {…}

inline Racional& Racional::operator+=(Racional const& r2) {…}

inline Racional& Racional::operator-=(Racional const& r2) {…}

inline void Racional::reduz() {…}

inline bool Racional::cumpreInvariante() const {…}

(continua)(continua)

Construtores

Inspectores

Modificadores

Auxiliares

Page 158: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação158

Definição de rotinas não-membro

inline Racional const operator++(Racional& r, int) {…}

inline Racional const operator--(Racional& r, int) {…}

inline Racional const operator*(Racional r1, Racional const& r2) {…}

inline Racional const operator/(Racional r1, Racional const& r2) {…} inline Racional const operator+(Racional r1, Racional const& r2) {…}

inline Racional const operator-(Racional r1, Racional const& r2) {…}

inline Racional const& operator+(Racional const& r) {…}

inline bool operator==(Racional const& r1, Racional const& r2) {…} inline bool operator!=(Racional const& r1, Racional const& r2) {…}

inline bool operator<(Racional const& r1, Racional const& r2) {…}

inline bool operator>(Racional const& r1, Racional const& r2) {…}

inline bool operator<=(Racional const& r1, Racional const& r2) {…}

inline bool operator>=(Racional const& r1, Racional const& r2) {…}

int main() {…}

Operadores aritméticos

binários

Incrementação e decrementação

sufixas

Operadores de igualdade e

diferença

Operador identidade

Operadores relacionais

Page 159: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação159

TAD Racional (construtores)

/** Representa números racionais.

@invariant 0 < denominador_ mdc(numerador_, denominador_) = 1. */class Racional { public: /** Constrói racional com valor inteiro.

@pre V.

@post *this = valor. */ Racional(int const valor = 0);

/** Constrói racional correspondente a numerador/denominador.

@pre denominador ≠ 0.

@post *this = numerador/denominador. */ Racional(int const numerador, int const denominador);

(continua)(continua)

Page 160: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação160

TAD Racional (inspectores)

(continuação)(continuação)

/** Devolve numerador da fracção mínima correspondente ao racional.

@pre V.

@post numerador/denominador() = *this. */ int numerador() const;

/** Devolve denominador da fracção mínima correspondente ao racional.

@pre V.

@post 0 < denominador (E n : V : n/denominador = *this mdc(n, denominador) = 1). */ int denominador() const;

(continua)(continua)

Page 161: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação161

TAD Racional (inspectores)

(continuação)(continuação)

/** Escreve um racional no ecrã no formato de uma fracção. @pre V. @post cout.fail() ou cout contém n/d (ou simplesmente n, se d = 1) em que n e d são os valores de numerador e denominador. */ void escreve() const;

/** Devolve simétrico do racional. @pre V. @post operator- = -*this. */ Racional const operator-() const;

(continua)(continua)

Page 162: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação162

TAD Racional (modificadores)

(continuação)(continuação) /** Lê do teclado um racional, na forma de dois inteiros sucessivos. @pre *this = r. @post Se cin.good() cin tem dois inteiros n e d disponíveis para leitura, com d <> 0, então *this = n/d cin.fail(), senão *this = r cin.fail(). */ void lê();

/** Incrementa o racional. @pre *this = r. @post operator++ ≡ *this *this = r + 1. */ Racional& operator++();

/** Decrementa o racional. @pre *this = r. @post operator-- ≡ *this *this = r - 1. */ Racional& operator--(); (continua)(continua)

Page 163: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação163

TAD Racional (modificadores)

(continuação)(continuação) /** Multiplica por um racional.     @pre *this = r.     @post operator*= ≡ *this *this = r × r2. */ Racional& operator*=(Racional const& r2);

/** Divide por um racional.     @pre *this = r r2 ≠ 0.     @post operator/= ≡ *this *this = r / r2. */ Racional& operator/=(Racional const& r2);

/** Adiciona de um racional.     @pre *this = r.     @post operator+= ≡ *this *this = r + r2. */ Racional& operator+=(Racional const& r2);

/** Subtrai de um racional.     @pre *this = r.     @post operator-= ≡ *this *this = r - r2. */ Racional& operator-=(Racional const& r2);(continua)(continua)

Page 164: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação164

TAD Racional (implementação)

(continuação)(continuação) private: /** Indica se a CIC se verifica.      @pre V.      @post  cumpreInvariante = 0 < denominador_ mdc(numerador_, denominador_) = 1. */ bool cumpreInvariante() const;

/** Reduz a fracção que representa o racional. @pre denominador_ ≠ 0 *this = r. @post denominador_ ≠ 0 mdc(numerador_, denominador_) = 1 *this = r. */ void reduz();

    int numerador_;    int denominador_; };

Page 165: Aula 13 Tipos Abstractos de Dados IV. 2003/2004 Introdução à Programação 2 Estrutura global do programa (I) Construtores Inspectores.

2003/2004Introdução à Programação165

Aula 13: Sumário

Definindo constantes de uma classe: Necessidade de declarar operações como constantes (que não alteram a instância

implícita). Sintaxe. Devolução por valor constante. Vantagens da utilização de const.

Evitando o mecanismo de invocação de rotinas no código máquina produzido pelo compilador:

Rotinas inline. Sintaxe. Regras de utilização. Explicação do efeito de inline sobre o código máquina produzido. Exemplo com programa em C++ e respectiva tradução para MAC-1 (ver

Arquitectura de Computadores). Quando optimizar.

Incrementação e decrementação sufixa: sobrecarga. Ordem de declaração/definição de operações/métodos e rotinas não-membro

associados a um TAD.