76091476-ponteiros

70
Programação C Ponteiros Fernando S. Pacheco INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE SANTA CATARINA CAMPUS FLORIANÓPOLIS DEPARTAMENTO ACADÊMICO DE ELETRÔNICA

Upload: victor-borgaco

Post on 28-Dec-2015

9 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 76091476-ponteiros

Programação CPonteiros

Fernando S. Pacheco

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE SANTA CATARINACAMPUS FLORIANÓPOLISDEPARTAMENTO ACADÊMICO DE ELETRÔNICA

Page 2: 76091476-ponteiros

ProgC ­ Ponteiros 2

Sumário

● Ponteiros– Recapitulando variáveis– Aplicações– Operadores e inicialização– Argumento de funções– Aritmética de ponteiros– Relação com vetores (arrays)– Exemplos e cuidados– Ponteiros const

Page 3: 76091476-ponteiros

ProgC ­ Ponteiros 3

Ponteiros

● Conceito importantíssimo em C● Recapitulando variáveis em C

– Variável é um espaço em memória com um nome específico e com valor que pode mudar

– Tamanho do espaço depende do tipo da variável

Endereço (byte)

kNome

Valor

0xA0 0xA1 0xA2 0xA3 0xA4 0xA5

Variável

Memória hipotética organizada em bytes

Page 4: 76091476-ponteiros

ProgC ­ Ponteiros 4

Recapitulando variáveis

● Quando se declarachar k;

● 1 byte (8 bits) de memória é reservado (para guardar um valor inteiro)

● Uma tabela de símbolos mapeia o endereço reservado para o identificador k

Page 5: 76091476-ponteiros

ProgC ­ Ponteiros 5

Recapitulando variáveis

● Quando, no programa, define­sek=2;

● O valor 2 é colocado na porção de memória reservada para k

00000010

Endereço (byte)

kNome

Valor

0xA0 0xA1 0xA2 0xA3 0xA4 0xA5

Variável

Page 6: 76091476-ponteiros

ProgC ­ Ponteiros 6

Recapitulando variáveis

● Observe que ao elemento k estão associadas duas informações– O próprio inteiro que está armazenado (2, p.ex.)– O “valor” da localização de memória, ou seja, o 

endereço de k

● Há situações em que o que se deseja armazenar é um endereço

● Ponteiro é uma variável que armazena um endereço de memória, ou seja, aponta para um endereço

Page 7: 76091476-ponteiros

ProgC ­ Ponteiros 7

Ponteiros

● Na figura, a caixa representa um espaço em memória

● var1 é o nome de um desses espaços● 2 é o valor que está armazenado nesse espaço● 0xA0 é o endereço desse espaço na memória

00000010

Endereço (byte)

Nome

Valor

0xA0

Variávelvar1

0xA0

0xA7

ptr_var1

Page 8: 76091476-ponteiros

ProgC ­ Ponteiros 8

Ponteiros

● ptr_var1 é uma outra variável● ptr_var1 armazena o valor (endereço) 0xA0● Neste exemplo, é o endereço da variável var1

00000010

Endereço (byte)

Nome

Valor

0xA0

Variávelvar1

0xA0

0xA7

ptr_var1

Page 9: 76091476-ponteiros

ProgC ­ Ponteiros 9

Ponteiros

● Diz­se que ptr_var1 aponta para var1● Ponteiro também é chamado de variável de 

endereço

00000010

Endereço (byte)

Nome

Valor

0xA0

Variávelvar1

0xA0

0xA7

ptr_var1

Page 10: 76091476-ponteiros

ProgC ­ Ponteiros 10

Aplicações de Ponteiros

● Fazendo uma analogia com endereços físicos● O endereço é praticamente de mesmo tamanho● As casas em cada endereço podem ter 

tamanhos diferentes

R. das

 Letra

s, 45

R. das

 Letra

s, 97

R. das

 Letra

s, 10

3

R. das

 Letra

s, 25

Page 11: 76091476-ponteiros

ProgC ­ Ponteiros 11

Aplicações de ponteiros

● Observe o exemplo seguinte● Executando, verifica­se que tamanho dos 

ponteiros é sempre o mesmo● Para plataforma 32 bits, é de 4 bytes

printf("tamanho de char: %d\n", sizeof(char));printf("tamanho do ptr para char: %d\n", sizeof(char*));printf("tamanho de int: %d\n", sizeof(int));printf("tamanho do ptr para int : %d\n", sizeof(int*));

Page 12: 76091476-ponteiros

ProgC ­ Ponteiros 12

Aplicações de Ponteiros

● Voltando à analogia da casa/endereço● Uma aplicação é acessar estruturas de dados 

(“casa”) através de ponteiros (“endereço”)● Mesmo para estruturas complexas, o acesso 

será rápido

Page 13: 76091476-ponteiros

ProgC ­ Ponteiros 13

Aplicações de Ponteiros

● Outra aplicação é retornar mais de um valor de uma função através de ponteiros

● Lembrar que no formato convencionaltipo_retorno nome_funcao(parametr1, parametr2)

float media(float nota1, float nota2)

● Só um valor pode ser retornado

Page 14: 76091476-ponteiros

ProgC ­ Ponteiros 14

Declaração de ponteiros

● Colocar um asterisco na frente do nome da variávelint var1; // declara uma variável do tipo int

int *ptr_num; //declara um ponteiro do tipo int

● Cuidado com declaração de mais de um ponteiro na mesma linhaint  p,  q,  r; // três variáveis comunsint *p,  q,  r; // cuidado! apenas p será um ponteiro!int *p, *q, *r; // agora temos três ponteiros

Page 15: 76091476-ponteiros

ProgC ­ Ponteiros 15

Operadores para Ponteiros

Operador Significado

*

&

Dereference (dado um ponteiro, obtém o elemento referenciado)

Address_of (dado um elemento, aponta para o mesmo)

Page 16: 76091476-ponteiros

ProgC ­ Ponteiros 16

Operadores para Ponteirosint var1; // declara variável do tipo int com o nome var1var1 = 4;

int *ptr_var1; //declara um ponteiro do tipo int

ptr_var1 = &var1; //ponteiro aponta para var1, ou seja, armazena o endereço de var1

*ptr_var1 = 5; //altera o valor que está armazenado no endereço apontado pelo ponteiro para 5

Código C Descrição

var1 Variável simples

&var1 Ponteiro para a variável var1 (endereço de var1)

Um inteiroptr_var1

Ponteiro para um inteiro (neste exemplo, aponta para a variável var1)

*ptr_var1

Page 17: 76091476-ponteiros

ProgC ­ Ponteiros 17

Operações com Ponteiros

Page 18: 76091476-ponteiros

ProgC ­ Ponteiros 18

Operações com Ponteiros#include <stdio.h>int main()  {   int  i = 10;   int *ptr;   ptr = &i;

   printf("Valor de i: %d\n", i);   printf("Valor apontado por ptr: %d\n", *ptr);   printf("Endereço de i: %p\n", &i);   printf("Endereço apontado por ptr: %p\n", ptr);   printf("Endereço de ptr: %p\n", &ptr);      *ptr =  5;   printf("Valor de i: %d\n", i);   printf("Valor apontado por ptr: %d\n", *ptr);   printf("Endereço apontado por ptr: %p\n", ptr);   return(0);}

Page 19: 76091476-ponteiros

ProgC ­ Ponteiros 19

Mais ponteiros

● Dois ou mais ponteiros podem apontar para o mesmo endereço

int val;

int  *primeiro_ptr;   /* um ponteiro */int  *segundo_ptr;    /* mais um ponteiro */

val = 1;         /* atribui um valor para a variável * /

primeiro_ptr = &val;  //O que está sendo feito aqui? Comentesegundo_ptr = primeiro_ptr; // E aqui? É válido fazer isso?

Page 20: 76091476-ponteiros

ProgC ­ Ponteiros 20

Exercício 1

● Determine o que ocorre em cada linha do programa– Qual o valor final de c e d?int *a, *b, c = 3, d = 7;a = &c;        b = &d;        *a = 5;*b = 8;        *a = *b;       *a = 2;        b = a;         *b = 0;        

Page 21: 76091476-ponteiros

ProgC ­ Ponteiros 21

Resposta do Exercício 1

int *a, *b, c = 3, d = 7;a = &c;   // a apontará para cb = &d;   // b apontará para d*a = 5;   // o valor em c é alterado (c=5)*b = 8;   // o valor na variável d é alterado (d=8)*a = *b;  // o valor de d (apontado por b) é                  //  copiado para c (apontado por a) (c=8)*a = 2;   // o valor na variável c é alterado (c=2)b = a;    // b aponta para o mesmo lugar que a,          //  ou seja, para c*b = 0;   // o valor de c é alterado (c=0)

Page 22: 76091476-ponteiros

ProgC ­ Ponteiros 22

Exercício 2

● Determine o que ocorre em cada linha do programa– Qual o valor final de a e d?int a=5, *b, *c, d=8;b = &a;a = 7;        c = &a;*c = 9;b = &d;        *b = *c;        *c = *b + *b;       d = a;         *b = 1;        

Page 23: 76091476-ponteiros

ProgC ­ Ponteiros 23

Inicialização de ponteiros

● Ponteiros devem ser inicializados antes de serem usados, ou seja, têm que apontar para um endereço específico antes do uso– Chamado wild pointer (ponteiro selvagem)– Fazer o seguinte levará a uma falha de 

segmentação

int *p; /*ponteiro não inicializado*/*p = 9; /*o endereço físico para guardar o número 9 pode não ser válido*/

Page 24: 76091476-ponteiros

ProgC ­ Ponteiros 24

Inicialização de ponteiros

● Compile e execute o programa seguinte● Observe o problema

Page 25: 76091476-ponteiros

ProgC ­ Ponteiros 25

Inicialização de ponteiros#include <stdio.h>int main(){   int  val = 7;   int *ptr;

   printf("Valor de val: %d\n", val);   printf("Endereço apontado por ptr: %p\n", ptr);

   printf("Valor apontado por ptr: %d\n", *ptr);    /*observe que aqui haverá “lixo”, que poderia ser usado e traria consequências desastrosas*/      return(0);}

Page 26: 76091476-ponteiros

ProgC ­ Ponteiros 26

Inicialização de ponteiros#include <stdio.h>int main(){   int  val = 7;   int *ptr=NULL; /*apontar para o endereço NULL (0), irá evitar que “lixo” seja usado, como no exemplo anterior*/

   printf("Valor de val: %d\n", val);   printf("Endereço apontado por ptr: %p\n", ptr);

   printf("Valor apontado por ptr: %d\n", *ptr);    /*irá gerar um SEG FAULT (falha de segmentação)*/      return(0);}

Page 27: 76091476-ponteiros

ProgC ­ Ponteiros 27

Inicialização de ponteiros/*Mais um exemplo de problema*/#include <stdio.h>int main(){   int  val = 7;   int *ptr;

   *ptr = 5; //aqui ocorrerá uma falha de segmentação (SEG FAULT)      printf("Valor de val: %d\n", val);   printf("Valor apontado por ptr: %d\n", *ptr);   printf("Endereço apontado por ptr: %p\n", ptr);   return(0);}

Page 28: 76091476-ponteiros

ProgC ­ Ponteiros 28

Resumo até aqui

● Até aqui, vimos o que são ponteiros e como operá­los

● Vamos ver, agora, uma aplicação importante– Funções com mais de um retorno através do uso 

de ponteiros

Page 29: 76091476-ponteiros

ProgC ­ Ponteiros 29

Ponteiros como argumentos de funções

● Em C, parâmetros são passados para uma função através de uma chamada por valor

● Valor do argumento é copiado para dentro da função

Page 30: 76091476-ponteiros

ProgC ­ Ponteiros 30

Ponteiros como argumentos de funções

● Na chamada por valor o caminho só tem uma direção

Page 31: 76091476-ponteiros

ProgC ­ Ponteiros 31

Ponteiros como argumentos de funções

● Mas usando ponteiros, é possível alterar o próprio parâmetro de entrada

● Assim, função poderá emular a existência de mais de um retorno

● Passagem por referência

● Vamos ver um exemplo prático

Page 32: 76091476-ponteiros

ProgC ­ Ponteiros 32

Ponteiros como argumentos de funções

● Programa para trocar o valor de duas variáveis#include <stdio.h>int main(){   int a = 5;   int b = 10;   int temp;   printf ("%d %d\n", a, b);      temp = a;   a = b;   b = temp;      printf ("%d %d\n", a, b);   return 0;}

Page 33: 76091476-ponteiros

ProgC ­ Ponteiros 33

Ponteiros como argumentos de funções

● E se essa operação tiver que ser repetida várias vezes? Como colocá­la em uma função?

● Verifique se o código seguinte faria isso.

Page 34: 76091476-ponteiros

ProgC ­ Ponteiros 34

#include <stdio.h>void swap(int i, int j){   int temp;   temp = i;   i = j;   j = temp;}int main(){   int a, b;   a = 5;   b = 10;   printf ("%d %d\n", a, b);   swap (a, b);   printf ("%d %d\n", a, b);   return 0;}

Page 35: 76091476-ponteiros

ProgC ­ Ponteiros 35

Ponteiros como argumentos de funções

● Como fazer usando ponteiros#include <stdio.h>void swap (int *i, int *j) {   int temp;   temp = *i;   *i = *j;   *j = temp;}int main () {   int a, b;   a = 5;   b = 10;   printf ("\n\nValem a=%d, b=%d\n", a, b);   swap (&a, &b);   printf ("\n\nAgora, valem a=%d, b=%d\n", a, b);   return 0;}

Page 36: 76091476-ponteiros

ProgC ­ Ponteiros 36

Ponteiros como argumentos de funções

● Outro exemplo//contador é incrementado dentro da função#include <stdio.h>void inc_contador(int *conta_ptr){   (*conta_ptr)++;}

int main(){    int   conta = 0;    while (conta < 10)        inc_contador(&conta);        printf(“conta = %d\n”, conta);    return (0);}

Page 37: 76091476-ponteiros

ProgC ­ Ponteiros 37

Ponteiros como argumentos de funções

#include <stdio.h>

void inc_contador    (int *conta_ptr){   (*conta_ptr)++;}

int main(){    int   conta = 0;    while (conta < 10)        inc_contador(&conta);    return (0);}

Page 38: 76091476-ponteiros

ProgC ­ Ponteiros 38

Exercício

● Fazer uma função que receba o raio de um círculo e devolva o comprimento da circunferência e a área– Não use variáveis globais– Use ponteiros

● main() pergunta o raio para o usuário, chama a função e depois imprime o resultado

Page 39: 76091476-ponteiros

ProgC ­ Ponteiros 39

Ponteiros como argumentos de funções

● Além de permitir que mais de um valor retorne, a passagem por referência tem outra vantagem– Não há cópia dos valores para dentro da função– Mais rápido e eficiente

● Principalmente para manipulação de vetores e estruturas

– Observe o exemplo seguinte●  interessante monitorar a memória (no debugger)

Page 40: 76091476-ponteiros

ProgC ­ Ponteiros 40

Ponteiros como argumentos de funções

#include <stdio.h>

void troca(char* string_ptr) {   //frase não é copiada para dentro da função. É passado um ponteiro (endereço do início da string).   *string_ptr='0'; //altera a primeira letra   string_ptr++;   *string_ptr='1'; //altera a segunda letra}

int main () {   char frase[150]="Esta é uma string grande...";   printf ("\n\nfrase=%s\n", frase);   troca(frase);   printf ("\n\nAgora, frase=%s\n", frase);   return 0;}

Page 41: 76091476-ponteiros

ProgC ­ Ponteiros 41

Aritmética de Ponteiros

● A definição do tipo em ponteiros serve para–  que o compilador saiba quantos bytes copiar para 

uma posição de memória

int *ptr, var1; //plataforma com int 32

ptr = &var1;

*ptr = 2;● Neste exemplo, indica que 32 bits representando o 

número 2 serão copiados para a área de memória apontada

– Além disso, também serve para fazer operações aritméticas com ponteiros

Page 42: 76091476-ponteiros

ProgC ­ Ponteiros 42

Aritmética de Ponteiros

● Vamos imaginar que ptr do exemplo anterior aponta para o endereço (em bytes) 100 (decimal)

● Para qual endereço aponta (ptr+1)?

Page 43: 76091476-ponteiros

ProgC ­ Ponteiros 43

Aritmética de Ponteiros

● Se ptr é do tipo int (4 bytes), o ponteiro irá apontar para o próximo endereço com um inteiro

● Neste caso hipotético, para o endereço 104

Page 44: 76091476-ponteiros

ProgC ­ Ponteiros 44

Aritmética de Ponteiros

● Os operadores–  ++, ­­– comparação: >, <, >=, <=, ==, !=– São válidos com ponteiros e operam sobre os 

endereços– Veja exemplo seguinte

Page 45: 76091476-ponteiros

ProgC ­ Ponteiros 45

Aritmética de Ponteiros#include <stdio.h>int main(void) {  int k=2010;  int *ptr=&k;

  printf("0. tamanho do int: %d\n", sizeof(int));  printf("0. endereço de k: %p\n", &k);  printf("0. endereço apontado por ptr: %p\n", ptr);

  ptr++; //para fins didáticos.Não deve ser acessado  printf("1. endereço apontado por ptr: %p\n", ptr);  ptr++;  printf("2. endereço apontado por ptr: %p\n", ptr);

  if (ptr>&k)  {    printf("endereço %p é maior que %p\n", ptr, &k);  }  return 0;}

Page 46: 76091476-ponteiros

ProgC ­ Ponteiros 46

Ponteiros e Vetores (Arrays)

● Podemos continuar estudando a aritmética de ponteiros a partir de vetores

● Em C, os elementos de um vetor são guardados sequencialmente, a uma “distância” fixa um do outro

● Seja o seguinte (pont_vet1.c)

char array[5] = {5, 10, 15, 20, 25};char *array_ptr = &array[0];

Page 47: 76091476-ponteiros

ProgC ­ Ponteiros 47

Ponteiros e Vetores (Arrays)

● Considerando a organização hipotética de memória da figura– Verifique o que é obtido comprintf(“%d    %d”, *array_ptr, *(array_ptr+1));

– E com     printf(“%d”,(*array_ptr)+1); ?

char array[5] = {5, 10, 15, 20, 25};char *array_ptr = &array[0];

Page 48: 76091476-ponteiros

ProgC ­ Ponteiros 48

Ponteiros e Vetores (Arrays)

● Programa Exemplo– Definir vetor– Usar ponteiro para acessar cada valor– (No próximo exemplo, será vista a equivalência 

com vetor)

Page 49: 76091476-ponteiros

ProgC ­ Ponteiros 49

Ponteiros e Vetores (Arrays)

● Verifique a saída do programa (pont_vetor2.c)#include <stdio.h>int main (){   int i;   int vetor[3] = {4, 7, 1};   int *ptr;   ptr = vetor;// Em C é igual a ptr = &vetor[0]   printf("Tam. do int nessa plataf.: %d\n\n", sizeof(int));   printf("End. vetor: %p\n", vetor);   printf("End. apontado por ptr: %p\n", ptr);   printf("End. onde está ptr: %p\n", &ptr);   for (i = 0; i < 3; i++)  {      printf("O endereço do índice %d do vetor é %p\n", i, &ptr[i]);      printf("O valor do índice %d do vetor é %d\n", i, ptr[i]);   }   return 0;}

Page 50: 76091476-ponteiros

ProgC ­ Ponteiros 50

Ponteiros e Vetores (Arrays)

● C trata ponteiros e vetores da mesma forma● Assim, são equivalentes (programa anterior)

● Teste cada um deles e confira a equivalência!

vetor[i]; //”acesso” padrão vetorptr[i];

*(vetor + i); //”acesso” padrão ponteiro*(ptr + i);

printf("O valor do índice %d do vetor é %d\n", i, vetor[i]);...printf("O valor do índice %d do vetor é %d\n", i, *(ptr+i));

Page 51: 76091476-ponteiros

ProgC ­ Ponteiros 51

Ponteiros e Vetores (Arrays)

– O programa seguinte verifica quantos elementos estão no vetor antes que apareça um 0

– Não usa ponteiros de forma explícita#include <stdio.h>

int array[] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3};int indice;

int main(){    indice = 0;    while (array[indice] != 0)  {        ++indice;    }    printf("Numero de elementos antes de zero %d\n", indice);    return (0);}

Page 52: 76091476-ponteiros

ProgC ­ Ponteiros 52

Ponteiros e Vetores (Arrays)

● E este é o equivalente, usando ponteiros● Verifique como funciona#include <stdio.h>

int array[] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3};int *array_ptr;

int main(){    array_ptr = array;

    while ((*array_ptr) != 0)  {        ++array_ptr;    }    printf("Numero de elementos antes do zero %d\n", array_ptr ­ array);    return (0);}

Page 53: 76091476-ponteiros

ProgC ­ Ponteiros 53

Exemplo de Uso de Ponteiros

● Suponha que um nome esteja na forma “Silva/Maria”

● Deseja­se separá­lo em duas partes (sobrenome e nome)

Page 54: 76091476-ponteiros

ProgC ­ Ponteiros 54

Exemplo de Uso de Ponteiros

● Como a barra é o separador, temos que procurá­la dentro da string de entrada

while (*string_ptr != caracter_procurar) {

● Dentro do laço, verificar se a string acabou e não encontramos a barra,

   if (*string_ptr == '\0')       return(NULL);   ++string_ptr;}return(string_ptr); //aqui estará a posição do caracter procurado

Page 55: 76091476-ponteiros

ProgC ­ Ponteiros 55

Exemplo de Uso de Ponteiros

● Depois de descobrir a posição da barra, falta separar as strings

Page 56: 76091476-ponteiros

ProgC ­ Ponteiros 56

Exemplo de Uso de Ponteiros

● Função está no arquivo split_nome.c● A função strchr da biblioteca padrão string.h  

faz isso, mas aqui foi usada  uma versão própria para fins didáticos

Page 57: 76091476-ponteiros

ProgC ­ Ponteiros 57

Cuidados no Uso de Ponteiros

● Em C, é fácil escrever código que seja difícil de entender

● Isso deve ser evitado● Nem sempre ter um código compacto é a 

melhor solução● Legibilidade deve ser prioritária

Page 58: 76091476-ponteiros

ProgC ­ Ponteiros 58

Cuidados no Uso de Ponteiros

● Não escreva programas assim (preced1.c)#include <stdio.h>int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int main()  {    int *data_ptr;    int valor;    data_ptr = &array[0];    printf("0. data_ptr aponta = %p\n", data_ptr);    valor = *data_ptr++;    printf("1. valor = %d\n", valor);    printf("1. data_ptr aponta = %p\n", data_ptr);    valor = *++data_ptr;    printf("2. valor = %d\n", valor);    printf("2. data_ptr aponta = %p\n", data_ptr);    valor = ++*data_ptr;    printf("3. valor = %d\n", valor);    printf("3. data_ptr aponta = %p\n", data_ptr);    return(0);}

Page 59: 76091476-ponteiros

ProgC ­ Ponteiros 59

Cuidados no Uso de Ponteiros

Page 60: 76091476-ponteiros

ProgC ­ Ponteiros 60

Cuidados no Uso de Ponteiros

● O resultado depende da precedência dos operadores

● Para ficar mais claro, usar parênteses● Parênteses têm precedência maior● Mas verificar os programas

– preced1­ponteiros.c– preced2­ponteiros.c

Page 61: 76091476-ponteiros

ProgC ­ Ponteiros 61

Cuidados com ponteiros

● Wild pointer: ponteiro não inicializado● aponta para endereço possivelmente inválido

– já vimos exemplos

● Dangling pointer: aponta para memória desalocada– Um dos bugs mais complicados de encontrar

● Porque, em um primeiro momento, o comportamento pode ser ok

– Mais em http://en.wikipedia.org/wiki/Dangling_pointer

Page 62: 76091476-ponteiros

ProgC ­ Ponteiros 62

Cuidados com ponteiros#include <stdio.h>int* funcao(void)  {  int num = 1234;  printf("O endereço de num: %p\n", &num);  printf("O valor de num: %d\n", num);  return &num;}

int main(void)  {  int *ptr;  ptr=funcao();  printf("O endereço apontado por ptr: %p\n", ptr);  printf("O valor apontado por ptr: %d\n", *ptr); // aqui já virou lixo, porque num está fora de escopo  return(0);}

Page 63: 76091476-ponteiros

ProgC ­ Ponteiros 63

Cuidados com ponteiros#include <stdio.h>int main(void)  {  int *ptr;  {    int num=21; //escopo de num é dentro deste bloco    ptr=&num;    printf("O endereço apontado por ptr: %p\n", ptr);    printf("O valor apontado por ptr: %d\n", *ptr);  }  //num saiu de escopo  printf("O endereço apontado por ptr: %p\n", ptr);  printf("O valor apontado por ptr: %d\n", *ptr); // embora possa mostrar um num. ainda válido, é um problema em potencial  return(0);}

Page 64: 76091476-ponteiros

ProgC ­ Ponteiros 64

Cuidados com ponteiros#include <stdio.h>int main(void)  {  char frase[6]="12345";  char *ptr=frase;  printf("caractere[0]=%c\n", *ptr);  ptr++;  printf("caractere[1]=%c\n", *ptr);  ptr+=3;  *ptr='A';   printf("caractere[4]=%c\n", *ptr);  ptr++;  printf("caractere[5]=%x\n", *ptr);//final da string (\0)  ptr++;//saiu da "frase"  *ptr='F';//está acessando endereço fora da string  printf("caractere fora=%c\n", *ptr);  printf("frase=%s\n", frase);  return 0;}

Page 65: 76091476-ponteiros

ProgC ­ Ponteiros 65

SAÍDA DO DEBUGGER (gdb)Breakpoint 1, main () at ponteiro­fora­escopo3.c:33         char frase[6]="12345";4         char *ptr=frase;6         printf("caractere[0]=%c\n", *ptr);(gdb) print &frase$1 = (char (*)[6]) 0xbf99964a(gdb) x/8cb 0xbf99964a0xbf99964a:     49 '1'  50 '2'  51 '3'  52 '4'  53 '5'  0 '\0'  74 'J'  ­106 '\226'7         ptr++;8         printf("caractere[1]=%c\n", *ptr);9         ptr+=3;10        *ptr='A';11        printf("caractere[4]=%c\n", *ptr);12        ptr++;

Page 66: 76091476-ponteiros

ProgC ­ Ponteiros 66

SAÍDA DO DEBUGGER (gdb)   (continuação)13        printf("caractere[5]=%x\n", *ptr);(gdb) x/8cb 0xbf99964a0xbf99964a:     49 '1'  50 '2'  51 '3'  52 '4'  65 'A'  0 '\0'  79 'O'  ­106 '\226'14        ptr++;//saiu da "frase"15        *ptr='F';//está acessando endereço inválido16        printf("caractere fora=%c\n", *ptr);17        printf("frase=%s\n", frase);(gdb) x/8cb 0xbf99964a0xbf99964a:     49 '1'  50 '2'  51 '3'  52 '4'  65 'A'  0 '\0'  70 'F'  ­106 '\226'18        return 0;19      }

Page 67: 76091476-ponteiros

ProgC ­ Ponteiros 67

Cuidados com ponteiros

● Ver discussão emhttp://stackoverflow.com/questions/2583656/what­is­the­meaning­of­wild­pointer­in­c

Page 68: 76091476-ponteiros

ProgC ­ Ponteiros 68

Ponteiros const

● O que está definido como constante em cada declaração?

const int result = 10;

const char *resposta_ptr = "Eletronica";

char *const nome_ptr = "IF­SC";

const char *const teste_ptr = "Florianopolis";

Page 69: 76091476-ponteiros

ProgC ­ Ponteiros 69

Ponteiros const

● O que está definido como constante em cada declaração?

const int result = 10; // result é um inteiro e o valor não pode ser alterado

const char *resposta_ptr = "Eletronica"; // os dados (char) são constantes, mas a variável resposta_ptr, não.//resposta_ptr é um ponteiro que pode apontar para outro endereço.//os dados apontados por resposta_ptr são constantes.

char *const nome_ptr = "IF­SC"; // nome_ptr é um ponteiro que é constante.// os dados apontados por nome_ptr podem ser mudados.

const char *const teste_ptr = "Florianopolis"; //aqui, nem os dados nem o ponteiro podem ser alterados.

Page 70: 76091476-ponteiros

ProgC ­ Ponteiros 70

Bibliografia e Crédito das Figuras

● OUALLINE, S. Practical C Programming. 3. ed. O'Reilly, 1997.

● ARGOUD, F. I. M. Introdução à Linguagem C (notas de aula). Florianópolis, 2009.

● http://home.netcom.com/~tjensen/ptr/pointers.htm

● http://br.geocities.com/cesarakg/pointers.html● http://pt.wikibooks.org/wiki/Programar_em_C/Ponteiros

● http://www.difranco.net/cop2220/op­prec.htm