Você está na página 1de 36

Preparatório EsAEx

TÉCNICAS DE PROGRAMAÇÃO
Ponteiros em C
Prof. Ricardo Sant'Ana
Sumário

1 Introdução

2 Conceitos de Ponteiros

3 Conclusão
Introdução
Lista de Assuntos
 2. TÉCNICAS DE PROGRAMAÇÃO:
• a. Lógica aplicada: algoritmos, técnicas de construção de
algoritmos, resolução de problemas;
• b. Estrutura de dados: vetores, matrizes, cadeia de caracteres,
listas lineares, pilhas, filas, árvores, grafos, pesquisa de dados,
classificação de dados, estruturas e tipos abstratos de dados,
recursividade, eficiência e complexidade;
• c. Programação estruturada: refinamentos sucessivos, estruturas
em blocos, estruturas de controle de fluxo, programação modular,
rotinas, subrotinas, procedimentos e funções (Linguagem C);
• d. Programação orientada a objetos: classes e objetos,
polimorfismo, herança, interface, linguagens orientadas a objetos
(Linguagens C++ e Java);
• e. Linguagens de programação para a Internet: PHP e JSP.
Introdução
Bibliografia
 COSTA, Daniel G. JAVA em Rede: Recursos Avançados. Rio de Janeiro:
Brasport, 2008.
 DEITEL, H. M. JAVA Como Programar. 6. ed. [S.l.]: Editora Bookman, 2006.
 GAMMA, Erich et al. Padrões de Projeto: Soluções Reutilizáveis de Software
Orientado a Objetos. [S.l.]: Bookman, 2005.
 GUIMARÃES, Ângelo de Moura; LAGES, Newton de Castilho. Algoritmos
Estruturados de Dados. [S.l.]: Editora LTC, 1994.
 MORGAN, Michael. JAVA 2 para Programadores Profissionais. [S.l.]: Editora
Ciência Moderna, 2001.
 MUTO, Claudio Adonai. PHP & MYSQL Guia Completo. [S.l.]: Brasport, 2004.
 TENENBAUM, Aaron M.; LANGSAM, Yedidyah; AUGENSTEIN, Moshe J.
Estruturas de Dados Usando C. [S.l.]: Makron Books, 1995.
 VELOSO, Paulo et al. Estrutura de Dados. [S.l.]: Editora Campus, 1983.
 WIRTH, Niklaus. Algorítmos e Estruturados de Dados. [S.l.]: Editora PHB, 1989.
Introdução
Foco (baseado em questões)
 Programação Orientada a Objetos em Java
 Ponteiros em C
• 01 questão em 2010
• questões de lógica em C em 2009
 Árvores e Pilhas (Estrutura da Dados)

Teoria e Exercícios
 Exige um conhecimento prévio!
Conceitos
Ponteiros
 Um ponteiro é simplesmente uma variável
que armazena o endereço de outra variável.
• Em outras palavras, um ponteiro aponta para algo.
• Em programação, temos as variáveis
armazenadas na memória, e um ponteiro aponta
para um endereço de memória.
Conceitos
Declarando e acessando ponteiros
 Um ponteiro, como qualquer variável, deve
ter um tipo, que é o tipo da variável para a
qual ele aponta.
 Para declarar um ponteiro, especificamos o
tipo da variável para a qual ele aponta e seu
nome precedido por asterisco:
int idade ;
int *ponteiro ;
Conceitos
Exemplo
int a=1234;
int *p;
p = &a;

 Na figura temos uma representação da


situaçao após o código acima.
 Um opção era: int *p = &a;

Conceitos
Exemplo
#include <stdio.h>
int main()
{
int i = 10 ;
int *p ;
p = &i ;
*p = 5 ;
printf ("%d\t%d\t%p\n", i, *p, p);
return 0;
}

 Resultado (exemplo):
• 5 5 0022FF74
Conceitos
Exemplo
#include <stdio.h>
int main()
{
int i = 10 ;
a
int *p ;
p = &i ; End #2010

*p = 5 ; int
printf ("%d\t%d\t%p\n", i, *p, p);
10
return 0;
}

 Criamos a variável a com o valor 10 na memória (no endereço


2010)
Conceitos
Exemplo
#include <stdio.h>
int main()
{
int i = 10 ;
a p
int *p ;
p = &i ; End #2010 End #5072

*p = 5 ; int ponteiro
para int
printf ("%d\t%d\t%p\n", i, *p, p);
10
return 0;
}

 Criamos o ponteiro para inteiros p no endereço 5072. O


valor dele ainda é indefinido.
Conceitos
Exemplo
#include <stdio.h>
int main()
{
int i = 10 ;
a p
int *p ;
p = &i ; End #2010 End #5072

*p = 5 ; int ponteiro
para int
printf ("%d\t%d\t%p\n", i, *p, p);
10 #2010
return 0;
}

 O valor do ponteiro p é o endereço de a (&-> endereço).


Portanto, o valor 2010 é armazenado em p.
Conceitos
Exemplo
#include <stdio.h>
int main()
{
int i = 10 ;
a p
int *p ;
p = &i ; End #2010 End #5072

*p = 5 ; int ponteiro
para int
printf ("%d\t%d\t%p\n", i, *p, p);
5 #2010
return 0;
}

 O valor para onde p aponta (que é um inteiro e se


encontra no endereço 2010) é 5. Assim, o valor que era
10 é atualizado para 5.
Conceitos
Exemplo (cont)
#define null ( (char*) 0 )
int main(void){
int a = 5;
int *p = null;
*p = a;
}
 O código acima está errado. O endereço para o qual o ponteiro
p aponta é null. Não é possível, portanto, fazer com que *p =a –
ou seja – colocar o valor de a no endereço null !
Conceitos
Para os próximos exemplos, considerar
a memória no seguinte estado
p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 7.8 5.7
Conceitos
p1 = p2. Figura antes e depois

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 7.8 5.7

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 7.8 5.7
Conceitos
Operações
 Supondo dois ponteiros p1 e p2:
 p1 = p2;
• Esse primeiro exemplo fará com que p1 aponte
para o mesmo lugar que p2. Ou seja, usar p1 será
equivalente a usar p2 após essa atribuição.

 Ver figura a seguir


Conceitos
 p1 = p2. Figura antes e depois. Agora p1 e p2
“apontam” para b.

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 7.8 5.7

p1 p2 a b
End #5072 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2010 #2010 7.8 5.7
Conceitos
Operações
 Supondo dois ponteiros p1 e p2:
 *p1 = *p2;
• Nesse segundo caso, estamos igualando os
valores apontados pelos dois ponteiros:
alteraremos o valor apontado por p1 para o valor
apontado por p2.
 Ver figura a segur
Conceitos
 *p1 = *p2. Figura antes e depois. O valor de a
é atualizado para o valor de b.

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 7.8 5.7

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para float
ponteiro
para float
float float
#2024 #2010 5.7 5.7
Conceitos
Operações (cont)
 p1++;
• Aqui estamos incrementando o ponteiro. Quando
incrementamos um ponteiro ele passa a apontar
para o próximo valor do mesmo tipo em relação
ao valor para o qual o ponteiro aponta.
• Pode ser utilizado em vetores!
• O valor incrementado depende do tipo do ponteiro
(int, float, char)
Conceitos
Operações
 (*p1)++;
• Aqui, colocamos *p1 entre parênteses para
especificar que queremos alterar o valor apontado
por p1. Ou seja, aqui iremos incrementar o
conteúdo da variável apontada pelo ponteiro p1.
Conceitos
 (*p1)++. Figura antes e depois. Agora p1 é
incrementado·

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para int
ponteiro
para int
int int
#2024 #2010 6 8

p1 p2 a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para int
ponteiro
para int
int int
#2024 #2010 7 8
Conceitos
Operações
 *p1++
• Neste caso, o efeito não é tão claro quanto nos
outros exemplos. A precedência do operador ++
sobre o operador * faz com que a expressão seja
equivalente a *(p1++).
• Neste caso, incrementamos o endereço de p e o
valor desse novo endereço é retornado.
– Se o não for um vetor (sequência de valores na
memória, o resultado da expressão acima geralmente é
lixo da memória.
• Exemplo com vetor.
Conceitos
Operações
 x = *(p1 + 7);
 Esta linha atribui a uma variável x o conteúdo
do sétimo inteiro a partir daquele apontado
por p1.
 Por exemplo, suponhamos que tivéssemos
uma série de variáveis i0, i1, i2, … i7, i8, i9 e
que p1 apontasse para i0. Nossa variável x
receberia o valor de i7.
Conceitos
Passagem de
parâmetros int main()
#include <stdio.h> {
void swap(int i, int j) int a, b;
{ a = 5;
int temp; b = 10;
printf ("%d %d\n", a, b);
temp = i;
swap (a, b);
i = j; printf ("%d %d\n", a, b);
j = temp; return 0;
} }
Conceitos
 Neste caso, ao chamar a função swap,
internamento temos:
 i=a
 j=b
 A situação final está apresentada a seguir.
Portanto, temos uma cópia dos valores em i e j.

i j a b
End #3074 End #3200 End #2024 End #2010

int int int int


5 10 5 10
Conceitos
Passagem de
parâmetros int main ()
#include <stdio.h> {
void swap (int *i, int *j) int a, b;
{ a = 5;
int temp; b = 10;
printf ("\n %d,%d\n", a, b);
temp = *i;
swap (&a, &b);
*i = *j; printf ("\n %d, %d\n", a, b);
*j = temp; return 0;
} }
Conceitos
 Neste exemplo, a função swap recebe – por
meios dos ponteiros a e b o endereço de a e b:
 i = &a;
 J = &b;
 A situação final é apresentada a seguir

i j a b
End #5086 End #5072 End #2024 End #2010

ponteiro
para int
ponteiro
para int
int int
#2024 #2010 5 10
Conceitos
Passagem de Parâmetros
 Quando uma função recebe como
parâmetros os endereços e não os valores
das variáveis, dizemos que estamos fazendo
uma chamada por referência;
referência
 Quando passamos diretamente os valores
das variáveis para uma função, dizemos que
é uma chamada por valor;
valor
Conceitos
Ponteiros e Vetores
 podemos usar ponteiros e a aritmética de
ponteiros para percorrer vetores.
int main () {
int i;
int vetorTeste[3] = {4, 7, 1};
int *ptr = vetorTeste;
for (i = 0; i < 3; i++)
{
printf("O valor do índice %d do vetor é %d\n", i, ptr[i]);
printf("O valor do índice %d do vetor é %d\n", i, *(ptr+i));
}
return 0;
}
Conceitos
Ponteiros para Ponteiros
char a;
char *b;
char **c;
a = 'z';
b = &a;
c = &b;
**c = 'M';
 Perceba que temos dois "níveis": c aponta para b, e b aponta
para a.
 Assim, para acessar a usando o ponteiro c, é necessário usar
duas vezes o operador *: uma para obter o valor de b (cujo
endereço está guardado em c), e a outra para obter o valor de
a, apontado por b.
Conceitos
Exercício
int main(){
int *a, **b;
int c[] = {10,50,70,30};
a=&c[1];
++a;
b=&a;
printf(“%d \n”,**b);
}.
Conclusão
 Perguntas ?
Conclusão

“Algo só é impossível até que alguém


duvida e resolve provar o contrário.”
Albert Einstein
Prof. Ricardo Sant'Ana

Você também pode gostar