Buscar

ED_I_Un2_Ponteiros_v4

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Ciência da Computação 
Tecnologia em Análise e Desenvolvimento de 
Sistemas 
Estrutura de Dados I 
INF1014 - CCB1044 
Ponteiros 
SUMÁRIO 
• Organização de Memória 
 
• Definição de Ponteiro 
 
• Declaração e Inicialização 
 
• Operadores de Endereços 
 
• Expressões com Ponteiros 
 
 
• Ponteiros e Vetores 
 
• Ponteiros e Matrizes 
 
• Ponteiros e Estruturas 
 
• Arranjos de Ponteiros 
 
• Ponteiros para Ponteiros 
 
 
 
PONTEIROS 
• Organização de Memória 
– a memória de um computador é formada por uma sequência de bytes 
e cada byte é composto por 8 bits 
 
 
– cada byte pode armazenar 28 = 256 valores inteiros diferentes, que 
variam entre 0 e 255 
– cada byte na memória é identificado por um endereço numérico, 
qualquer que seja o seu conteúdo 
 
bit (binary digit) é a menor unidade de informação que pode 
ser armazenada em um computador 
0000 0001 
0001 1001 
0101 1010 
1111 0101 
1011 0011 
0x0022FF16 
0x0022FF17 
0x0022FF18 
0x0022FF19 
0x0022FF1A 
conteúdo endereço 
PONTEIROS 
• Organização de Memória 
– cada objeto que reside na memória do computador ocupa um certo 
número de bytes, que varia de acordo com o seu tipo, e tem um 
endereço 
– Exemplos 
• char: 1 byte 
• int: 2 bytes 
• float: 4 bytes 
• double: 8 bytes 
 
0110 0001 
 0000 0011 
1110 1000 
0x0022FF14 
0x0022FF15 
conteúdo endereço 
0000 0111 
1101 0000 
char c = ‘a’; 
int[] i = {1000, 2000}; 
o tamanho e a faixa desses tipos de 
dados variam de acordo com o tipo de 
processador e com a implementação do 
compilador C 
PONTEIROS 
• Definição de Ponteiro 
– é uma variável que contém um endereço de memória e esse endereço 
é, normalmente, a posição de outra variável na memória 
– uma variável aponta para outra se a primeira contém o endereço da 
segunda 
 
endereçamento de 32 bits 
(CPUs mais modernas 
utilizam 64 bits) 
 0000 0101 
 0010 1010 
0000 0000 
0x0022FF14 
0x0022FF15 
conteúdo endereço 
0010 0010 
1111 1111 
int x = 1322; 
int *py = &y; 
0001 1011 
0x0022FF16 
0x0022FF17 
0x0022FF18 
0x0022FF19 
0x0022FF1A 
0000 0000 
0010 1010 
0x0022FF1B 
0x0022FF1C 
int y = 42; 
PONTEIROS 
• Definição de Ponteiro 
– há pelo menos 3 razões para o emprego de ponteiros: 
• fornecem meios para que uma função modifique seus argumentos, ou 
seja, permitem que a função retorne mais de um valor 
• dão suporte às rotinas de alocação dinâmica, ou seja, permitem reservar 
posições de memória conforme a necessidade (tempo de execução) e não 
na declaração das variáveis (tempo de compilação) 
• aumentam a eficiência de certas rotinas 
– uma programação bem sucedida em C depende da compreensão e do 
uso correto de ponteiros 
 
PONTEIROS 
• Declaração e Inicialização 
– forma geral para a declaração de uma variável ponteiro 
 
– após a declaração o que se tem é um espaço de memória reservado para 
o armazenamento de endereços e o valor inicial é indefinido 
– assim como as variáveis tradicionais, os ponteiros devem ser inicializados 
antes de serem usados 
– um ponteiro pode ser inicializado com um endereço ou com o valor NULL 
(constante definida em stdio.h) 
 
 
 
 
 
tipo : qualquer tipo válido em C; 
nome : identificador da variável; 
tipo *nome; 
(ex_01) 
0x0022FF14 
0x0022FF15 
conteúdo endereço 
int *px; 
0x0022FF16 
0x0022FF17 
0x0022FF18 
0x0022FF19 
#include <stdio.h> 
void main (void) 
{ 
int *px = NULL; 
px = 0x0022FF19; 
} 
(ex_02) 
PONTEIROS 
• Operadores de Endereço 
– & devolve o endereço de memória do seu operando 
– * devolve o valor do que é apontado pelo seu operando 
(ex_03) 
#include <stdio.h> 
 
int main (void) 
{ 
int *pt_int = NULL; 
int ivalor = 555; 
 
pt_int = &ivalor; 
*pt_int = 333; 
 
printf ("Endereco = %d\n", pt_int); 
printf ("Conteudo = %d\n", *pt_int); 
} 
PONTEIROS 
• Operadores de Endereço 
 
int *a, *b; 
int c = 4, d = 2; 
 
a = &c; 
b = &d; 
*b = 8; 
*a = *b; 
 
*a = 1; 
b = a; 
 
*b = 0; 
PONTEIROS 
• Operadores de Endereço 
 
int *a, *b; 
int c = 4, d = 2; 
 
a = &c; // a apontará para c 
b = &d; // b apontará para d 
*b = 8; // altera o valor de d 
*a = *b; // copia o valor de d (apontado por b) 
 // para c (apontado por a) 
*a = 1; // altera o valor da variável c 
b = a; // b aponta para o mesmo lugar que a, 
 // ou seja, para c 
*b = 0; // altero o valor de c 
PONTEIROS 
• Expressões com Ponteiros 
– Atribuição 
• um ponteiro declarado como sendo de um tipo deve sempre apontar para 
variáveis deste mesmo tipo 
(ex_04) 
é possível atribuir qualquer endereço a uma variável ponteiro, porém, se 
for atribuído o endereço de uma variável que é de um tipo diferente do 
tipo do ponteiro, o programa não funcionará corretamente 
(ex_05) #include <stdio.h> 
int main (void) 
{ 
 int *pt_int = NULL; 
 float fvalor = 2.5; 
 pt_int = &fvalor; 
 
 printf ("Conteudo fvalor = %f\n", fvalor); 
 printf ("Conteudo *pt_int = %d\n", *pt_int); 
 
} 
Resultado: 
Conteudo fvalor = 2.500000 
Conteudo *pt_int = 1075838976 
Funcionamento incorreto. 
Conteúdo *pt_int não corrresponde ao 
valor atribuido a fvalor. 
PONTEIROS 
• Expressões com Ponteiros 
– Incremento e Decremento 
• ++ o ponteiro armazena o endereço de memória do elemento seguinte do 
seu tipo base 
• -- o ponteiro armazena o endereço de memória do elemento anterior do 
seu tipo base 
• forma geral para o incremento e o decremento de ponteiros 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
(ex_06) 
nome: identificador da variável ponteiro; nome++; 
nome--; 
#include <stdio.h> 
int main (void) { 
 int *pt_int; 
 int ivalor = 555; 
 char *pt_char; 
 char cvalor = 'S'; 
 pt_int = &ivalor; 
 pt_char = &cvalor; 
 
 printf ("pt_int = %d\t pt_char = %d\t \n", pt_int, pt_char); 
 pt_int++; //somando uma unidade (4 bytes) na memória 
 pt_char++; //somando uma unidade (1 byte) na memória 
 printf ("pt_int = %d\t pt_char = %d\t \n", pt_int, pt_char); 
} 
Resultado: 
pt_int = 2293524 pt_char = 2293523 
pt_int = 2293528 pt_char = 2293524 
PONTEIROS 
• Expressões com Ponteiros 
– Adição e Subtração de Inteiros 
• ponteiros admitem a adição e a subtração de qualquer valor inteiro 
 
(ex_07) 
nome: identificador da variável ponteiro; 
valor: constante ou variável do tipo int; 
nome = nome + valor; 
nome = nome – valor; 
apenas a adição e a subtração podem ser usadas com ponteiros 
toda aritmética de ponteiros é relativa a seu tipo base 
char *pt_ch = 0xE0; 
int *pt_i = 0xE0; 
0xE0 
0xE1 
0xE2 
0xE3 
0xE4 
0xE5 
pt_ch 
pt_ch+1 
pt_ch+2 
pt_ch+3 
pt_ch+4 
pt_ch+5 
pt_i 
pt_i+1 
pt_i+2 
Por simplificação, o exemplo usa 
endereçamento de 8 bits e inteiros de 2 
bytes 
PONTEIROS 
• Expressões com Ponteiros 
– Comparação 
• é possível comparar ponteiros em uma expressão relacional, mas a 
comparação é restrita a ponteiros do mesmo tipo 
• forma geral para a comparação de ponteiros 
 
 
 
 
 
– Não é válido: 
• somar ponteiros (pi + pf) 
• multiplicar ou dividir ponteiros (pi*pf, pi/pf) 
• operar ponteiros com double ou float (pi ± 2.0) 
 
nomei : identificador da variável ponteiro i; 
op : operador relacional (<, <=,>, >=, ==, !=); 
if (nome1 op nome2) 
 ... 
PONTEIROS 
• Expressões com Ponteiros 
– Exemplo - Jogo da sequência inversa 
 
 
 
(ex_08) 
#include <stdio.h> 
#include <stdlib.h> 
#define SIZE 50 
void push(int i); 
int pop(void); 
int *tos, *p1, stack[SIZE]; 
int main(void) 
{ 
 int value; 
 tos = stack; //tos mantem end inicial 
 p1 = stack; // p1 aponta para topo 
 do { 
 printf("Entre com o valor: "); 
 scanf("%d", &value); 
 if(value!=0) 
push(value); 
 else 
printf(“Valor do topo‚ %d\n", 
pop()); 
 } while(value!=-1); 
} 
void push(int i) 
{ 
 p1++; 
 if(p1 ==(tos+SIZE)) 
 { 
 printf("estouro da pilha"); 
 exit(1); 
 } 
 *p1 = i; 
} 
 
int pop(void) 
{ 
 if(p1 == tos) 
 { 
 printf("pilha vazia"); 
 exit(1); 
 } 
 p1--; 
 return *(p1+1); 
} 
 
PONTEIROS 
• Ponteiros e Vetores 
– Existe uma associação forte entre vetores e ponteiros, pois se existe a 
declaração: 
int v[10]; 
o símbolo v, que representa o vetor, é uma constante que representa 
seu endereço inicial, isto é, v, sem indexação, é um ponteiro constante 
que aponta para o primeiro elemento do vetor. 
– sendo uma constante, o nome de um vetor não pode ter o seu valor 
alterado; são inválidas as operações abaixo. 
 
(ex_09) 
int main(){ 
 int list[5], i; 
 
 // erro : o ponteiro list não pode ser modificado 
 list = &i; 
 
 // erro: o ponteiro list nao pode ser incrementado 
 list++; 
} 
PONTEIROS 
• Ponteiros e Vetores 
– o conteúdo de um vetor pode ser acessado por meio do operador * e de 
aritmética de ponteiros 
– por exemplo, se p representa o ponteiro para um inteiro, p+1 representa 
um ponteiro para o próximo inteiro armazenado na memória. 
– portanto, escrever &v[i] é equivalente a escrever (v+i). E escrever v[i] 
é equivalente a escrever *(v+i). 
 
 
 
 
 
 
 
 
1 int main(void) 
2 { 
3 int v[2]; 
4 int *p; 
5 p = v; 
6 p = p + 1; 
7 *p = 5; 
8 return 0; 
9 } 
Por simplificação, o exemplo usa 
endereçamento de 8 bits e inteiros de 2 bytes 
v[0] 
v[1] 
v 
p 
00000000 
00000000 
00000000 
conteúdo em 5 
00000000 
0xE0 
0xE0 
0xE0 
endereço 
0xE1 
0xE2 
0xE3 
0xE5 
0xE4 
00000000 
00000000 
00000000 
conteúdo em 6 
00000000 
0xE0 
0xE2 
00000000 
00000000 
00000101 
conteúdo em 7 
00000000 
0xE0 
0xE2 
(ex_10) 
PONTEIROS 
• Ponteiros e Vetores 
– o conteúdo de um vetor também pode ser acessado por meio de 
indexação de ponteiro 
 
 
 
 
 
 
– há uma diferença importante entre declarar um conjunto de dados 
como vetor ou como ponteiro 
• vetor: o compilador reserva automaticamente um bloco de memória para 
o armazenamento do arranjo 
• ponteiro: o compilador aloca um ponteiro para apontar para a memória, 
sem que o espaço seja reservado 
int main(void) 
{ 
 int v[10]; 
 int *p; 
 p = v; 
 p[5] = 100; 
 return 0; 
} 
PONTEIROS 
• Ponteiros e Matrizes 
– assim como em um vetor, o conteúdo de um arranjo multidimensional 
(matriz) também pode ser acessado por meio do operador * 
– é necessário mapear o espaço multidimensional em apenas uma 
dimensão 
– em matrizes bidimensionais é necessário mapear o endereço de cada 
elemento, indexado por um par [i] [j], em um endereço linear 
– forma geral para o mapeamento 
 
(ex_11) 
nome: identificador do ponteiro; 
COL: número de colunas da matriz 
nome + (i * COL + j) 
00 01 02 
10 11 12 
00 
01 
02 
10 
11 
12 
int M[2][3] 
 
linha 0 
linha 1 
PONTEIROS 
• Ponteiros e Matrizes 
– lembre-se que ponteiros podem ser utilizados para acessar elementos de um vetor 
usando indexação de ponteiro 
 
 
 
 
 
 
 
 
– fazendo: 
p = M[2] ; //equivale a p = &M[2][0] 
então, p[0] é o elemento M[2][0], p[1] é o elemento M[2][1],e assim por diante. 
– mas a construção p[i][j] não é válida e a atribuição abaixo não é aconselhável, pois 
a linguagem C permite que um ponteiro seja utilizado apenas com uma dimensão 
p = M; //cuidado! P[i][j] é incorreto 
int M[3][4]; 
 
//inicializa os elementos da linha i de M com o conteudo c 
int init(int i, int c) 
{ 
 int *p; int j; 
 p = M[i]; // p aponta para o 1o elemento da linha i de M; 
 // equivale a fazer p = &M[i][0] 
 for (j=0; j<4; j++) 
 p[j] = c; // equivale a fazer M[i][j] = c 
} 
PONTEIROS 
• Ponteiros e Matrizes 
– uma matriz também não pode ser considerada um ponteiro para 
ponteiro, também devido a sua estrutura particular onde cada linha é 
seguida imediatamente por outra. 
– assim, a atribuição no pedaço de código abaixo também não é válida. 
 
int **p ; 
int M[3][4]; 
p = M ; //incorreto, M não é ponteiro para ponteiro 
PONTEIROS 
• Ponteiros e Matrizes 
– a principal vantagem de se utilizar o endereçamento linear com ponteiro para 
varrer uma matriz é que essa é uma forma mais eficiente do que o endereçamento 
indexado por um par [i] [j]. 
– exemplo 
 
 
 
 
 
 
 
 
 
 
– cada vez que se faz matrx[i][j], o programa tem que calcular o 
deslocamento para adicionar ao endereço inicial , totalizando 2500 cálculos. 
– no segundo programa, o único cálculo que deve ser feito é o de um incremento de 
ponteiro. 
// Com acesso indexado 
void main () 
{ 
float matrx[50][50]; 
int i,j; 
for (i=0;i<50;i++) 
for (j=0;j<50;j++) 
matrx[i][j]=0.0; 
} 
 
 
 
 
//Com endereçamento linear 
void main () 
{ 
float matrx [50][50]; 
float *p; 
int count; 
p = matrx[0]; 
for (count=0;count<2500;count++) 
{ 
*p=0.0; 
p++; 
} 
} 
PONTEIROS 
• Ponteiros e Estruturas 
– para definir ponteiros para estruturas a declaração é similar a 
declaração de um ponteiro normal 
 
 
 
 
– ponteiros para estruturas são úteis quando é necessário passa-las 
para funções 
– ao passar apenas o ponteiro, economiza-se tempo e memória, pois: 
• se evita copiar os dados que compõem a estrutura um por um; 
• não é necessário gastar o tempo de empilhar e desempilhar todos os 
elementos da estrutura no processo de passagem para a função. 
– para acessar elementos da estrutura apontada por um ponteiro usa-se 
o chamado operador seta (->) 
 
 
struct aluno 
{ 
char nome [40]; 
int ano_entrada ; 
float n1 , n2 , media; 
} * maria; 
printf ("A media vale %.1 f", maria -> media ); 
PONTEIROS 
• Arranjos de Ponteiros 
– ponteiros podem ser organizados em arranjos como qualquer outro 
tipo de dado 
 
(ex_12) 
tipo *nome[]; 
tipo: qualquer tipo válido em C; 
nome: identificador da variável; 
#include <stdio.h> 
#include <stdlib .h> 
#define LINHAS 5 
#define COLUNAS 10 
 
int main (void) 
{ 
 char *linha[LINHAS]; 
 char cadeia[COLUNAS]; int i; 
 
 for (i = 0; i < LINHAS ; i++){ 
 linha[i] = cadeia; //todas apontam para o mesmo string 
 } 
 for (i = 0; i < LINHAS ; i++){ 
 printf ("Entre com a linha %d.\n", i); 
 gets (linha[i]); //cadeia será sobrescrita 
 } 
 for (i = 0; i < LINHAS ; i++){ 
 printf (" Linha %d %s.\n", i, linha[i]); 
 } 
 return 0; 
endereço 
endereço 
PONTEIROS 
• Ponteiros para Ponteiros 
– um ponteiro pode apontar para outro que aponta para o valor final 
– forma geral para a declaração de um ponteiro para ponteiro 
 tipo **nome; tipo: qualquer tipo válido em C; 
nome: identificador da variável; 
ponteiro variável 
valorendereço valor 
ponteiro ponteiro variável 
(ex_13) 
ponteiro simples 
ponteiro para ponteiro 
ponteiros podem apontar para ponteiros indefinidamente, mas 
raramente é necessário mais de um ponteiro para um ponteiro 
 
 
 
 
 
FIM

Outros materiais