Aula 13 ponteiros - Programação 1

55
Programação I: Ponteiros Rodrigo Paes

description

Aulas da Disciplina de Programação I do Professor Rodrigo Paes, UFAL

Transcript of Aula 13 ponteiros - Programação 1

Page 1: Aula 13 ponteiros - Programação 1

Programação I:Ponteiros

Rodrigo Paes

Page 2: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exercício em sala

Objetivo: ler 03 numeros nas variaveis x,y e z e depois ordenar x,y e z de tal forma que x armazene o menor valor, y o intermediário e z o maior

[email protected]

Page 3: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Código repetido

O que queremos com esses 03 trechos? Trocar os valores de duas

variáveis, correto? Ou seja, queriamos

isolar uma funcionalidade Uma função de trocar

valores

[email protected]

Page 4: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Não seria melhor assim?

Ok … vamos tentar

[email protected]

trocar(x,y)

trocar(x,z)

trocar(y,z)

Page 5: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Tentativa 01

funcao_trocar_valores2.c

[email protected]

Page 6: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Os valores foram trocados?

Não, né?

Passagem por valor A passagem de parâmetro foi feita por valor É feita uma cópia do valor da variável

[email protected]

Page 7: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Passagem por valor

[email protected]

Page 8: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ponteiros

Ao declarar uma variável sempre informamos o tipo dela int a; float soma; …

Lembra da 1a aula? As variáveis ficam na memória

Endereço e Conteúdo

[email protected]

Page 9: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Variáveis

Já sabemos alterar o conteúdo das variáveis Comando de

atribuição resto = 25; soma =soma + i; …

Mas como descobrir o endereço de memória das nossas variáveis?

[email protected]

End.

Conteúdo

1 34

2 “O rato roeu a roupa do rei de roma”

3 34.67

4 1

5 0

6 “aula de p1”

7 4677

… 123

n

Page 10: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Operador &

Este operador nos fornece o endereço de memória de uma variável

Exemplo:main()

{

int a = 1;

printf("O endereco de a eh: %p\n",&a);

}

[email protected]

Page 11: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Um novo tipo de variável: ponteiro

O tipo da variável define os valores válidos para uma variável Exemplo

int: valores inteiros char: caracteres float: ponto flutuante …

Um ponteiro é um tipo de variável cujos valores válidos são endereços de memória

[email protected]

Page 12: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Como funciona?

Imagine uma caixa postal Caixa postal 22300

A caixa postal é só um endereço Ela aponta para uma localização que contém um

imóvel (conteúdo) Os imóveis podem ser de vários tipos

Residencial casa, residencial apartamento, comercial …

Ou seja, a caixa postal contém um endereço para um conteúdo de um determinado tipo A caixa postal é um ponteiro

[email protected]

Page 13: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

… voltando ao C

Um ponteiro é um endereço para um determinado tipo int float char outro ponteiro …

[email protected]

Page 14: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ponteiros

Endereço Identificador Conteúdo

0xFF4454 a 5

… … …

… … …

… … …

… … …

0xBBA031 b 12

[email protected]

ponteiro_a

Page 15: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Declaração de ponteiros

main()

{

int a = 1;

int b = 2;

int *pt_a;

[email protected]

Page 16: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Atribuição com ponteiro

main()

{

int a = 1;

int b = 2;

int *meu_ponteiro;

meu_ponteiro = &a; // atribui o endereço de a

[email protected]

Page 17: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Acesso ao conteúdo do local apontado pelo ponteiro: *, o operador de “dereference”

main()

{

int a = 1;

int b = 2;

int *pt_a;

pt_a = &a;

*pt_a = 50; // o que vai acontecer aqui?

[email protected]

Page 18: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Brincando com ponteiros

ponteiros.c

[email protected]

Page 19: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Interessante né? mas e daí?

Vamos voltar para a nossa função de troca

[email protected]

E se …• na nossa função recebessemos os

endereços das variáveis que desejamos trocar

• Com o endereço, poderíamos trocar os valores

Page 20: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 5

0xFF1242 y 3

0xBBA031 z 2

0xABA005 aux ---

a

b

void trocar_valores(float *a, float *b){ float aux;

Page 21: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 5

0xFF1242 y 3

0xBBA031 z 2

0xABA005 aux 5

a

b

void trocar_valores(float *a, float *b){ float aux; aux = *a;

Page 22: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 5

0xFF1242 y 3

0xBBA031 z 2

0xABA005 aux 5

a

b

void trocar_valores(float *a, float *b){ float aux; aux = *a; *a = *b;

Page 23: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 3

0xFF1242 y 3

0xBBA031 z 2

0xABA005 aux 5

a

b

void trocar_valores(float *a, float *b){ float aux; aux = *a; *a = *b;

Page 24: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 3

0xFF1242 y 3

0xBBA031 z 2

0xABA005 aux 5

a

b

void trocar_valores(float *a, float *b){ float aux; aux = *a; *a = *b; *b = aux;}

Page 25: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

trocar_valores(&x,&y)

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 3

0xFF1242 y 5

0xBBA031 z 2

0xABA005 aux 5

a

b

void trocar_valores(float *a, float *b){ float aux; aux = *a; *a = *b; *b = aux;}

Page 26: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ideia

Ao sair … do escopo local as variáveis são eliminadas

[email protected]

Endereço Identificador Conteúdo

0xFF4454 x 3

0xFF1242 y 5

0xBBA031 z 2if (y < z) // neste caso y é o menor { // troca os conteúdos de x e de y trocar_valores(&x,&y); } else // neste caso z é o menor

Page 27: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

O programa completo

funcao_trocar_valores3.c

[email protected]

Page 28: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Passagem por referência

O que acabamos de fazer foi passar os parâmetros por referência ao invés de passar por valor Passamos apenas uma referência para a variável

externa O seu valor não é copiado

Mais eficiente Exige cuidados com efeitos colaterais

[email protected]

Page 29: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Algumas reflexões

Pra que ponteiros? C é de uma época em que os computadores eram

menos poderosos Necessidade de uso eficiente de processamento e

memória Logo, habilidade de trabalhar diretamente a memória

é muito útil E por que ainda usamos ponteiros?

Necessidade de eficiência ainda é importante

[email protected]

Page 30: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exemplos

main(){ int x = 7 ; int *px ;

px = &x ; *px = 8 ;

printf( "%d\n" , x ) ; printf( "%d\n" , &x ) ; printf( "%d\n" , px ) ; printf( "%d\n" , *px ) ; }

[email protected]

Page 31: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exemplos

void exemplo2()

{

int firstvalue, secondvalue;

int * mypointer;

mypointer = &firstvalue;

*mypointer = 10;

mypointer = &secondvalue;

*mypointer = 20;

printf("%d\n",firstvalue);

printf("%d\n",secondvalue);

}

[email protected]

Page 32: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exemplos

void exemplo3()

{

int firstvalue = 5, secondvalue = 15;

int * p1, * p2;

p1 = &firstvalue;

p2 = &secondvalue;

*p1 = 10;

*p2 = *p1;

p1 = p2;

*p1 = 20;

printf("%d\n",firstvalue);

printf("%d\n",secondvalue);

}

[email protected]

Page 33: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exemplos

Assuma que os seguintes endereços: c é 1 d é 2 e é 3

Qual a saída do programa abaixo:char c = 'T', d = 'S';

char *p1 = &c;

char *p2 = &d;

char *p3;

p3 = &d;

printf("%c\n",*p3);

p3 = p1;

printf("%c %p\n", *p3, p3);

*p1 = *p2;

printf("%c %p\n", *p1, p1 );

[email protected]

Page 34: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exemplos

int *p;

int i;

int k;

i = 42;

k = i;

p = &i;

Qual dos seguintes comandos muda o valor de i para 75? k = 75; *k = 75; p = 75; *p = 75;

[email protected]

Page 35: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Qual o valor de y?

int main(){

int y, *p, x;y = 0;p = &y;x = *p;x = 4;(*p)++;x;(*p) += x;printf ("y = %d\n", y);return(0);

}

Rodrigo Paes – [email protected]

Page 36: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Exercício: escreva a função ordenar

int main()

{

int a, b, c, d, e;

printf("Digite 05 numeros\n");

scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);

ordenar(&a,&b,&c,&d,&e);

printf("Os numeros ordenados em ordem decrescente sao: %d, %d, %d, %d, %d\n",a,b,c,d,e);

return 0;

}

Rodrigo Paes – [email protected]

Page 37: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

PONTEIROS E ARRAYS

[email protected]

Page 38: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Lembra como você usa os arrays?

int array[9];

array[0] = 20;

printf(“%d”, array[0] );

[email protected]

Page 39: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Por debaixo dos panos

Uma variável array é um ponteiro constante para uma área de memória onde os elementos serão armazenadosint array[9];

*array = 20;

printf(“%d”, *array );

Perceba que a variável array é um ponteiro para o primeiro elemento

[email protected]

20

array

Page 40: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

E como acessar os outros elementos?

Aritmética de ponteirosint array[9];

*array = 20;

*(array +1) = 30;

*(array +2) = 40;

[email protected]

20 30 40

array

32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits

Desloca 1 * sizeof(int) bytes

Desloca 2 * sizeof(int) bytes

Page 41: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Então …

array[7]=96; É idêntico a fazer: *(array+7)=96;

Podemos também:int *p;int array[5];p = array;p = &array[4];p[-1] = 5;printf("%d\n",array[3]);*(p-1) = 8;printf("%d\n",array[3]);

[email protected]

Page 42: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Atenção

int *p;

p[3] = 8;

Certo ou errado?

[email protected]

Page 43: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Quiz: pode ou não ? Qual a saída?

#include <stdio.h>

int main()

{

int a[10];

*a = 3;

a[1]= 4;

printf("%d\n%d\n",a[0],a[1]);

}[email protected]

Page 44: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Quiz: pode ou não? Qual a saída?

int main()

{

int a[10];

*a = 3;

a[1]= 4;

a++;

*a =5;

printf("%d\n%d\n",a[0],a[1]);

}[email protected]

Não podemos alterar o ponteiro

Page 45: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Passando arrays para funções

void funcao(int *a, int tamanho){

int i;for (i=0; i< tamanho ; i++){

a[i] = i*i;}

}main(){

int x[5];funcao(x,5);

}

[email protected]

Page 46: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Ponteiros para ponteiros

char a;

char * b;

char ** c;

a = 'z';

b = &a;

c = &b;

printf("%c\n",a);

printf("%c\n",*b);

printf("%c\n",**c);

[email protected]

Page 47: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Arrays bidimensionais :: estáticos

int array1[2][2] = {{0, 1}, {2, 3}};

Na memória:

0 1 2 3

O mesmo layout de:

int array2[4] = { 0, 1, 2, 3 };

[email protected]

Page 48: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Arrays bidimensionais :: estáticos

Um array 2D não é a mesma coisa que int** Array para ponteiros, só “funciona”

automaticamente no primeiro nível Logo:

int array1[2][2] = {{0, 1}, {2, 3}}; void function2(int a[][2]); ou: void function2(int a[2][2]);

Diferente para alocação dinâmica

[email protected]

Page 49: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Alocação dinâmica

Muitas vezes só sabemos o tamanho do nosso array durante a execução do programa

Usar esta abordagem permite protelar a decisão sobre o tamanho do bloco de memória necessário para armazenar um array

Quando aquela memória não é mais necessária, ela pode ser liberada para outros usos

[email protected]

Page 50: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Alocação dinâmica

Exemplo. Alocação de um array com 10 inteiros

int *iptr;

iptr = (int *)malloc(10 * sizeof(int));

if (iptr == NULL)

{

... Rotina de erro vem aqui ...

}

[email protected]

Page 51: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Alocação dinâmica e arrays

int *iptr;

iptr = (int *)malloc(10 * sizeof(int));

if (iptr == NULL)

{

... Rotina de erro vem aqui ...

}

int k;

for (k = 0; k < 10; k++)

iptr[k] = 2;

[email protected]

Page 52: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Alocar uma matriz de inteiros

int **mi;

int row,col;

mi = malloc (ROWS * sizeof (int *));

for (row = 0; row < ROWS; row++)

{

mi[row] = malloc (COLS * sizeof (int));

}

for (row = 0; row < ROWS; row++)

{

for (col = 0; col < COLS; col++)

{

mi[row][col] = 17;

}

}

[email protected]

Não há garantia dealocação contínua na memória, nesse caso

Page 53: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Alocar uma matriz de inteiros :: continuamente https://

dl.dropbox.com/u/17364381/p1/alocacao_continua_matriz.c

[email protected]

Page 54: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Realocação

https://dl.dropbox.com/u/17364381/p1/realloc.c

[email protected]

Page 55: Aula 13 ponteiros - Programação 1

Instituto de Computação – UFAL

Liberar a memória

/* free example */

#include <stdlib.h> /* malloc, calloc, realloc, free */

int main ()

{

int * buffer1, * buffer2, * buffer3;

buffer1 = (int*) malloc (100*sizeof(int));

buffer2 = (int*) calloc (100,sizeof(int));

buffer3 = (int*) realloc (buffer2,500*sizeof(int));

free (buffer1);

free (buffer3);

return 0;

}

[email protected]