27
IAED, 2012/2013 Ponteiros e Tabelas K&R: Capitulo 5 IAED, 2012/2013 2 Ponteiros e Tabelas Ponteiros e endereços Ponteiros e argumentos de funções Ponteiros e tabelas Alocação dinâmica de memória Aritmética de ponteiros Tabelas de ponteiros e ponteiros para ponteiros Tabelas multi-dimensionais Inicialização de tabelas de ponteiros Argumentos da linha de comandos Ponteiros para funções

Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

Embed Size (px)

Citation preview

Page 1: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

1

IAED, 2012/2013

Ponteiros e Tabelas

K&R: Capitulo 5

IAED, 2012/2013 2

Ponteiros e Tabelas

•  Ponteiros e endereços •  Ponteiros e argumentos de funções •  Ponteiros e tabelas •  Alocação dinâmica de memória •  Aritmética de ponteiros •  Tabelas de ponteiros e ponteiros para ponteiros •  Tabelas multi-dimensionais •  Inicialização de tabelas de ponteiros •  Argumentos da linha de comandos •  Ponteiros para funções

Page 2: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

2

IAED, 2012/2013 3

Ponteiros em C

=

IAED, 2012/2013 4

Ponteiros e Endereços

•  Na memória do computador cada posição é referenciada por um endereço, atribuído de forma sequencial

•  Posições adjacentes têm endereços consecutivos

3245434

3245435

3245436

3245437

Page 3: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

3

IAED, 2012/2013 5

Ponteiros e Endereços

•  Um ponteiro é uma variável que contém o endereço de outra variável

3245434

3245435

3245436

3245437

3245438

3245439

3245440

3245441

3245442

3245443

‘a’

3245435 char c = ‘a’; char *ptr = &c;

aponta

declaração de um ponteiro inicializo ptr com

o endereço de c

IAED, 2012/2013 6

Um ponteiro em C

é um endereço de memória

IAED, 2012/2013 6

Page 4: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

4

IAED, 2012/2013 7

Um ponteiro em C

é um endereço de memória

IAED, 2012/2013 7

IAED, 2012/2013 8

Ponteiros e Endereços

•  Declaração de um ponteiro para tipo <tipo>

•  Exemplos

<tipo> *<variável>;

char *cptr; /* ponteiro para caracter */

int *iptr; /* ponteiro para inteiro */

double *dptr; /* ponteiro para double */

Page 5: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

5

IAED, 2012/2013 9

Ponteiros e Endereços

•  Operador & aplicado a x representa o endereço de x

#include <stdio.h>

int main() {

int y, x = 1;

int *px;

px = &x; y = *px;

*px = 0;

printf("%d %d\n", x, y);

return 0;

}

IAED, 2012/2013 10

Ponteiros e Endereços

•  Operador * aplicado a px representa o conteúdo da posição de memória apontada por px

#include <stdio.h>

int main() {

int y, x = 1;

int *px;

px = &x;

y = *px; *px = 0; printf("%d %d\n", x, y);

return 0;

}

Page 6: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

6

IAED, 2012/2013

Utilizações do * (asterisco)

•  Declaração do ponteiro

–  x é um ponteiro para um inteiro

•  Conteúdo da posição de memória apontada pelo ponteiro

–  o valor 4 é atribuído ao conteúdo da posição de memória apontada por x

11

int *x;

*x = 4;

IAED, 2012/2013 12

Utilização de Ponteiros

•  O valor de retorno de uma função pode ser um ponteiro

•  O argumento de uma função pode ser um ponteiro

•  Prioridade de & e * é superior à dos operadores aritméticos –  y = *px + 1 funciona como esperado –  ++*px incrementa o valor de x –  (*px)++ (os parênteses são necessários)

int *xpto();

int abcd(char *a, int *b);

Page 7: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

7

IAED, 2012/2013 13

Passagem de Parâmetros para Funções

•  Em C os parâmetros são passados por valor

•  Não funciona como necessário !

void swap(int a, int b) { int aux;

aux = a;

a = b;

b = aux; }

IAED, 2012/2013 14

Passagem de Parâmetros para Funções

•  Passagem por referência consegue-se enviando ponteiros

•  Chamada deverá ser swap(&x, &y)

void swap(int *a, int *b) { int aux;

aux = *a;

*a = *b;

*b = aux; }

Page 8: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

8

IAED, 2012/2013 15

Ponteiros e Tabelas

•  Em C existe uma relação entre ponteiros e tabelas

•  a é um ponteiro para a primeira posição da tabela

#include <stdio.h>

int main() {

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

int *pa = a;

printf("%d %d %d\n", a[2], *(a+2), *(pa+2));

return 0; }

IAED, 2012/2013 16

Ponteiros e Tabelas

•  A declaração int *p1; declara o mesmo que int p2[]; –  p1 pode ser alterado –  p2 não pode ser alterado –  int p2[]; só pode ser utilizado em certos casos

•  A declaração int p3[100]; declara uma tabela com 100 inteiros e aloca memória na quantidade necessária –  p3 não pode ser alterado

•  A declaração char *text; não aloca qualquer memória –  no entanto char *text = "ola"; aloca;

Page 9: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

9

IAED, 2012/2013 17

Ponteiros e Tabelas

•  Qual a diferença entre as duas declarações seguintes ?

•  Ambas alocam 4 bytes e copiam para essa posição de memória a sequência de caracteres 'o','l','a','\0'

•  Em ambos os casos é possível modificar o conteúdo da memória alocada

•  Não é possível alterar o valor de t1, ou seja não é possível pôr t1 a apontar para outra posição de memória

•  É possível alterar o valor de t2

char t1[] = "ola"; char *t2 = "ola";

IAED, 2012/2013 18

Ponteiros e Tabelas

•  Exemplo: cópia de strings void strcpy(char *s, char *t)

{

int i = 0

while ((s[i] = t[i]) != ’\0’)

i++;

}

void strcpy(char *s, char *t) {

while ((*s = *t) != ’\0’) {

s++;

t++;

}

}

Page 10: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

10

IAED, 2012/2013 19

Ponteiros e Tabelas

•  Exemplo: cópia de strings void strcpy(char *s, char *t) {

while ((*s = *t) != ’\0’) {

s++;

t++;

}

}

void strcpy(char *s, char *t)

{

while ((*s++ = *t++));

}

IAED, 2012/2013 20

Ponteiro Nulo / Endereço Zero

•  Ponteiro especial para representar o endereço 0

•  Definido em stdlib.h –  Necessário #include <stdlib.h>

•  Utilizado para indicar situações especiais

•  Na realidade NULL == 0

int *ptr = NULL;

Page 11: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

11

IAED, 2012/2013 21

Alocação Dinâmica de Memória

•  Alocação estática

–  Memória alocada durante o scope da variável –  Não é possível libertar quando não necessária –  Não é possivel utilizar fora do scope

•  Solução: alocação dinâmica !

int tab[100];

IAED, 2012/2013 22

Alocação Dinâmica de Memória

•  Função malloc

•  Recebe como argumento o número de bytes –  Tipo size_t representa uma dimensão em bytes

•  Devolve um ponteiro (endereço) para o primeiro byte do bloco de memória contígua alocada (mas não inicializada) –  void * indica um ponteiro para um tipo não especificado –  permite utilização com qualquer tipo de dados –  posteriormente faz-se conversão para o tipo correcto por type cast

void *malloc(size_t size);

int *tab; tab = (int *) malloc(4*100);

Page 12: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

12

IAED, 2012/2013 23

Alocação Dinâmica de Memória

•  Função malloc

•  Recebe como argumento o número de bytes –  Tipo size_t representa uma dimensão em bytes

•  Devolve um ponteiro (endereço) para o primeiro byte do bloco de memória contígua alocada (mas não inicializada) –  void * indica um ponteiro para um tipo não especificado –  permite utilização com qualquer tipo de dados –  posteriormente faz-se conversão para o tipo correcto por type cast

void *malloc(size_t size);

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

IAED, 2012/2013 24

Alocação Dinâmica de Memória

•  malloc retorna NULL caso não seja possível alocar a memória pedida

•  Verificar sempre o resultado do pedido de memória

int *pvector

pvector = (int *) malloc(sizeof(int)* VEC_SIZE);

if (pvector == NULL){

fprintf(stderr, “Erro: falta de memória\n”);

exit(-1); }

Page 13: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

13

IAED, 2012/2013 25

Alocação Dinâmica de Memória

•  Memória válida desde o ponto em que é alocada até ser libertada ou até o programa terminar

•  Exemplo: alocar memória para uma string e copiá-la

char *strsav(char *s)

{ char *d;

d = (char *) malloc(sizeof(char)*(strlen(s)+1));

strcpy(d, s);

return d; }

IAED, 2012/2013 26

Alocação Dinâmica de Memória

•  Libertação de memória é efectuada com a função free

•  Recebe como argumento o ponteiro para a primeira posição do bloco de memória contígua a libertar

•  Não devolve nada

•  Tanto malloc como free estão definidas em stdlib.h –  Necessário #include <stdlib.h>

void free(void *ptr);

Page 14: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

14

IAED, 2012/2013 27

Alocação Dinâmica de Memória

•  Função realloc

•  Recebe ponteiro ptr para bloco de memória antigo e dimensão size do novo bloco de memória

•  Devolve ponteiro para novo bloco de memória •  Copia valores do bloco antigo para o novo

–  Se novo fôr mais pequeno, só copia até caber –  Se novo fôr maior, copia tudo e deixa o resto sem ser inicializado

void *realloc(void *ptr, size_t size);

IAED, 2012/2013 28

Alocação Dinâmica de Memória

•  Função calloc

•  Aloca memória para uma tabela de nmemb elementos, cada um com dimensão size em bytes

•  Devolve ponteiro para a tabela alocada •  A mesma coisa que malloc(nmemb*size); •  A memória alocada é inicializada toda a 0 (zeros)

void *calloc(size_t nmemb, size_t size);

Page 15: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

15

IAED, 2012/2013 29

Aritmética de Endereços

•  É possível efectuar + e - com ponteiros

int x = 10; int *px = &x;

x px

IAED, 2012/2013 30

Aritmética de Endereços

•  É possível efectuar + e - com ponteiros

•  Incrementa/decrementa na dimensão do tipo para o qual aponta –  sizeof(int) neste caso

int x = 10; int *px = &x;

px++; x px

Page 16: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

16

IAED, 2012/2013 31

Tabelas de Ponteiros

•  É possível definir tabelas em que cada elemento é um ponteiro

•  Neste caso definimos uma tabela com 100 elementos, em que cada elemento é um ponteiro para int

•  tabptr também é um ponteiro

int *tabptr[100];

IAED, 2012/2013 32

Tabelas Multi-Dimensionais

•  A declaração int x[NROWS][NCOLS] declara uma matriz –  Aloca espaço NROWS*NCOLS de inteiros

•  É equivalente a int *x[NROWS] –  Aloca espaço NROWS de ponteiros para inteiros –  Permite que linhas tenham tamanhos diferentes

•  Elemento na linha i e coluna j é x[i][j]

•  Na prática, ponteiros para tabelas são mais usados •  Qualquer número de dimensões pode ser usado •  Primeira dimensão pode não ser especificada

Page 17: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

17

IAED, 2012/2013 33

Inicialização de Tabelas de Ponteiros

char *month_name(int n)

{ static char *name[] = {

"Illegal month",

"January", "February", "March",

"April", "May", "June",

"July", "August", "September", "October", "November", "December"

};

return (n < 1 || n > 12) ? name[0] : name[n];

}

IAED, 2012/2013 34

Ponteiros para Ponteiros

•  É possível declarar um ponteiro para um ponteiro

#include <stdio.h>

int main() {

int x = 10;

int *px = &x;

int **ppx = &px; printf("%d %d %d\n", x, *px, **ppx);

return 0;

}

Page 18: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

18

IAED, 2012/2013 35

Argumentos da Linha de Comandos •  argc - argument count - número de parametros

•  argv - argument values - tabela de strings com os argumentos –  argv[0] é o nome do programa –  argv[i] é i-ésimo argumento

•  Programa "echo" •  $ echo hello world hello world

3 int main(int argc, char *argv[]) { int i;

for(i=1; i < argc; i++)

printf("%s ", argv[i]);

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

return 0;

}

IAED, 2012/2013 36

Ponteiros para Funções

•  É possível ter ponteiros para funções •  O nome de uma função é um ponteiro para essa função

int soma(int a, int b) { return a+b; }

int main() {

int (*ptr)(int, int);

ptr = soma;

printf("%d\n", (*ptr)(3,4)); return 0; }

Page 19: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

19

IAED, 2012/2013 37

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

4

2 base

size

top

IAED, 2012/2013 38

Exemplo: Pilha Dinâmica de Inteiros

#include <stdio.h>

#include <stdlib.h>

#define INITSIZE 3

static int *base; static int *top; static int size;

Page 20: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

20

IAED, 2012/2013 39

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

base top

size

IAED, 2012/2013 40

Exemplo: Pilha Dinâmica de Inteiros

void init() { size = INITSIZE; base = (int*) malloc(size*sizeof(int)); top = base; }

Page 21: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

21

IAED, 2012/2013 41

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

2 base top

size

top

push(2);

IAED, 2012/2013 42

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

4

2 base

size

top

push(4);

top

Page 22: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

22

IAED, 2012/2013 43

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

6

4

2 base

size

push(6);

top

top

IAED, 2012/2013 44

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

6

4

2 base

size

push(8);

top

Page 23: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

23

IAED, 2012/2013 45

•  Quando está cheia, duplica a dimensão: size = size * 2

•  Aloca novo bloco de memória com o dobro da dimensão e copia elementos para lá

•  Insere novo elemento

Exemplo: Pilha Dinâmica de Inteiros

8

6

4

2 base

size

push(8);

top

top

IAED, 2012/2013 46

Exemplo: Pilha Dinâmica de Inteiros

void push(int value) { if (top-base == size) increase_size();

*(top++) = value; }

Page 24: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

24

IAED, 2012/2013 47

Exemplo: Pilha Dinâmica de Inteiros

void increase_size() { int *oldbase = base; int *pa, *pb;

size *= 2; base = (int*) malloc(size * sizeof(int)); for (pa = oldbase, pb = base; pa < top; ) *(pb++) = *(pa++);

free(oldbase);

top += base - oldbase; /* top = pb; */ }

IAED, 2012/2013 48

•  Base: base •  Primeira posição livre: top •  # de posições alocadas: size

•  # de posições ocupadas: top-base

•  Está cheia quando: top-base == size

Exemplo: Pilha Dinâmica de Inteiros

8

6

4

2 base

size

pop();

top

top

Page 25: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

25

IAED, 2012/2013 49

Exemplo: Pilha Dinâmica de Inteiros

int pop() { if (!is_empty()) return *(--top); else

return -1;

}

int is_empty() { return top == base; }

IAED, 2012/2013 50

O que é um ponteiro em C ?

IAED, 2012/2013 50

Page 26: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

26

IAED, 2012/2013 51

Um ponteiro em C

é um endereço de memória

IAED, 2012/2013 51

IAED, 2012/2013 52

O que é um ponteiro em C ?

IAED, 2012/2013 52

Page 27: Ponteiros e Tabelas - Técnico Lisboa · • Tabelas de ponteiros e ponteiros para ponteiros ... 3 5 IAED, 2012/2013 Ponteiros e Endereços • Um ponteiro é uma variável que contém

27

IAED, 2012/2013 53

Um ponteiro em C

é um endereço de memória

IAED, 2012/2013 53

IAED, 2012/2013 54

Apple II

IAED, 2012/2013 54