SlideShare uma empresa Scribd logo
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Ponteiros
Ponteiros ou apontadores (em inglês pointers) são variáveis cujo conteúdo é um endereço.
Já vimos que variáveis são posições na memória que podem conter um determinado valor
dependendo de seu tipo (char, int, float, double, etc . . .). Assim, uma
variável do tipo ponteiro contém valores que são na verdade endereços para outras posições
de memória. Os nomes apontador, ponteiro ou pointer são utilizados com o mesmo
significado.
Como declarar um ponteiro
Uma variável tipo ponteiro, “aponta” para uma variável de um determinado tipo conhecido
(char, int, float, double, etc.), ou seja, contém um endereço de uma variável
de um determinado tipo. Assim é necessário na declaração de um ponteiro, especificar para
qual tipo de variável ele irá apontar. O operador * indica que a variável é um apontador.
int *pi ; /* ponteiro para int */
char *pc; /* ponteiro para char */
float *pf; /* ponteiro para float */
double *pd; /* ponteiro para double */
Uso de ponteiro
O operador & significa “endereço de”.
int a;
char b;
pi = &a; /* pi fica com o endereço de a */
pc = &b; /* pc fica com o endereço de c */
/* Os dois comandos abaixo são equivalentes */
a = 45;
*pi = 45;
/* idem para */
b = ‘a’; e
*pc = ‘a’;
Veja o programa abaixo e o que ele imprime no vídeo. O formato p é um formato para
imprimir o conteúdo de um ponteiro, ou seja, um endereço.
#include <stdio.h>
#include <stdlib.h>
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

int main() {
int a, *pa;
double b, *pb;
char c, *pc;
/* atribuições de endereços */
pa = &a; pb = &b; pc = &c;
/* atribuição de valores */
a = 1; b = 2.34; c = '@';
printf("n valores:%5d %5.2lf %c", a, b, c);
printf("n ponteiros:%5d %5.2lf %c", *pa, *pb, *pc);
printf("n enderecos:%p %p %p", pa, pb, pc);
/* mais atribuições de valores usando os ponteiros */
*pa = 77; *pb = 0.33; *pc = '#';
printf("n valores :%5d %5.2lf %c", a, b, c);
printf("n ponteiros:%5d %5.2lf %c", *pa, *pb, *pc);
printf("n enderecos:%p %p %p", pa, pb, pc);
system (“pause”); return 0;
}
valores:
1
2.34 @
ponteiros:
1
2.34 @
enderecos:0063FDDC 0063FDD4
valores :
77
0.33 #
ponteiros:
77
0.33 #
enderecos:0063FDDC 0063FDD4

0063FDD3
0063FDD3

Um pouco sobre a memória e endereços
O formato %p mostra o endereço. Os endereços são dependentes do particular computador
e do particular compilador. Também depende do lugar em que o programa está carregado
na memória. Assim um mesmo programa pode ocupar posições diferentes de memória em
duas execuções diferentes. O mesmo pode ter suas variáveis alocadas em lugares diferentes
se for compilado com diferentes compiladores. No exemplo acima estamos usando um
computador com processador INTEL onde os endereços possuem 2 partes: número do
segmento e deslocamento dentro do segmento. As variáveis possuem os seguintes
endereços (em hexadecimal):
a – 0063 FDDC (4 bytes FDDC a FDDF)
b – 0063 FDD4 (4 bytes FDD4 a FDD7)
c – 0063 FDD3 (1 byte FDD3)
Veja outro exemplo de alocação de endereços na memória:
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

#include <stdio.h>
#include <stdlib.h>
int main() {
int a, aa;
double b, bb;
char c, cc;
int vi[5];
double vd[5];
char vc[5];
int i;
printf("n endereco de a = %p endereco de aa = %p", &a, &aa);
printf("n endereco de b = %p endereco de bb = %p", &b, &bb);
printf("n endereco de c = %p endereco de cc = %p", &c, &cc);
for (i = 0; i < 5; i++)
printf("n endereco de vi[%1d] = %p", i, &vi[i]);
for (i = 0; i < 5; i++)
printf("n endereco de vd[%1d] = %p", i, &vd[i]);
for (i = 0; i < 5; i++)
printf("n endereco de vc[%1d] = %p", i, &vc[i]);
printf("n endereco de vi = %pn endereco de vd = %pn endereco de vc =
%p", vi, vd, vc);
system(“pause”); return 0;
}

endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco
endereco

de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de
de

a = 0063FDA0 endereco de aa = 0063FD9C
b = 0063FD94 endereco de bb = 0063FD8C
c = 0063FD8B endereco de cc = 0063FD8A
vi[0] = 0063FDD4
vi[1] = 0063FDD8
vi[2] = 0063FDDC
vi[3] = 0063FDE0
vi[4] = 0063FDE4
vd[0] = 0063FDAC
vd[1] = 0063FDB4
vd[2] = 0063FDBC
vd[3] = 0063FDC4
vd[4] = 0063FDCC
vc[0] = 0063FDA7
vc[1] = 0063FDA8
vc[2] = 0063FDA9
vc[3] = 0063FDAA
vc[4] = 0063FDAB
vi = 0063FDD4
vd = 0063FDAC
vc = 0063FDA7

Qual o endereço do ponteiro?

Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

Ponteiros também são variáveis, portanto ocupam posições na memória. Veja o programa
abaixo que mostra o endereço das variáveis e dos ponteiros.
#include <stdio.h>
#include <stdlib.h>
int main() {
int a, *pa;
double b, *pb;
char c, *pc;
/* atribuições de endereços */
pa = &a; pb = &b; pc = &c;
/* mostra o endereço das variáveis */
printf("nn enderecos de a, b e c:%p

%p

%p", pa, pb, pc);

/* mostra o endereço das variáveis de outra forma */
printf("nn enderecos de a, b e c (outra forma):%p %p
&c);
/* mostra o endereço dos ponteiros */
printf("nn enderecos dos ponteiros:%p
system(“pause”); return 0;

%p

%p", &a, &b,

%p", &pa, &pb, &pc);

}
enderecos de a, b e c:0063FDDC

0063FDD4

0063FDD3

enderecos de a, b e c (outra forma):0063FDDC
enderecos dos ponteiros:0063FDE8

0063FDE4

0063FDD4

0063FDD3

0063FDE0

E ponteiros de ponteiros?
Como os ponteiros também são variáveis, também é possível a construção de ponteiro para
um ponteiro. Começa a ficar meio artificial, mais existem exemplos onde isso é útil.
Veja o exemplo abaixo e algumas maneiras inusitadas de somar 1 a um inteiro.
#include <stdio.h>
#include <stdlib.h>
int main(){
int a, *pa, **ppa, ***pppa;
a = 0;
pa = &a;
ppa = &pa;
pppa = &ppa;

/* pa aponta para a */
/* ppa aponta para pa */
/* pppa aponta para ppa */

a = a + 1;
*pa = *pa + 1;
**ppa = **ppa + 1;
***pppa = ***pppa + 1;
system(“pause”);return

printf("nvalor
printf("nvalor
printf("nvalor
printf("nvalor
0;

Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

de
de
de
de

a
a
a
a

=
=
=
=

%1d",
%1d",
%1d",
%1d",

a);
a);
a);
a);
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

}

valor
valor
valor
valor

de
de
de
de

a
a
a
a

=
=
=
=

1
2
3
4

Ponteiros e o scanf
int i, *pi;
pi = &i;
scanf(“%d”, &i); é equivalente a
scanf(“%d”, pi); note que não é &pi
Ponteiros e parâmetros de retorno de funções
Já vimos anteriormente, no estudo das funções em C, que para que tenhamos parâmetros
de retorno, isto é, parâmetros que são alterados dentro da função e retornam com esse novo
valor, é necessário que passemos o endereço da variável como parâmetro. O endereço nada
mais é que um ponteiro.
Veja a função troca abaixo, o programa e o que será impresso.
#include <stdio.h>
#include <stdlib.h>
/* Função que recebe 2 variáveis reais e permute o valor */
int troca (double *a, double *b) {
double aux;
aux = *a;
*a = *b;
*b = aux;
}
int main() {
double x = 2.78,
y = 3.14,
*xx = &x,
*yy = &y;
/* x e y antes e depois da troca */
printf("nnn************** primeiro exemplo ******************");
printf("n* antes de chamar a troca x = %15.5lf e y = %15.5lf", x, y);
troca (&x, &y);
printf("n* depois de chamar a troca x = %15.5lf e y = %15.5lf", x, y);
/* x e y antes e depois da troca usando ponteiros */
*xx = 1.23456;
*yy = 6.54321;
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

printf("nnn************** segundo exemplo ******************");
printf("n* antes de chamar a troca x = %15.5lf e y = %15.5lf", x, y);
troca (xx, yy);
printf("n* depois de chamar a troca x = %15.5lf e y = %15.5lf", x, y);
system(“pause”); return 0;
}
************** primeiro exemplo ******************
* antes de chamar a troca x =
2.78000 e y =
* depois de chamar a troca x =
3.14000 e y =

3.14000
2.78000

************** segundo exemplo
* antes de chamar a troca x =
* depois de chamar a troca x =

6.54321
1.23456

******************
1.23456 e y =
6.54321 e y =

Ponteiros e vetores
O que acontece quando somamos (ou subtraímos) algo do valor de um ponteiro? Como não
sabemos em geral como as variáveis estão na memória, isto é, quem é vizinho de quem,
isso não faz muito sentido. Entretanto, se o ponteiro aponta para um vetor, isso pode fazer
sentido, pois os elementos do vetor estão contíguos na memória.
int v[100];
int *pv;
pv = &v[0];
*pv = 0; é o mesmo que v[0] = 0;
*(pv+i) = 0; é o mesmo que v[i] = 0;
for (i=0; i<100; i++) *(pv+i) = 0; zera o vetor v
Os incrementos ou decrementos no valor do ponteiro não são em bytes e sim acompanham
o tamanho do elemento apontado.
int *pi;
double *pa;
char *pc;
pi = pi + k; soma k*sizeof(int) em pi
pa = pa + k; soma k*sizeof(double) em pa
pc = pc + k; soma k em pc – o sizeof(char) é 1.
O nome do vetor também é um ponteiro
int v[100];
*v = 33; é o mesmo que v[0] = 33;
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

*(v+2) = 44; é o mesmo que v[2] = 44;
for (i = 0; i < 100; i++) *(v+i) = 0; zera o vetor v
O nome do ponteiro também é um vetor
Podemos também usar um ponteiro como um vetor.
int v[100];
int *pv;
pv = v; também pode ser pv = &v[0];
for (i = 0; i < 100; i++) pv[i] = 0;
Alocação dinâmica de memória – funções malloc calloc e free
Durante a execução de um programa é possível alocar certa quantidade de memória para
conter dados do programa
A função malloc (n) aloca dinamicamente n bytes e devolve um ponteiro para o
início da memória alocada.
A função calloc(n, t) aloca dinamicamente n elementos de tamanho t e devolve
ponteiro para o início da memória alocada.
A função free(p) libera a região de memória apontada por p. O tamanho liberado está
implícito, isto é, é igual ao que foi alocado anteriormente por malloc ou calloc.
Não se deve liberar espaço que não foi obtido explicitamente por uma chamada de
malloc ou calloc.
Outro detalhe é que malloc e calloc devolvem ponteiros. Como esse ponteiro é para
um tipo específico de dados (int, char, double, etc ...) deve-se aplicar uma
função de conversão de tipos após a chamada de malloc ou calloc para prover o
alinhamento necessário. Por exemplo, int tem que ser alocado em posição par de
memória.
Os comandos abaixo alocam dinamicamente um inteiro e depois o liberam.
#include <stdlib.h>
int *pi;
pi = (int *) malloc (sizeof(int));
...
free(pi);
ou ainda:
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

#include <stdlib.h>
int *pi;
pi = (int *) calloc (1, sizeof(int));
...
free(pi);
As funções malloc e calloc não tem um tipo específico. Assim, (int *)
converte seu valor em ponteiro para inteiro. Como não sabemos necessariamente o
comprimento de um inteiro (2 ou 4 bytes dependendo do compilador), usamos como
parâmetro a função sizeof(int).
Alocação dinâmica de vetores
Conforme sabemos, quando declaramos um vetor é necessário fixar o seu tamanho. Com
isso, temos sempre que declarar o seu tamanho máximo, pois o tamanho realmente
utilizado só será conhecido durante a execução do programa.
Com alocação dinâmica podemos resolver esse problema. Veja o trecho abaixo:
#include <stdlib.h>
#include <stdio.h>
int main() {
int *v;
int i, n;
scanf(“%d”, &n); /* le n */
/* aloca n elementos para v */
v = (int *) malloc(n*sizeof(int));
/* zera e utiliza o vetor v com exatamente n elementos */
for (i = 0; i < n; i++) v[i] = 0;
...
/* libera os n elementos de v quando não mais necessário */
free(v);
}
Outros exemplos:
char
…
pa =
pa =
pb =
pb =

*pa; int pb;
(char *) malloc(1000); /* aloca vetor com 1000 bytes */
(char *) malloc(1000*sizeof(char)); /* o mesmo */
(int *) malloc(1000); /* aloca vetor com 250 int */
(int *) malloc(250*sizeof(int)); /* o mesmo */

Usando calloc, os comandos acima ficariam:
char *pa; int pb;
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio
Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

…
pa
pa
pb
pb

=
=
=
=

(char *) calloc(1000,1); /*aloca vetor com 1000 bytes*/
(char *) calloc(1000,sizeof(char)); /* o mesmo */
(int *) calloc(1000,1); /* aloca vetor com 250 int */
(int *) calloc(250,sizeof(int)); /* o mesmo */

Ponteiros, ponteiros e vetores e alocação dinâmica de memória
Mac122 – Marcilio

Mais conteúdo relacionado

Mais procurados

Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Elaine Cecília Gatto
 
Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Elaine Cecília Gatto
 
Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Karoline Tavares
 
Estrutura de dados em Java - Ponteiros e Alocação de Memória
Estrutura de dados em Java - Ponteiros e Alocação de Memória Estrutura de dados em Java - Ponteiros e Alocação de Memória
Estrutura de dados em Java - Ponteiros e Alocação de Memória Adriano Teixeira de Souza
 
2 funcoes e estrutura de blocos
2   funcoes e estrutura de blocos2   funcoes e estrutura de blocos
2 funcoes e estrutura de blocosRicardo Bolanho
 
Exemplos registros e funções
Exemplos registros e funçõesExemplos registros e funções
Exemplos registros e funçõesCarla Lee
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template LibraryDuda Dornelles
 
Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05thomasdacosta
 
Palestra python
Palestra pythonPalestra python
Palestra pythonRony Cruch
 
Caderno de exercicios algoritmos-v.1.3
Caderno de exercicios   algoritmos-v.1.3Caderno de exercicios   algoritmos-v.1.3
Caderno de exercicios algoritmos-v.1.3Débora Inocêncio
 
Paradigmas de Linguagens de Programacao - Aula #3
Paradigmas de Linguagens de Programacao - Aula #3Paradigmas de Linguagens de Programacao - Aula #3
Paradigmas de Linguagens de Programacao - Aula #3Ismar Silveira
 
Conexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das GaláxiasConexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das GaláxiasMaurício Aniche
 

Mais procurados (20)

Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1
 
Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3
 
Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros Linguagem C - Funções e ponteiros
Linguagem C - Funções e ponteiros
 
Estrutura de dados em Java - Ponteiros e Alocação de Memória
Estrutura de dados em Java - Ponteiros e Alocação de Memória Estrutura de dados em Java - Ponteiros e Alocação de Memória
Estrutura de dados em Java - Ponteiros e Alocação de Memória
 
Linguagem C - Vetores
Linguagem C - VetoresLinguagem C - Vetores
Linguagem C - Vetores
 
Estrutura de Dados - Ponteiros
Estrutura de Dados - PonteirosEstrutura de Dados - Ponteiros
Estrutura de Dados - Ponteiros
 
2 funcoes e estrutura de blocos
2   funcoes e estrutura de blocos2   funcoes e estrutura de blocos
2 funcoes e estrutura de blocos
 
Exemplos registros e funções
Exemplos registros e funçõesExemplos registros e funções
Exemplos registros e funções
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template Library
 
Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05Programação Estruturada 2 - Aula 05
Programação Estruturada 2 - Aula 05
 
Palestra python
Palestra pythonPalestra python
Palestra python
 
Clean code
Clean codeClean code
Clean code
 
Ponteiros de Função
Ponteiros de FunçãoPonteiros de Função
Ponteiros de Função
 
Caderno de exercicios algoritmos-v.1.3
Caderno de exercicios   algoritmos-v.1.3Caderno de exercicios   algoritmos-v.1.3
Caderno de exercicios algoritmos-v.1.3
 
Paradigmas de Linguagens de Programacao - Aula #3
Paradigmas de Linguagens de Programacao - Aula #3Paradigmas de Linguagens de Programacao - Aula #3
Paradigmas de Linguagens de Programacao - Aula #3
 
pSets TSI32B - Estrutura, Pesquisa e Ordenação de Dados (TSI UTFPR-Toledo)
pSets TSI32B - Estrutura, Pesquisa e Ordenação de Dados (TSI UTFPR-Toledo)pSets TSI32B - Estrutura, Pesquisa e Ordenação de Dados (TSI UTFPR-Toledo)
pSets TSI32B - Estrutura, Pesquisa e Ordenação de Dados (TSI UTFPR-Toledo)
 
Estruturas
EstruturasEstruturas
Estruturas
 
Php
PhpPhp
Php
 
Ling c
Ling cLing c
Ling c
 
Conexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das GaláxiasConexão Java 2012 - Orientação a Objetos das Galáxias
Conexão Java 2012 - Orientação a Objetos das Galáxias
 

Semelhante a 8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria

Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...
Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...
Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...Os Fantasmas !
 
Conhecendo ou relembrando C
Conhecendo ou relembrando CConhecendo ou relembrando C
Conhecendo ou relembrando CVinícius Hax
 
Introdução a Linguagem C
Introdução a Linguagem CIntrodução a Linguagem C
Introdução a Linguagem Capolllorj
 
Aula c++ estruturas de dados
Aula c++   estruturas de dadosAula c++   estruturas de dados
Aula c++ estruturas de dadosJean Martina
 
02 JAVAEstrutura sequencial (slides).pptx
02 JAVAEstrutura sequencial (slides).pptx02 JAVAEstrutura sequencial (slides).pptx
02 JAVAEstrutura sequencial (slides).pptxwilliam Sarti José
 
Aula 13 ponteiros - Programação 1
Aula 13 ponteiros - Programação 1Aula 13 ponteiros - Programação 1
Aula 13 ponteiros - Programação 1Isaac Barros
 
tmn - Introdução ao JavaScript
tmn - Introdução ao JavaScripttmn - Introdução ao JavaScript
tmn - Introdução ao JavaScriptClaudio Gamboa
 
Comandos de Controle de Programa em C
Comandos de Controle de Programa em CComandos de Controle de Programa em C
Comandos de Controle de Programa em CElaine Cecília Gatto
 
3 funcoes vetores matrizes
3   funcoes vetores matrizes3   funcoes vetores matrizes
3 funcoes vetores matrizesRicardo Bolanho
 
Algoritmo e lógica de programação - aula 2
Algoritmo e lógica de programação - aula 2Algoritmo e lógica de programação - aula 2
Algoritmo e lógica de programação - aula 2engenhariadecomputacao
 
RevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxRevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxClaudia Ferlin
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordidaLuciano Ramalho
 

Semelhante a 8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria (20)

Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...
Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...
Capítulo 14 Livro Algoritmos e Programação de Computadores Autores JR., Diler...
 
Aula 6 pc - slides
Aula 6   pc - slidesAula 6   pc - slides
Aula 6 pc - slides
 
Conhecendo ou relembrando C
Conhecendo ou relembrando CConhecendo ou relembrando C
Conhecendo ou relembrando C
 
Ed1
Ed1Ed1
Ed1
 
Introdução a Linguagem C
Introdução a Linguagem CIntrodução a Linguagem C
Introdução a Linguagem C
 
Função malloc
Função mallocFunção malloc
Função malloc
 
Pged 01
Pged 01Pged 01
Pged 01
 
Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
 
Aula c++ estruturas de dados
Aula c++   estruturas de dadosAula c++   estruturas de dados
Aula c++ estruturas de dados
 
02 JAVAEstrutura sequencial (slides).pptx
02 JAVAEstrutura sequencial (slides).pptx02 JAVAEstrutura sequencial (slides).pptx
02 JAVAEstrutura sequencial (slides).pptx
 
Linguagem C - Entrada e Saída
Linguagem C - Entrada e SaídaLinguagem C - Entrada e Saída
Linguagem C - Entrada e Saída
 
Linguagem_C.pdf
Linguagem_C.pdfLinguagem_C.pdf
Linguagem_C.pdf
 
Aula 7 pc - estrutura
Aula 7   pc - estruturaAula 7   pc - estrutura
Aula 7 pc - estrutura
 
Aula 13 ponteiros - Programação 1
Aula 13 ponteiros - Programação 1Aula 13 ponteiros - Programação 1
Aula 13 ponteiros - Programação 1
 
tmn - Introdução ao JavaScript
tmn - Introdução ao JavaScripttmn - Introdução ao JavaScript
tmn - Introdução ao JavaScript
 
Comandos de Controle de Programa em C
Comandos de Controle de Programa em CComandos de Controle de Programa em C
Comandos de Controle de Programa em C
 
3 funcoes vetores matrizes
3   funcoes vetores matrizes3   funcoes vetores matrizes
3 funcoes vetores matrizes
 
Algoritmo e lógica de programação - aula 2
Algoritmo e lógica de programação - aula 2Algoritmo e lógica de programação - aula 2
Algoritmo e lógica de programação - aula 2
 
RevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptxRevisãoCompactaFuncoesPonteiro.pptx
RevisãoCompactaFuncoesPonteiro.pptx
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordida
 

Mais de Ricardo Bolanho

19 algoritmos de enumeracao
19   algoritmos de enumeracao19   algoritmos de enumeracao
19 algoritmos de enumeracaoRicardo Bolanho
 
18 algoritmos de busca de palavras em texto
18   algoritmos de busca de palavras em texto18   algoritmos de busca de palavras em texto
18 algoritmos de busca de palavras em textoRicardo Bolanho
 
17 arvores binarias de busca
17   arvores binarias de busca17   arvores binarias de busca
17 arvores binarias de buscaRicardo Bolanho
 
16 algoritmos de busca em tabelas - hash
16   algoritmos de busca em tabelas - hash16   algoritmos de busca em tabelas - hash
16 algoritmos de busca em tabelas - hashRicardo Bolanho
 
15 algoritmos de busca em tabelas - sequencial e binaria
15   algoritmos de busca em tabelas - sequencial e binaria15   algoritmos de busca em tabelas - sequencial e binaria
15 algoritmos de busca em tabelas - sequencial e binariaRicardo Bolanho
 
14 algoritmos de classificacao de tabelas
14   algoritmos de classificacao de tabelas14   algoritmos de classificacao de tabelas
14 algoritmos de classificacao de tabelasRicardo Bolanho
 
13 introducao a analise de algoritmos
13   introducao a analise de algoritmos13   introducao a analise de algoritmos
13 introducao a analise de algoritmosRicardo Bolanho
 
12 algoritmos e funcoes recursivas
12   algoritmos e funcoes recursivas12   algoritmos e funcoes recursivas
12 algoritmos e funcoes recursivasRicardo Bolanho
 
11 tipos abstratos de dados
11   tipos abstratos de dados11   tipos abstratos de dados
11 tipos abstratos de dadosRicardo Bolanho
 
10 alocacao dinamica - listas ligadas
10   alocacao dinamica - listas ligadas10   alocacao dinamica - listas ligadas
10 alocacao dinamica - listas ligadasRicardo Bolanho
 
7 alocacao sequencial - filas
7   alocacao sequencial - filas7   alocacao sequencial - filas
7 alocacao sequencial - filasRicardo Bolanho
 
6 alocacao sequencial - pilhas
6   alocacao sequencial - pilhas6   alocacao sequencial - pilhas
6 alocacao sequencial - pilhasRicardo Bolanho
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bitsRicardo Bolanho
 
Lógica para computação silva-finger-melo
Lógica para computação   silva-finger-meloLógica para computação   silva-finger-melo
Lógica para computação silva-finger-meloRicardo Bolanho
 
00 essential raymond murphy
00 essential raymond murphy00 essential raymond murphy
00 essential raymond murphyRicardo Bolanho
 
Symon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pSymon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pRicardo Bolanho
 

Mais de Ricardo Bolanho (20)

19 algoritmos de enumeracao
19   algoritmos de enumeracao19   algoritmos de enumeracao
19 algoritmos de enumeracao
 
18 algoritmos de busca de palavras em texto
18   algoritmos de busca de palavras em texto18   algoritmos de busca de palavras em texto
18 algoritmos de busca de palavras em texto
 
17 arvores binarias de busca
17   arvores binarias de busca17   arvores binarias de busca
17 arvores binarias de busca
 
16 algoritmos de busca em tabelas - hash
16   algoritmos de busca em tabelas - hash16   algoritmos de busca em tabelas - hash
16 algoritmos de busca em tabelas - hash
 
15 algoritmos de busca em tabelas - sequencial e binaria
15   algoritmos de busca em tabelas - sequencial e binaria15   algoritmos de busca em tabelas - sequencial e binaria
15 algoritmos de busca em tabelas - sequencial e binaria
 
14 algoritmos de classificacao de tabelas
14   algoritmos de classificacao de tabelas14   algoritmos de classificacao de tabelas
14 algoritmos de classificacao de tabelas
 
13 introducao a analise de algoritmos
13   introducao a analise de algoritmos13   introducao a analise de algoritmos
13 introducao a analise de algoritmos
 
12 algoritmos e funcoes recursivas
12   algoritmos e funcoes recursivas12   algoritmos e funcoes recursivas
12 algoritmos e funcoes recursivas
 
11 tipos abstratos de dados
11   tipos abstratos de dados11   tipos abstratos de dados
11 tipos abstratos de dados
 
10 alocacao dinamica - listas ligadas
10   alocacao dinamica - listas ligadas10   alocacao dinamica - listas ligadas
10 alocacao dinamica - listas ligadas
 
9 structs e ponteiros
9   structs e ponteiros9   structs e ponteiros
9 structs e ponteiros
 
7 alocacao sequencial - filas
7   alocacao sequencial - filas7   alocacao sequencial - filas
7 alocacao sequencial - filas
 
6 alocacao sequencial - pilhas
6   alocacao sequencial - pilhas6   alocacao sequencial - pilhas
6 alocacao sequencial - pilhas
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bits
 
4 char e strings
4   char e strings4   char e strings
4 char e strings
 
Lógica para computação silva-finger-melo
Lógica para computação   silva-finger-meloLógica para computação   silva-finger-melo
Lógica para computação silva-finger-melo
 
Projeto 2 aula 5
Projeto 2   aula 5Projeto 2   aula 5
Projeto 2 aula 5
 
Projeto 1 aula 4
Projeto 1   aula 4Projeto 1   aula 4
Projeto 1 aula 4
 
00 essential raymond murphy
00 essential raymond murphy00 essential raymond murphy
00 essential raymond murphy
 
Symon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pSymon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341p
 

8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria

  • 1. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio Ponteiros, ponteiros e vetores e alocação dinâmica de memória Ponteiros Ponteiros ou apontadores (em inglês pointers) são variáveis cujo conteúdo é um endereço. Já vimos que variáveis são posições na memória que podem conter um determinado valor dependendo de seu tipo (char, int, float, double, etc . . .). Assim, uma variável do tipo ponteiro contém valores que são na verdade endereços para outras posições de memória. Os nomes apontador, ponteiro ou pointer são utilizados com o mesmo significado. Como declarar um ponteiro Uma variável tipo ponteiro, “aponta” para uma variável de um determinado tipo conhecido (char, int, float, double, etc.), ou seja, contém um endereço de uma variável de um determinado tipo. Assim é necessário na declaração de um ponteiro, especificar para qual tipo de variável ele irá apontar. O operador * indica que a variável é um apontador. int *pi ; /* ponteiro para int */ char *pc; /* ponteiro para char */ float *pf; /* ponteiro para float */ double *pd; /* ponteiro para double */ Uso de ponteiro O operador & significa “endereço de”. int a; char b; pi = &a; /* pi fica com o endereço de a */ pc = &b; /* pc fica com o endereço de c */ /* Os dois comandos abaixo são equivalentes */ a = 45; *pi = 45; /* idem para */ b = ‘a’; e *pc = ‘a’; Veja o programa abaixo e o que ele imprime no vídeo. O formato p é um formato para imprimir o conteúdo de um ponteiro, ou seja, um endereço. #include <stdio.h> #include <stdlib.h> Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 2. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio int main() { int a, *pa; double b, *pb; char c, *pc; /* atribuições de endereços */ pa = &a; pb = &b; pc = &c; /* atribuição de valores */ a = 1; b = 2.34; c = '@'; printf("n valores:%5d %5.2lf %c", a, b, c); printf("n ponteiros:%5d %5.2lf %c", *pa, *pb, *pc); printf("n enderecos:%p %p %p", pa, pb, pc); /* mais atribuições de valores usando os ponteiros */ *pa = 77; *pb = 0.33; *pc = '#'; printf("n valores :%5d %5.2lf %c", a, b, c); printf("n ponteiros:%5d %5.2lf %c", *pa, *pb, *pc); printf("n enderecos:%p %p %p", pa, pb, pc); system (“pause”); return 0; } valores: 1 2.34 @ ponteiros: 1 2.34 @ enderecos:0063FDDC 0063FDD4 valores : 77 0.33 # ponteiros: 77 0.33 # enderecos:0063FDDC 0063FDD4 0063FDD3 0063FDD3 Um pouco sobre a memória e endereços O formato %p mostra o endereço. Os endereços são dependentes do particular computador e do particular compilador. Também depende do lugar em que o programa está carregado na memória. Assim um mesmo programa pode ocupar posições diferentes de memória em duas execuções diferentes. O mesmo pode ter suas variáveis alocadas em lugares diferentes se for compilado com diferentes compiladores. No exemplo acima estamos usando um computador com processador INTEL onde os endereços possuem 2 partes: número do segmento e deslocamento dentro do segmento. As variáveis possuem os seguintes endereços (em hexadecimal): a – 0063 FDDC (4 bytes FDDC a FDDF) b – 0063 FDD4 (4 bytes FDD4 a FDD7) c – 0063 FDD3 (1 byte FDD3) Veja outro exemplo de alocação de endereços na memória: Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 3. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio #include <stdio.h> #include <stdlib.h> int main() { int a, aa; double b, bb; char c, cc; int vi[5]; double vd[5]; char vc[5]; int i; printf("n endereco de a = %p endereco de aa = %p", &a, &aa); printf("n endereco de b = %p endereco de bb = %p", &b, &bb); printf("n endereco de c = %p endereco de cc = %p", &c, &cc); for (i = 0; i < 5; i++) printf("n endereco de vi[%1d] = %p", i, &vi[i]); for (i = 0; i < 5; i++) printf("n endereco de vd[%1d] = %p", i, &vd[i]); for (i = 0; i < 5; i++) printf("n endereco de vc[%1d] = %p", i, &vc[i]); printf("n endereco de vi = %pn endereco de vd = %pn endereco de vc = %p", vi, vd, vc); system(“pause”); return 0; } endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco endereco de de de de de de de de de de de de de de de de de de de de de a = 0063FDA0 endereco de aa = 0063FD9C b = 0063FD94 endereco de bb = 0063FD8C c = 0063FD8B endereco de cc = 0063FD8A vi[0] = 0063FDD4 vi[1] = 0063FDD8 vi[2] = 0063FDDC vi[3] = 0063FDE0 vi[4] = 0063FDE4 vd[0] = 0063FDAC vd[1] = 0063FDB4 vd[2] = 0063FDBC vd[3] = 0063FDC4 vd[4] = 0063FDCC vc[0] = 0063FDA7 vc[1] = 0063FDA8 vc[2] = 0063FDA9 vc[3] = 0063FDAA vc[4] = 0063FDAB vi = 0063FDD4 vd = 0063FDAC vc = 0063FDA7 Qual o endereço do ponteiro? Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 4. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio Ponteiros também são variáveis, portanto ocupam posições na memória. Veja o programa abaixo que mostra o endereço das variáveis e dos ponteiros. #include <stdio.h> #include <stdlib.h> int main() { int a, *pa; double b, *pb; char c, *pc; /* atribuições de endereços */ pa = &a; pb = &b; pc = &c; /* mostra o endereço das variáveis */ printf("nn enderecos de a, b e c:%p %p %p", pa, pb, pc); /* mostra o endereço das variáveis de outra forma */ printf("nn enderecos de a, b e c (outra forma):%p %p &c); /* mostra o endereço dos ponteiros */ printf("nn enderecos dos ponteiros:%p system(“pause”); return 0; %p %p", &a, &b, %p", &pa, &pb, &pc); } enderecos de a, b e c:0063FDDC 0063FDD4 0063FDD3 enderecos de a, b e c (outra forma):0063FDDC enderecos dos ponteiros:0063FDE8 0063FDE4 0063FDD4 0063FDD3 0063FDE0 E ponteiros de ponteiros? Como os ponteiros também são variáveis, também é possível a construção de ponteiro para um ponteiro. Começa a ficar meio artificial, mais existem exemplos onde isso é útil. Veja o exemplo abaixo e algumas maneiras inusitadas de somar 1 a um inteiro. #include <stdio.h> #include <stdlib.h> int main(){ int a, *pa, **ppa, ***pppa; a = 0; pa = &a; ppa = &pa; pppa = &ppa; /* pa aponta para a */ /* ppa aponta para pa */ /* pppa aponta para ppa */ a = a + 1; *pa = *pa + 1; **ppa = **ppa + 1; ***pppa = ***pppa + 1; system(“pause”);return printf("nvalor printf("nvalor printf("nvalor printf("nvalor 0; Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio de de de de a a a a = = = = %1d", %1d", %1d", %1d", a); a); a); a);
  • 5. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio } valor valor valor valor de de de de a a a a = = = = 1 2 3 4 Ponteiros e o scanf int i, *pi; pi = &i; scanf(“%d”, &i); é equivalente a scanf(“%d”, pi); note que não é &pi Ponteiros e parâmetros de retorno de funções Já vimos anteriormente, no estudo das funções em C, que para que tenhamos parâmetros de retorno, isto é, parâmetros que são alterados dentro da função e retornam com esse novo valor, é necessário que passemos o endereço da variável como parâmetro. O endereço nada mais é que um ponteiro. Veja a função troca abaixo, o programa e o que será impresso. #include <stdio.h> #include <stdlib.h> /* Função que recebe 2 variáveis reais e permute o valor */ int troca (double *a, double *b) { double aux; aux = *a; *a = *b; *b = aux; } int main() { double x = 2.78, y = 3.14, *xx = &x, *yy = &y; /* x e y antes e depois da troca */ printf("nnn************** primeiro exemplo ******************"); printf("n* antes de chamar a troca x = %15.5lf e y = %15.5lf", x, y); troca (&x, &y); printf("n* depois de chamar a troca x = %15.5lf e y = %15.5lf", x, y); /* x e y antes e depois da troca usando ponteiros */ *xx = 1.23456; *yy = 6.54321; Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 6. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio printf("nnn************** segundo exemplo ******************"); printf("n* antes de chamar a troca x = %15.5lf e y = %15.5lf", x, y); troca (xx, yy); printf("n* depois de chamar a troca x = %15.5lf e y = %15.5lf", x, y); system(“pause”); return 0; } ************** primeiro exemplo ****************** * antes de chamar a troca x = 2.78000 e y = * depois de chamar a troca x = 3.14000 e y = 3.14000 2.78000 ************** segundo exemplo * antes de chamar a troca x = * depois de chamar a troca x = 6.54321 1.23456 ****************** 1.23456 e y = 6.54321 e y = Ponteiros e vetores O que acontece quando somamos (ou subtraímos) algo do valor de um ponteiro? Como não sabemos em geral como as variáveis estão na memória, isto é, quem é vizinho de quem, isso não faz muito sentido. Entretanto, se o ponteiro aponta para um vetor, isso pode fazer sentido, pois os elementos do vetor estão contíguos na memória. int v[100]; int *pv; pv = &v[0]; *pv = 0; é o mesmo que v[0] = 0; *(pv+i) = 0; é o mesmo que v[i] = 0; for (i=0; i<100; i++) *(pv+i) = 0; zera o vetor v Os incrementos ou decrementos no valor do ponteiro não são em bytes e sim acompanham o tamanho do elemento apontado. int *pi; double *pa; char *pc; pi = pi + k; soma k*sizeof(int) em pi pa = pa + k; soma k*sizeof(double) em pa pc = pc + k; soma k em pc – o sizeof(char) é 1. O nome do vetor também é um ponteiro int v[100]; *v = 33; é o mesmo que v[0] = 33; Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 7. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio *(v+2) = 44; é o mesmo que v[2] = 44; for (i = 0; i < 100; i++) *(v+i) = 0; zera o vetor v O nome do ponteiro também é um vetor Podemos também usar um ponteiro como um vetor. int v[100]; int *pv; pv = v; também pode ser pv = &v[0]; for (i = 0; i < 100; i++) pv[i] = 0; Alocação dinâmica de memória – funções malloc calloc e free Durante a execução de um programa é possível alocar certa quantidade de memória para conter dados do programa A função malloc (n) aloca dinamicamente n bytes e devolve um ponteiro para o início da memória alocada. A função calloc(n, t) aloca dinamicamente n elementos de tamanho t e devolve ponteiro para o início da memória alocada. A função free(p) libera a região de memória apontada por p. O tamanho liberado está implícito, isto é, é igual ao que foi alocado anteriormente por malloc ou calloc. Não se deve liberar espaço que não foi obtido explicitamente por uma chamada de malloc ou calloc. Outro detalhe é que malloc e calloc devolvem ponteiros. Como esse ponteiro é para um tipo específico de dados (int, char, double, etc ...) deve-se aplicar uma função de conversão de tipos após a chamada de malloc ou calloc para prover o alinhamento necessário. Por exemplo, int tem que ser alocado em posição par de memória. Os comandos abaixo alocam dinamicamente um inteiro e depois o liberam. #include <stdlib.h> int *pi; pi = (int *) malloc (sizeof(int)); ... free(pi); ou ainda: Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 8. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio #include <stdlib.h> int *pi; pi = (int *) calloc (1, sizeof(int)); ... free(pi); As funções malloc e calloc não tem um tipo específico. Assim, (int *) converte seu valor em ponteiro para inteiro. Como não sabemos necessariamente o comprimento de um inteiro (2 ou 4 bytes dependendo do compilador), usamos como parâmetro a função sizeof(int). Alocação dinâmica de vetores Conforme sabemos, quando declaramos um vetor é necessário fixar o seu tamanho. Com isso, temos sempre que declarar o seu tamanho máximo, pois o tamanho realmente utilizado só será conhecido durante a execução do programa. Com alocação dinâmica podemos resolver esse problema. Veja o trecho abaixo: #include <stdlib.h> #include <stdio.h> int main() { int *v; int i, n; scanf(“%d”, &n); /* le n */ /* aloca n elementos para v */ v = (int *) malloc(n*sizeof(int)); /* zera e utiliza o vetor v com exatamente n elementos */ for (i = 0; i < n; i++) v[i] = 0; ... /* libera os n elementos de v quando não mais necessário */ free(v); } Outros exemplos: char … pa = pa = pb = pb = *pa; int pb; (char *) malloc(1000); /* aloca vetor com 1000 bytes */ (char *) malloc(1000*sizeof(char)); /* o mesmo */ (int *) malloc(1000); /* aloca vetor com 250 int */ (int *) malloc(250*sizeof(int)); /* o mesmo */ Usando calloc, os comandos acima ficariam: char *pa; int pb; Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio
  • 9. Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio … pa pa pb pb = = = = (char *) calloc(1000,1); /*aloca vetor com 1000 bytes*/ (char *) calloc(1000,sizeof(char)); /* o mesmo */ (int *) calloc(1000,1); /* aloca vetor com 250 int */ (int *) calloc(250,sizeof(int)); /* o mesmo */ Ponteiros, ponteiros e vetores e alocação dinâmica de memória Mac122 – Marcilio