ponteiros - dc.ufscar.br€¦ · ponteiros! usado para criar e manipular estrutura de dados que...

25
Programação de Computadores 185 Ponteiros ! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos Básicos: ! ponteiro=> variável que armazena um endereço de memória. ! variável=> contem um valor ! ponteiro=> contem o endereço de uma variável que por sua vez armazena um valor ! variável=> diretamente referencia um valor ! ponteiro=> indiretamente referencia um valor

Upload: others

Post on 21-Sep-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 185

Ponteiros! Usado para criar e manipular estrutura de dados que

podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc.

! Conceitos Básicos:! ponteiro=> variável que armazena um endereço de

memória.! variável=> contem um valor! ponteiro=> contem o endereço de uma variável que por

sua vez armazena um valor! variável=> diretamente referencia um valor! ponteiro=> indiretamente referencia um valor

Page 2: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 186

! Como as variáveis, os ponteiros devem ser declarados antes do seu uso:int *ptcont, cont; nessa declaração temos:

" ptcont-> ponteiro para uma posição de memória que armazena um inteiro. Em outras palavras, o conteúdo da posição de memória chamada ptcont, é o endereço de uma posição de memória que armazena um inteiro.

" cont -> posição de memória que armazena um inteiroint *pty, *ptx;

" duas posições de memória que armazenam um endereço de memória onde será armazenado um inteiro.

Page 3: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 187

! ponteiros podem ser iniciados quando declarados ou por uma comando de atribuição. Valores possíveis:0, NULL ou um endereço. (NULL é uma constante simbólica definida em iostream.h)

NULL e 0 são equivalentes-> 0 é mais usado.! Operadores:

! & -> operador unário de endereço. Quando aplicado retorna o endereço do operando.Exemplo:int y = 5;int *pty;pty = &y;

atribui a pty o endereço da variável y ...

pty

5y

...

Page 4: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 188

// usando os operadores & e *#include <iostream.h>void main( ){ int a;

int *ponta; // ponta é um ponteiro para uma posição de memória // que armazena um inteiro

a = 7;ponta = &a;cout<<“Endereço de memória onde está armazenada a variável a:”

<<&a<<endl<<“Valor de ponta é:"<<ponta<<endl<<endl<<"O valor da variável a é:"<<a<<endl<<"O valor de *ponta é:"<<*ponta<<endl<<endl<<“* e & são complementares um do outro"<<endl <<"&*ponta="<<&*ponta<<endl<<"*&ponta=“<<*&ponta<<endl;

}

Page 5: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 189

Endereço de memória onde está armazenado a variável a:0x603f293aValor de ponta é:0x603f293a

O valor da variável a é:7O valor de *ponta é:7

* e & são complementares um do outro&*ponta =0x603f293a*&ponta =0x603f293a

Page 6: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 190

! Arranjo de Ponteiros! int a[10]; declara um arranjo de 10 posições! se não conhecemos antecipadamente o tamanho do problema,

podemos deixar que o usuário indique o tamanho desejado na hora da execução.

#include <iostream.h>#include <assert.h>void main( ){ int *arranjo, tamanho;cout<<"entre com o tamanho do arranjo:"; cin>>tamanho;arranjo = new int[tamanho];assert(arranjo!=0);cout<<endl<<"entre agora com os elementos do arranjo:";for (int i=0; i<tamanho;i++) cin>>arranjo[i];cout<<endl<<"Arranjo montado:"<<endl;for (int i=0;i<tamanho;i++) cout<<" "<<arranjo[i];

}

Page 7: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 191

#include <assert.h>void assert(int test);Descrição: Testa uma condição e aborta a execução se o teste falhar. É uma macro. Quando falha, além de abortar o programa emite uma mensagem indicando o teste que falhou, o nome do arquivo onde foi feito o teste e o número da linha dentro do arquivo

Page 8: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 192

! Podemos fazer a mesma alocação para matrizes.float **matriz;int nro_linhas, nro_colunas;cout<<"Entre com o nro de linhas da matriz:";cin>>nro_linhas;matriz= new float* [nro_linhas];assert(matriz!=0);cout<<"Entre agora com o nro de colunas da matriz:";cin>>nro_colunas;for (int i=0;i<nro_linhas;i++){ matriz[i]= new float[nro_colunas];

assert(matriz[i]!=0);}

Page 9: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 193

! matriz= new float* [nro_linhas];! se nro_linhas =3

for (int i=0; i<nro_linhas;i++)matriz[i]=new float [nro_colunas]; //se nro_colunas=3

matriz 012

matriz

0

1

2

0 1 2

Page 10: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 194

! Matriz Triangular15712

02915

0 00 03 0

21 4

0

321

01

23

≠0 só os elementos que tem i ≤ jfloat **matriang;int ordem;cin>>ordem;matriang = new float*[ordem]; assert(matriang!=0);for (int i=0; i<ordem;i++){ matriang[i] = new float [i+1];

assert(matriang[i]!=0);}

Page 11: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 195

! Fazer a alocação para matriz triangular superior.! char *cad[4]={“ouro”, “copas”, “paus”, “espada”};

O

C O

UAP

cad[0]0 1 2 3

cad[3]cad[2]cad[1]

U R O \0

4

AP S \0

S \0

\0ADAPSE

5 6

TAMANHOS DIFERENTES PARA AS COLUNAS

Page 12: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 196

! Simulando embaralhar e distribuir cartas=> baralho tem 52 cartas, 13 cartas de cada naipe. Podemos imaginar o baralho como sendo um arranjo de 4 linhas correspondendo aos naipes e 13 colunas correspondendo a numeração das cartas.

copas0 1 2 3

espadapausouro

4 12111098765

AS 2 3 4 5 6 7 8 9 10 rei

dama

valete

0

1

2

3

cartas

cartas[2][12] representa o Rei de paus

Page 13: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 197

! A simulação do embaralhamento das cartas pode ser feita usando o seguinte método. ! O arranjo cartas é iniciado com 0. ! Aleatoriamente é escolhida uma linha(0-3) e uma coluna(0-12)! O número 1 é inserido na posição cartas[linha][coluna] para

indicar que na distribuição essa será a primeira carta. ! O mesmo processo é feito com os números 2,3,4,…, 52. Se uma

posição selecionada já tiver aparecido em outra rodada, ela é ignorada e outra linha e coluna é selecionada.

! Quando todo o arranjo tiver sido preenchido, as cartas serão distribuídas.

PS: Um programa escrito usando esse algoritmo pode rodar indefinidamente. Pq?

Page 14: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 198

! Depois de embaralhado, quando formos proceder a distribuição temos que ter uma forma de “traduzir” cartas[linha] [coluna] para o texto equivalente ao significado da carta. Por exemplo, se cartas[2][12]=1 temos que distribuir a carta Rei de Ouro.

! Uma maneira simples é criar um arranjo de ponteiros para caracteres naipe[4], colocando na posição naipe[0]= ‘copas’, naipe[1]=‘ouro’, naipe[2]=‘paus’ e naipe[3]=‘espada’. Uma vez determinada a linha, basta ir no arranjo naipe na linha selecionada e imprimir o conteúdo.

! O mesmo pode ser feito com o valor das cartas. Criamos um arranjo de ponteiros para caracteres valor[13], sendo que valor[0]=‘As’, valor[1]=‘dois’,…, valor[10]=‘Valete’, valor[11]=‘Dama’ e valor[12]=‘Rei’.

Page 15: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 199

! Vamos usar a metodologia de desenvolvimento chamada de refinamentos sucessivos.

! Embaralhe e distribua as 52 cartas! inicie o arranjo cartas! inicie o arranjo valor! inicie o arranjo naipe! embaralhe as cartas! distribua as cartas

! Embaralhe as cartas pode ser expandida para:! para cada uma das 52 cartas

faça { linha#número aleatório entre 0 e 4 ;coluna#número aleatório entre 0 e 12;enquanto cartas[linha][coluna] ≠0faça { linha#número aleatório entre 0 e 4 ;

coluna#número aleatório entre 0 e 12;}

carta[linha][coluna]# número da carta}

Page 16: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 200

! Distribua as cartaspara cada uma das 52 cartasfaça { procura pela posição cartas[linha][coluna]=valor

da carta;imprime valor[coluna] seguido da cadeia “de”

seguido de naipe[linha];}

Page 17: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 201

#include <iostream.h>#include <iomanip.h>#include <stdlib.h>#include <time.h>void embaralha(int[][13]);void distribui(int[][13], char*[ ], char*[ ]) ;void main( ){ char *naipe[]={"copas","ouro","paus","espada"};

char *valor[ ]={"As","dois","tres","quatro","cinco","seis","sete","oito","nove","dez","valete","dama","rei"};

int cartas[4][13]={0};srand(time(NULL));embaralha(cartas);distribui(cartas,valor,naipe);

}

Page 18: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 202

void embaralha(int baralho[ ][13]){ int linha,coluna;

for (int carta=1;carta<=52;carta++){ linha = rand()% 4; coluna = rand( ) % 13;while (baralho[linha][coluna]!=0){ linha = rand( ) % 4; coluna = rand( ) % 13;}

baralho[linha][coluna] = carta ;}

}void distribui(int baralho[ ][13], char* face[ ], char *naipe[ ]){ for (int carta = 1; carta<=52; carta++)

for (int linha=0; linha<=3; linha++)for (int coluna=0; coluna<=12; coluna++)if (baralho[linha][coluna] == carta)cout<<setw(5)<<setiosflags(ios::right)<<face[coluna]

<<" de "<<setw(8)<<setiosflags(ios::left)<<naipe[linha]<< (carta%3==0?'\n':'\t');

}

Page 19: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 203

! Ponteiro para funções=> contem o endereço da função na memória.

! Vimos que o nome de um arranjo é também o endereço na memória do primeiro elemento do arranjo

! Nome de uma função => é o endereço onde inicia o código que realiza as tarefas da função.

! Ponteiro para função:! podem ser passados para outras funções! pode ser retornado de uma função! armazenado em arranjos! atribuído a outros ponteiros para funções.

Page 20: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 204

#include <iostream.h>#include <iomanip.h>void ordena(int [ ], const int, int(*)(int,int));int ascendente(const int,const int);int descendente(const int, const int);void main( ){ const int tamanho=10;

int ordem,cont, a[tamanho]={2,6,4,8,10,12,89,68,45,37};cout<<"Entre com o valor 1 se a ordenação for crescente"<<endl

<<"Entre com o valor 2 para ordenação decrescente"<<endl;cin>>ordem;cout<<endl<<"Dados na ordem original"<<endl;for (cont=0;cont<tamanho;cont++) cout<<setw(4)<<a[cont];if (ordem==1){ ordena(a, tamanho,ascendente);cout<<endl<<"Elementos em ordem crescente"<<endl;

}else{ ordena(a, tamanho, descendente);cout<<endl<<"elementos em ordem decrescente"<<endl;

}for (cont=0;cont<tamanho;cont++) cout<<setw(4)<<a[cont];cout<<endl;

}

Page 21: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 205

void ordena(int a[ ], const int tam, int(*compare)(int,int)){ int aux; ;

int posicao;for (int i=0; i<tam-1; i++){ aux = a[i]; posicao = i;for (int j=i+1; j<tam;j++)if ((*compare)(aux,a[j])){ aux= a[j]; posicao =j;}

if (posicao!= i){ a[posicao] = a[i]; a[i] = aux;}

}}

int ascendente(const int a, const int b){ return b<a;}

int descendente(const int a, const int b){ return b>a;}

Page 22: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 206

! Funções: ordena, ascendente e descendente! ordena=> recebe um ponteiro para uma função que pode

ser ascendente ou descendente, junto com o arranjo e seu tamanho.

! Programa pergunta ao usuário o tipo de ordenação desejado. Se for ascendente (tipo 1) o ponteiro para a função ascendente é passado para a função ordena.

! int(*) (int,int) => diz para a função ordena esperar 1 parâmetro que é 1 ponteiro para uma função que tem como parâmetro dois inteiros.

! No programa o código (if (*compare)(aux,a[j])) é equivalente a if (compare(aux,a[j]). PQ?

! Nome da função é um ponteiro para a mesma

Page 23: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 207

! Maior uso de ponteiros para função: Sistemas orientados a menu.

! Usuário seleciona um opção a partir de um menu. Cada opção é executada por uma função diferente.

! Os ponteiros para cada função são armazenados num arranjo de ponteiros para função. A escolha do usuário é usada como índice para o arranjo e o ponteiro armazenado na posição usado para chamar a função correspondente.

Page 24: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 208

#include <iostream.h>void funcao1(int);void funcao2(int);void funcao3(int);void main( ){ void (*f[3])(int)={funcao1,funcao2,funcao3};

int escolha;cout<<"Entre com o valor entre 1 e 3, 0 para terminar:";cin>>escolha;while (escolha>=1 && escolha<=3){ f[escolha-1](escolha); // seleciona o ponteiro na posição

//escolhida do arranjocout<<"Entre com um valor entre 1 e 3, 0 para terminar:";cin>>escolha;

}cout<<"Você entrou com o valor 0, portanto encerrando o

programa"<<endl;}

f é um arranjo de 3 posição sendo que cada uma delas é um ponteiro para uma função que recebe como argumento um inteiro e retorna void. O arranjo é iniciado com o nome da função correspondente

Page 25: Ponteiros - dc.ufscar.br€¦ · Ponteiros! Usado para criar e manipular estrutura de dados que podem aumentar/diminuir de tamanho como listas encadeadas, árvores, etc. ! Conceitos

Programação de Computadores 209

void funcao1(int a){ cout<<"Você entrou com o valor "<<a<<" então a

função 1 foi chamada"<<endl<<endl;}

void funcao2(int a){ cout<<"Você entrou com o valor "<<a<<" então a

função 2 foi chamada"<<endl<<endl;}

void funcao3(int a){ cout<<"Você entrou com o valor "<<a<<" então a

função 3 foi chamada"<<endl<<endl;}