ponteiros em pascal variáveis ponteiros são aquelas que guardam o endereço de outra,...

Post on 18-Apr-2015

107 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Ponteiros em Pascal Variáveis ponteiros são aquelas que guardam o endereço de outra, possibilitando o acesso a seu conteúdo.

Declaração em Pascal:

 var

ptInt: ^integer; {ponteiro para uma variável

inteira }

ptReal: ^real; {ponteiro para uma variável

real}

Operador @  Operador unário que obtém o endereço de uma variável

program soma;var S,A,B:integer; PtS,PtA,PtB : ^integer;begin readln(A,B); PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; writeln('Resultado: ',PtS^);end.

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A B

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S 5

PtB

PtS

program soma;var S,A,B: integer; PtS,PtA,PtB: ^integer;begin A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^);end.

Alocação de memória

A 2 B 3

PtA

S 5

PtB

PtS

5

procedure New( )

Cria dinamicamente (em tempo de execução) uma nova variável e faz uma variável ponteiro apontar para ela.type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

Alocação de memória

P

type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

Alocação de memória

P

type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

Alocação de memória

P

Bom Dia!

type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

Alocação de memória

P

Bom Dia!

Bom Dia!

type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.

Alocação de memória

P

OBS: a procedure Dispose libera uma variável criada dinamicamente. Se isso não for feito, a região de memória

disponibilizada não poderá ser usada até que o computador seja reiniciado.

Outras situações comuns

Um ponteiro recebendo o endereço de um outro:

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^); { ou q^ ou, ainda, r^ } dispose(q^); { ou p^ ou, ainda, r^ } :

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

5

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

5

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

5

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

5

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

5

5

var p,q,r: ^integer;begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q^);{ou p^ ou r^ } :

Alocação de memória

p

q

r

ATENÇÃO: observe que a partir de q:=p;, perdeu-se o acesso à variável criada com new(q);

Portanto, o manuseio de ponteiros exige cuidado!

Listas encadeadas

Em várias situações em programação temos que lidar com listas de elementos cujo tamanho exato é desconhecido. Soluções:

• Empregar um agregado homogêneo (array) superdimensionado.

1 2 3...

N-1 N

• Empregar seqüências de células (nós) que contêm dois elementos: um valor e um ponteiro para o próximo nó.

...

p

/

Quando adotar uma ou outra solução?

• Agregado homogêneo: quando pudermos determinar com segurança o tamanho máximo.

• Listas encadeada:

- quando for difícil estimar o tamanho máximo com segurança; e/ou...

- quando se desejar maior agilidade nas inclusões ou exclusões de novos elementos.

Lista: uma estrutura recursiva:

Ex: definição de uma lista de inteiros:

• Lista vazia;

• Um inteiro seguido de uma lista de inteiros.

p

/4 7 1 9

/ p

Lista vazia Lista com quatro elementos(o último quarda o ponteiro nil)

OBS: o ponteiro contido noprimeiro nó aponta para a lista formada

pelos demais nós

Lista: uma estrutura recursiva:

Ex: definição de uma lista de inteiros:

• Lista vazia;

• Um inteiro seguido de uma lista de inteiros.

p

/4 7 1 9

/ p

Lista vazia Lista com quatro elementos(o último quarda o ponteiro nil)

OBS: para se ter acesso aos elementos da lista é necessário que haja sempre uma variável ponteiro

apontando para a “cabeça” da lista (primeiroelemento)

Lista: uma estrutura recursiva:

Ex: definição de uma lista de inteiros:

• Lista vazia;

• Um inteiro seguido de uma lista de inteiros.

p

/4 7 1 9

/ p

Lista vazia Lista com quatro elementos(o último quarda o ponteiro nil)

A partir de cada nó, pode-se ter acesso ao seguinte.Assim, pode-se percorrer a lista toda.

Lista: uma estrutura recursiva:

Ex: definição de uma lista de inteiros:

• Lista vazia;

• Um inteiro seguido de uma lista de inteiros.

p

/4 7 1 9

/ p

Lista vazia Lista com quatro elementos(o último quarda o ponteiro nil)

Quando a lista estiver vazia o ponteiro que deveria apontar o primeiro elemento, guarda o valor nil ( / ).

Definição (recursiva) de um nó:

type

tDado = integer; { ou real, char, etc.}

tPtNo = ^tNo;

tNo = record

Dado:tDado;

Prox :tPtNo;

end;

var

p,q: tPtNo;

OBS: no início da execução do programa só há ponteiros(p,q) para nós. Estes poderão, dinamicamente, ser

empregados para se construir uma lista.

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Exemplo de uso: criação de uma lista com dois elementos:

p^.Dadoacesso ao

objeto apontado por p

acesso ao campo

específico

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Exemplo de uso: criação de uma lista com dois elementos:

p^.Proxacesso ao

objeto apontado por p

acesso ao campo

específico

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

7

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

7

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

7 3

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

7 3

var

p,q: tPtNo;

begin

new(p);

p^.Dado := 7;

new(q);

q^.Dado := 3;

p^.Prox := q;

q^.Prox := nil;

:

Alocação de memória

p

q

7 3 /

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Exemplo 2: dada a lista abaixo, inserir um novo nó entre os dois existentes e armazenar nele o valor 2.

p

7 3 /

q

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

2

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

2

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

2

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

/

2

:

new(q);

q^.Dado := 2;

q^.Prox := p^.Prox;

p^.Prox := q;

q := nil;

:

Alocação de memória

p

7 3 /

q

/

2

Manuseio de listas encadeadas

Para tratar de forma genérica todas as possíveis manipulações de uma lista encadeada, é definido um conjunto de rotinas. Exemplos:

• inserir/excluir um elemento no início

• inserir /excluir um elemento no final

• inserir /excluir um elemento na enésima posição

• calcular a soma dos elementos

Exemplo: inserir elemento V no final

Duas situações a se considerar:

Lista vazia Lista com 1 ou mais elementos

p

/

/ p

...

Para lista vazia: / p

:

new(p);

p^.Dado:=V;

p^.Prox:=nil;

: new(p);

p^.Dado:=V;

p^.Prox:=nil;

Alocação de memória

p

V

5

: new(p);

p^.Dado:=V;

p^.Prox:=nil;

Alocação de memória

p

V

5

: new(p);

p^.Dado:=V;

p^.Prox:=nil;

Alocação de memória

p

V

5

5

: new(p);

p^.Dado:=V;

p^.Prox:=nil;

Alocação de memória

p

V

5

5 /

Para lista não vazia:

:

{ fazer q apontar para o último elemento }

q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

{ inserir o novo elemento }

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

p

4 7 1 /

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

5

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3 /

q

2

r

V

5

5 /

: q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

new(r);

r^.Dado:=V;

r^.Prox:=nil;

q^.Prox:=r;

Alocação de memória

p

7 3

q

2

r

V

5

5 /

Juntando as duas situações...

procedure InsereNo(var p: tPtNo; V : tDado);

var q,r: tPtNo;

begin

new(r);

r^.Dado:=V;

r^.Prox:=nil;

if p = nil then

p:= r

else begin

q:= p;

while q^.Prox <> nil do

q:=q^.Prox;

q^.Prox:=r;

end;

end;

Como existe a possibilidade de p mudar seu conteúdo, ele é passado por referência.

top related