ponteiros - feg.unesp.br · em se tratando de ponteiros, os sinais aritméticos +e – servem como...

16
Ponteiros | Introdução à Computação 1 de 17 2014 © MdaS Ponteiros Ponteiros Ponteiros Ponteiros Considere um carteiro recém-chegado na vila Na vila, a referência para se encontrar a casa é pelo morador

Upload: hadan

Post on 14-Nov-2018

215 views

Category:

Documents


0 download

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);