11 ponteiros em c prof. kariston pereira adaptado de material gentilmente fornecido pelo prof. rui...

26
1 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

Upload: joao-batista-carneiro-fialho

Post on 07-Apr-2016

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

11

Ponteiros em C Prof. Kariston Pereira

Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

Page 2: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 22

Introdução Operações sobre Ponteiros Exemplos Ponteiros e Funções Alocação Dinâmica em C

Índice

Page 3: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 3

Introdução Um ponteiro é uma variável cujo conteúdo é um

endereço de memória. Normalmente, de outra variável. Nesse caso, diz-se que o ponteiro aponta para a

variável.

Devem ser associados e um tipo de dados, e são declarados com um “*” antes do seu identificador:

int *ponteiro;

Page 4: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 4

Operações sobre Ponteiros Operadores para ponteiros:

& - retorna o endereço de uma variável. * - retorna o conteúdo apontado pelo ponteiro.

int *ip; int x;

ip = &x; *ip = 100;

100ipx

Page 5: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 5

Exemplo

int x = 1, y = 2; int *ip;

ip = &x; y = *ip; *ip = 3;

1x 2y ip13

Page 6: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 6

Contra-Exemplo Ponteiros devem sempre ser inicializados.

int *ip;

*ip = 10;

int *ip; int x;

ip = &x; *ip = 10;

Erro na execução!

Ponteiro não inicializado.

Ok!

Page 7: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 7

Ponteiros e Funções Parâmetros de funções podem ser

de dois tipos: Por valor Por referência;

Ponteiros são usados na passagem por referência.

Page 8: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 8

Ponteiros e Funções Exemplo:

Função para troca de valores entre duas variáveis:swap(a, b);

void swap(int x, int y){ int temp; temp = x; x = y; y = temp;}

Não funciona!

•Parâmetros são alocados na pilha;

•Desalocados no final da execução.

Page 9: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 9

Ponteiros e Funções Exemplo:

Função para troca de valores entre duas variáveis:swap(&a, &b);

void swap(int *x, int *y){ int temp; temp = *x; *x = *y; *y = temp;}

Funciona!

•Referências são passadas como parâmetro.

•A modificação é feita diretamente em a e b.

Page 10: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 10

Alocação Dinâmica em C

Page 11: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 11

Alocação Dinâmica em C A memória alocada pelas funções de alocação

dinâmica é obtida do heap.

O heap é a região de memória livre que se encontra entre o programa (com a área de armazenamento permanente) e a pilha (stack).

A linguagem C possui duas funções básicas para gerência de memória:

malloc(num de bytes) - aloca memória. free(endereço) - libera memória

Page 12: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 12

Função malloc() Protótipo:

void *malloc(número_de_bytes);

Devolve um ponteiro do tipo void (sem tipo) para o início (1º byte) da área de memória alocada.

Para isto deve ser utilizado sempre um typecasting. x = (int *) malloc( sizeof(int) );

número_de_bytes é a quantidade de bytes alocada.

Page 13: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 13

Função free() Protótipo:

void free( void *p );

Devolve memória previamente alocada apontada por p.

A utilização de free() com um valor de ponteiro qualquer poder ter resultados catastróficos.

A gerência de buracos no heap é responsabilidade do sistema operacional.

Page 14: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 14

Exemplo#include <stdlib.h>#include <stdio.h>

char *a;int *b;

main (){ a = (char *) malloc(512); // Aloca 512 bytes

b = (int *) malloc(50*sizeof(int));// Aloca espaço

// para 50 inteiros. free(a);} Sistema

Operacional

100111010...

ab

HeapPointerTopo da áreaalocável

StackPointerTopo da pilha

Variáveis estáticas

Código objeto

Constantes

512 bytes

50*int = 200 bytes

Page 15: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 15

Aritmética de Ponteiros

Page 16: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 16

Aritmética de Ponteiros A linguagem C permite que se faça operações

aritméticas sobre ponteiros.

Oferece uma liberdade que nenhuma outra linguagem de programação oferece (exceto assemblers).

Isto é muito útil, porém é também muito perigoso!

Operações válidas com ponteiros: adição, subtração e comparação.

São muito úteis com vetores.

Page 17: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 17

Semântica da Aritmética de Ponteiros A aritmética de ponteiros leva em o tamanho

ocupado pelo tipo de dados apontado.

Sejam p um ponteiro para o tipo T, e i um valor inteiro.

p + i é equivalente a:endereço( p ) + i * sizeof( T )

p - i é equivalente a:endereço( p ) - i * sizeof( T )

Page 18: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 18

Ponteiros e Vetores Vetores podem ser tratados como

ponteiros.

Aritmética de ponteiros é usada para localizar elementos dentro de um vetor.

Dado um vetor A: A[i] ≡ *( A + i )

Page 19: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 19

Ponteiros e Vetores Exemplo: int arr[10];

O tipo int ocupa 4 bytes na memória. Assumindo que arr está no endereço 1000, temos:

Page 20: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 20

Exemplos

Page 21: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 21

Exemplo 1

int *aponta;int valor1, valor2;

valor1 = 5;

aponta = &valor1;

valor2 = *aponta;

printf("%i\n", valor2);

Page 22: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 22

Exemplo 2:invertendo um vetor

int x[5] = {1, 2, 3, 4, 5};

int *left = x;int *right = x + 4;

while(left < right){ int temp = *left; *left = *right; *right = temp; left++; right--;}

Page 23: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 23

Exemplo 2int *p1, *p2, *p3, *p4, x=0;

p1 = &x;p2 = p1 + 1;p3 = p2 + 4;p4 = p3 - 5;

printf("%i\n", *p1); printf("%i\n", *p2); printf("%i\n", *p3); printf("%i\n", *p4);

printf("%i\n", p1); printf("%i\n", p2); printf("%i\n", p3); printf("%i\n", p4);

Page 24: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 24

Exemplo 2int *p1, *p2, *p3, *p4, x=0;

p1 = &x;p2 = p1 + 1;p3 = p2 + 4;p4 = p3 - 5;

printf("%i\n", *p1); // 0 printf("%i\n", *p2); // “lixo”printf("%i\n", *p3); // “lixo”printf("%i\n", *p4); // 0

printf("%i\n", p1); // 1000printf("%i\n", p2); // 1004printf("%i\n", p3); // 1020printf("%i\n", p4); // 1000

Page 25: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 25

char nome[30] = "João da Silva";char *p1, *p2;char car;int i;

p1 = nome;car = nome[3];car = p1[0];p2 = &nome[5];printf("%s", p2);p2 = p1;p2 = p1 + 5;printf("%s",(p1 + 5));printf("%s",(p1 + 20));

for (i=0; i < strlen(nome); i++){ printf ("%c", nome[i]);

p2 = p1 + i; printf ("%c", *p2);}

Page 26: 11 Ponteiros em C Prof. Kariston Pereira Adaptado de Material gentilmente fornecido pelo Prof. Rui Tramontin (DCC/UDESC)

UDESC – Prof. Kariston Pereira 26

char nome[30] = "João da Silva";char *p1, *p2;char car;int i;

p1 = nome; // nome é ponteiro. Mesmo que p1 = &nome[0].car = nome[3]; // atribui 'o' a car.car = p1[0]; // atribui 'J' a car.p2 = &nome[5]; // p2 aponta para 6ª posição de nome ('d').printf("%s", p2); // imprime "da Silva".p2 = p1; // p2 aponta para o mesmo endereço de p1.p2 = p1 + 5; // equivalente a p2 = &nome[5].printf("%s",(p1 + 5)); // imprime "da Silva".printf("%s",(p1 + 20)); // imprime lixo! (cuidado).

for (i=0; i < strlen(nome); i++){ printf ("%c", nome[i]); // imprime 'J','o','ã',...

p2 = p1 + i; // p2 aponta para próximo caracter em nome. printf ("%c", *p2); // imprime 'J','o','ã',...}