17
Aula prática 8 Ponteiros Monitoria de Introdução à Programação

Aula prática 8 Ponteiros Monitoria de Introdução à Programação

Embed Size (px)

DESCRIPTION

Aula prática 8 Ponteiros Monitoria de Introdução à Programação. Roteiro. Ponteiros Definição. Operadores. Ponteiros e Variáveis. Ponteiros e Vetores. Ponteiros e Funções. Duvidas Exercícios. Ponteiros - Definição. - PowerPoint PPT Presentation

Citation preview

Page 1: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Aula prática 8

Ponteiros

Monitoria de Introdução à Programação

Page 2: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Roteiro

Ponteirosl Definição.l Operadores.l Ponteiros e Variáveis.l Ponteiros e Vetores.l Ponteiros e Funções.

DuvidasExercícios

Page 3: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Definição

Ponteiros são tipos de dados que referenciam (ou “apontam” para) endereços de memória.

Em algumas linguagens com maior abstração, ponteiros não existem

expostos ao programador (como em Java) ou tem alternativas mais seguras em outros tipos de dados (como o tipo “referência” em C++).

Acessar o valor nesse endereço é chamado de “dereferenciar” o ponteiro.

Em C, um ponteiro é um numero inteiro, referindo-se ao endereço na

memória.

Page 4: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Declaração

A sintaxe para declarar um ponteiro, é, em C:

tipo *nome; ou tipo* nome;

Para declarar ponteiros em uma mesma linha deve-se usar o * para

cada ponteiro: tipo *pont1, *pont2, var, *pont3; Como qualquer outro tipo, podemos ter vetores de ponteiros:

tipo *vetorDePonteiros[tamanho];

E, como um ponteiro é um tipo, podemos ter ponteiros para ponteiros

(ad infinitum):

tipo **ponteiroDePonteiroDeTipo;tipo ***ponteiroDePonteiroDePonteiroDeTipo;

Page 5: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Operadores - &

Para a atribuição de valores para ponteiros, usamos o operador “=“,

como fizemos com qualquer outro tipo, MAS: Em geral não se atribuem valores arbitrários aos ponteiros pois

raramente usa-se endereços que são constantes* para todas as execuções do programa. Em vez disso utiliza-se o operador & para se obter o endereço de variáveis.

Exemplo: int var; int* ponteiro;

ponteiro = &var; //ponteiro recebe o endereço de var

*: Exceção para o endereço NULL, que equivale ao endereço 0, normalmente retornadopor funções em caso de erro, ou para indicar que o ponteiro não aponta para lugar

nenhum.

Page 6: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Operadores - * Mas somente obter o endereço não é o bastante. É preciso

também poder acessar o conteúdo de endereços. Para isso é utilizado o operador * (dereferenciador):

int var = 5; int* pont = &var; //Guarda o endereço de var printf(“%d”, *pont); /* Imprime o conteúdo do endereço

guardado por pont, isto é, 5 */

Podemos também usar a notação de vetores para acessar o conteúdo de um ponteiro (pois vetores são como ponteiros):

int vetorInt[6]; int* pvetor = vetorInt; //Recebe o endereço inicial do vetor int inteiro = pvetor[5];

O que é equivalente a: inteiro = *(pvetor + 5);

Page 7: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Cuidados

Porém, ao acessar o conteúdo de um ponteiro, devemos ter cuidado:

um ponteiro com um endereço de memória inválido ou nulo, ao ser dereferenciado, irá causar um erro de “Falha de segmentação” (segmentation fault), finalizando forçadamente a execução de seu programa.

Coisas desse tipo devem ser evitadas:

double* pont; //Ponteiro não inicializado (possui lixo de memória)*pont = 2.5; //Altera conteúdo de endereço qualquer

long* pLong; int inteiro = *pLong; //Recebe conteúdo de endereço qualquer

char* string = NULL; puts(string); //Tenta alterar conteúdo do endereço NULL

Page 8: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Aritmética

Podemos usar as operações de adição e subtração com ponteiros. Isso permite coisas desse tipo:

pInt = (pVetor + 5); pVetor++; pVetor--; pChar -= 3;

Multiplicação e divisão não são suportadas, nem soma de dois ponteiros,

pois isso não faz sentido se tratando de memória.

As operações de adição, subtração, incremento e decremento se dão em

função do tamanho do tipo para o qual o ponteiro aponta. Se tivermos um ponteiro para inteiro e incrementarmos esse ponteiro por um, ele apontará para o endereço de memória 4 bytes adiante.

Page 9: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros e Variáveis – Acesso Indireto

Podemos, usando os operadores apresentados, fazer um ponteiro apontar

para um endereço de uma variável e com isso alterar, se quisermos, o valor dessa variável indiretamente.

float var = 2.0;float* pfloat = &var; //pfloat aponta para var *pfloat = 12.0; //Equivale a 'var = 12.0;'

Page 10: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Vetores

Então podemos pensar, corretamente, que ao declarar uma variável da forma

float *pFloat;

Estamos declarando que o conteúdo ao qual pFloat aponta é do tipo float,

tornando pFloat um ponteiro para float.

Por isso, a seguinte declaração também é válida: char (*pString)[50];

Declarando que o conteúdo ao qual pString aponta é do tipo vetor de char

de 50 posições, tornando pString um ponteiro para vetor de char de 50 posições.

Como estamos declarando um ponteiro, e não a variável em si, memória

não é reservada para essa variável, que inicialmente aponta para um endereço qualquer na memória.

Page 11: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Vetores

Como já foi dito, ponteiros guardam endereços. Vetores também. Portanto podemos acessar os valores do vetor usando ponteiros.

char string[20];char* pchar = string;

Para acessar cada elemento:

for(i = 0; i < 20; i++) { //Notação de vetor aux = pchar[i]; //Notação de ponteiro *(pchar + i) = funcao(); }

Page 12: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Matrizes

Porém, para acessar matrizes através de ponteiros, temos que ter cuidado:

Uma matriz é um espaço contínuo na memória, sendo acessado diferenciando somente um endereço:

int matriz[20][10]; matriz[i][j]; //isso

*(matriz + i*10 + j); //Equivale a isso

Pode-se também olhar a matriz como um vetor de vetores e portanto

acessá-la usando ponteiro de ponteiro:

matriz[i][j]; //Isso*( *(matriz + i) + j); //Equivale a isso

Page 13: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Passagem por referência Ponteiros, por serem endereços, permitem que acessemos e modifiquemos dados externos à função, de dentro da função, contornando a passagem de variáveis por cópia*:

void funcao(int* pont) { *pont = 5; /* A função irá modificar o conteúdo do endereço passado como parâmetro */ }

int main() { int var = 4; funcao(&var); //Passo o endereço de 'var' como parâmetro printf(“%d”, var); //E portanto o valor impresso será 5

return 0; } *: A passagem ainda é por cópia, mas o valor copiado é o endereço.

Page 14: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Ponteiros - Passagem por referência

Podemos, dessa forma, “retornar” mais de um valor por execução de função.

Isso é muito útil quando é preferível retornar o estado da execução da

função, como um código de erro ou de execução correta:

Page 15: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Dúvidas?

Page 16: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Exercício 1

Interferência!Um matemático estava avaliando um fenômeno e percebeu um comportamento estranho no seu sinal. Ele tentava produzir um sistema crescente, mas percebeu que ocorriam oscilações bruscas de sinal. Ele percebeu que a função do tempo que rege o sinal é:

se t é divisível por 3 , se t é divisível por 2 e não por 3 , se t não for divisível por 2 nem por 3.

Faça um programa que receba do usuário um inteiro ‘t’ e que useuma função void que receba um ponteiro desse inteiro, para que este seja modificado e no final seja printado o resultado de f(t).

Exs.: f(6) = 2; f(7) = 3; f(8) = 77844992; f(9) = 3, f(10) = 711312970

 

Page 17: Aula  prática  8 Ponteiros Monitoria  de  Introdução  à  Programação

Exercício 2

l Faça um programa que receba um vetor de até 20 inteiros e o inverta l trocando os seus elementos seguindo a ordem: l O último elemento com o primeiro, o segundo com o penúltimo, l o terceiro com o antepenúltimo...

l Exemplo:l Entrada: 5 valores 1 5 8 9 10 l Saída: 10 9 8 5 1

l Obs: l Deve ser feita uma função void swap para trocar os elementos l e deve-se acessar o vetor usando notação de ponteiros