ponteiros em c - joinville.udesc.br · aritmética de ponteiros é usada para localizar elementos...

26
UDESC - Rui J. Tramontin Jr. 1 1 Ponteiros em C Prof. Rui Jorge Tramontin Jr.

Upload: doanhanh

Post on 12-Dec-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 1 1

Ponteiros em C

Prof. Rui Jorge Tramontin Jr.

Page 2: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 2 2

Introdução

Operações sobre Ponteiros

Exemplos

Ponteiros e Funções

Alocação Dinâmica em C

Índice

Page 3: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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;

100

ip

x

Page 5: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 5

Exemplo

int x = 1, y =

2;

int *ip;

ip = &x;

y = *ip;

*ip = 3;

1 x 2 y ip 1 3

Page 6: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 10

Alocação Dinâmica em C

Page 11: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 12

Função malloc()

Protótipo:

void *malloc(size_t n_bytes);

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

Exemplo: int *x = malloc( sizeof(int) );

n_bytes é a quantidade de bytes alocada.

size_t é um tipo long int sem sinal.

Page 13: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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...

a

b

HeapPointer

Topo da área

alocável

StackPointer

Topo da pilha

Variáveis

estáticas

Código objeto

Constantes

512 bytes

50*int = 200 bytes

Page 15: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 15

Aritmética de Ponteiros

Page 16: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 20

Exemplos

Page 21: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 21

Exemplo 1

int *aponta;

int valor1, valor2;

valor1 = 5;

aponta = &valor1;

valor2 = *aponta;

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

Page 22: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 23

Exemplo 2 int *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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 24

Exemplo 2 int *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); // 1000

printf("%i\n", p2); // 1004

printf("%i\n", p3); // 1020

printf("%i\n", p4); // 1000

Page 25: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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: Ponteiros em C - joinville.udesc.br · Aritmética de ponteiros é usada para localizar elementos dentro de um vetor. Dado um vetor A:

UDESC - Rui J. Tramontin Jr. 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','ã',...

}