ponteiros - feg.unesp.br · em se tratando de ponteiros, os sinais aritméticos +e – servem como...
TRANSCRIPT
Ponteiros | Introdução à Computação 1 de 172014 © MdaS
PonteirosPonteirosPonteirosPonteiros
� Considere um carteiro recém-chegado na vila
� Na vila, a referência para se encontrar a casa é pelo
morador
Ponteiros | Introdução à Computação 2 de 172014 © MdaS
PonteirosPonteirosPonteirosPonteiros
� No entanto, as cartas são direcionadas de acordo com
o endereço das casas
Ponteiros | Introdução à Computação 3 de 172014 © MdaS
PonteirosPonteirosPonteirosPonteiros
� Em C, os dados (representados pelas variáveis) não
são representados na memória pelo seu nome
� Esta tarefa é realizada apenas na programação
� Na memória, os dados são armazenados em função
dos seus respectivos endereços
� A variável ocupa um espaço endereçável da memória a
partir do momento em que ela é declarada
Ponteiros | Introdução à Computação 4 de 172014 © MdaS
EndereEndereEndereEndereççççosososos
� Para saber o endereço de memória
onde a variável está alocada, utiliza--se a expressão %X em meio ao printf
� Note que a variável é precedida por um &
� Este caractere significa que está
sendo referenciado o endereendereendereendereççççoooo da
variável na memória
� Por isso que ele é utilizado no scanf...
printf("Posicao da variavel %X: ", &x);
GATA, EU NÃO SOU CARTEIRO, MAS VIM TE DAR UM SELINHO. BOA NOITE!
Ponteiros | Introdução à Computação 5 de 172014 © MdaS
PonteirosPonteirosPonteirosPonteiros
� Algumas variáveis são utilizadas para armazenar o
endereço de memória de algumas informações
� Estas variáveis são conhecidas como ponteirosponteirosponteirosponteiros
� Em suas declarações, são precedidas por um *
int *a;
float *x;
char *c;
cliente *ender;
Ponteiros | Introdução à Computação 6 de 172014 © MdaS
PonteirosPonteirosPonteirosPonteiros
� Em suma, o ponteiro serve para armazenar o endereço
de memória de um determinado valor
� Cada ponteiro deve possuir o * ao ser declarado
� O elemento neutro de um ponteiro é o NULL
float x = 5.0;
float *y;
y = &x;
5.0x 0D5 0D5y 0A4
Ponteiros | Introdução à Computação 7 de 172014 © MdaS
Tipos de ReferênciaTipos de ReferênciaTipos de ReferênciaTipos de Referência
� Referência diretaReferência diretaReferência diretaReferência direta – o acesso à memória é feito por meio
da variável associada ao endereço
a = 500;
printf("Valor de a: %d\n", a);
printf("Endereco de a: %p\n", &a);
a++;
printf("%d" ,a);
Ponteiros | Introdução à Computação 8 de 172014 © MdaS
Tipos de ReferênciaTipos de ReferênciaTipos de ReferênciaTipos de Referência
� Referência indiretaReferência indiretaReferência indiretaReferência indireta – o acesso à memória é feito através
do ponteiro associado ao endereço
*pa = 500;
printf("Valor de a: %d\n", *pa);
printf("Endereco de a: %p\n", pa);
*pa++;
printf("%d", *pa);
Ponteiros | Introdução à Computação 9 de 172014 © MdaS
Deslocamento de um ponteiroDeslocamento de um ponteiroDeslocamento de um ponteiroDeslocamento de um ponteiro
� Em se tratando de ponteiros, os sinais aritméticos + e –
servem como deslocadores dos endereços de memória
� Têm como finalidade modificar a direção dos ponteiros
para posições posteriores e anteriores da memória,
respectivamente
� O mesmo pode ser aplicado à índices de vetores
char s[80], *ps, c;
ps = s; // equivalente à ps = &s[0];
//Atribui o elemento da posição 6 da string s à variável c
c = s[6]; // indexação de vetores, ou
c = *(ps + 6); // aritmética de ponteiros
Ponteiros | Introdução à Computação 10 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� Em C, variáveis e constantes devem ser declaradas
antes de serem utilizadas
� Se forem vetores ou matrizes, o número máximo já
deve ser pré-determinado (alocação estática)
� Porém, ponteiros permitem que este número possa ser
estabelecido durante a execução do programa
(alocação dinâmica)
Ponteiros | Introdução à Computação 11 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� Algumas funções são utilizadas para a alocação
dinâmica de memória
� sizeof(valor): comprimento em bytes de um dado
� calloc(num, tam): faz a alocação dinâmica, onde:
� num: número de elementos do vetor
� tam: tamanho em bytes de cada elemento
� free(variavel): libera da memória o espaço ocupado pela
variável
� Antes da função calloc(), deve ser colocado entre
parênteses o tipo estruturado do dado juntamente com
o ponteiro
Ponteiros | Introdução à Computação 12 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� Exemplo de uma alocação dinâmica de um vetor de
inteiros de dimensão n:
int *x;
int n, i;
printf("Tamanho do vetor: ");
scanf("%d", &n);
x = (int *) calloc(n, sizeof(int));
puts("Informe os elementos do vetor x:");
for (i = 0; i < n; i++)
scanf("%d", &x[i]);
...
free(x);
Ponteiros | Introdução à Computação 13 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� No caso de uma matriz, a alocação deve ser feita em
duas etapas
int **Y;
int m, n, i;
printf("Numero de linhas: ");
scanf("%d", &m);
Y = (int **) calloc(m, sizeof(int *));
printf("Numero de colunas: ");
scanf("%d", &n);
for (i = 0; i < m; i++)
Y[i] = (int *) calloc(n, sizeof(int));
Ponteiros | Introdução à Computação 14 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� Para a liberação da variável da memória, utiliza-se a função free():
� A liberação pode ser feita vetor a vetor
� Em se tratando de strings, a alocação dinâmica é bem
mais simples...
for (i = 0; i < m; i++)
free(Y[i]);
free(Y);
char *nome;
puts("Entre com seu nome: ");
gets(nome);
printf("Seu nome: %s\n", nome);
Ponteiros | Introdução à Computação 15 de 172014 © MdaS
AlocaAlocaAlocaAlocaçççção Dinâmica de Memão Dinâmica de Memão Dinâmica de Memão Dinâmica de Memóóóóriariariaria
� Em algumas situações, é necessário que seja feita a
verificação da alocação de memória
� Um exemplo de verificação é dado da seguinte
maneira:
� Neste caso, se não ocorre a alocação de memória, a
mensagem aparecerá
� Pode ser colocados comandos para, por exemplo, encerrar o programa, caso seja necessário
if (p == NULL)
puts("Memoria nao alocada para p!");
Ponteiros | Introdução à Computação 16 de 172014 © MdaS
ExercExercExercExercíííícioscioscioscios
1. Escreva um programa em C que calcule a soma de
dois vetores de tamanho n alocados dinamicamente
2. Reescreva em um programa C o seguinte trecho de
código e responda (Pereira, 2010)
a) Qual a saída fornecida pelo programa?
b) Se os &’s fossem omitidos, qual seria a saída do programa?
char c, *pc;
int i, *pi;
double x, *px;
pc = &c;
printf("Tam. c: %dB\tEndereco c: %p\t Prox. endereco: %p\n", sizeof(c), pc, pc+1);
pi = &i;
printf("Tam. i: %dB\tEndereco i: %p\t Prox. endereco: %p\n", sizeof(i), pi, pi+1);
px = &x;
printf("Tam. x: %dB\tEndereco x: %p\t Prox. endereco: %p\n", sizeof(x), px, px+1);