Вы находитесь на странице: 1из 32

`  

c Definição
c Uso
c Operadores
c Operações
c Vetores x Ponteiros
c Matrizes x Ponteiros
c Indireção Múltipla (ponteiro p/ ponteiro)
c Alocação Dinâmica
`  
c Definição
Ponteiros são endereços de memória.
Cuidado: Não são inicializados.
u u   
  u

c Uso
Permite a modificação dos argumentos das funções através da
referência ao endereço de memóriau

Permite o uso de rotinas de alocação dinâmicau

m alguns casos aumenta a eficiência dos programas.


`  
c Operadores

0 è o conteúdo do endereço.
Sendo que na declaração indica o tipo da variável.
ex.: int *pu

Na manipulação retorna o conteúdo


ex.: int n1=10, n2, *pu
p = &n1u n2 = *pu

Neste caso ele é unário, diferente do operador da


multiplicação.

è o endereço de memória.
p = &n1u // o ponteiro é inicializado
`  


main () {
int num=25u
int *pontu // * (asterisco) indica o tipo da variável

pont = &numu //pont recebe o endereço de num

printf("\nO endereco num: %p \tconteudo num: %d",&num,num)u


printf("\nO conteudo pont: %p \t",pont)u
printf("\n\nO endereco pont: %p \tconteudo do endereco pont: %d\n\n",&pont,*pont)u
O endereco num: 0022FF7C conteudo num: 25
O conteudo pont: 0022FF7C

O endereco pont: 0022FF78 conteudo do endereco pont: 25

*pont=230u /* Muda o valor de num de uma maneira indireta */


printf ("\nValor final de num: %d\n\n",num)u

Valor final de num: 230
`  


int *p1, *p2, n=15u
printf("\nO endereco de p1: %p p2: %p n: %p",&p1,&p2,&n)u

p1 =&nu
p2 = p1u
printf("\nO conteudo de p1: %p p2: %p",p1,p2)u

printf("\nO conteudo endereco de p1: %d p2: %d",*p1,*p2)u

*p1=*p2u
printf("\nO conteudo p1: %d p2: %d\n\n",*p1,*p2)u

int n1,n2, *pu


n1 =10u printf("\nn1: %d endereco n1: %p\n\n",n1,&n1)u

p = &n1u printf("\nconteudo de p que eh o endereco n1: %p endereco p: %p\n",p,&p)u

n2 = *pu printf("\nn1: %d n2: %d p: %d \n\n",n1,n2,*p)u


`  


Igualar dois ponteiros

p1 = p2u // iguala os endereços


*p1=*p2u // iguala os conteúdos
Os ponteiros assim como quaisquer variáveis precisam ser
inicializados antes de serem utilizados.

Incremento e Decremento
No incremento o ponteiro passa apontar para o próximo valor
do mesmo tipo para o qual o ponteiro aponta.
O compilador usa o tipo do ponteiro para calcular a próxima
posição de memória.
p++u /* Só muda a posição de memória não o
conteúdo */
p--u
`  


Operações com o conteúdo dos ponteiros

(*p)++u // soma 1 ao conteúdo do ponteiro


*(p+10)u /*recupera o conteúdo do ponteiro 10 posições adiante,
cuidado, não sabemos o que tem neste endereço */

Operações relacionais com ponteiros

p1 > p2

Operações que NÃO podem ser feitas com ponteiros

Dividir ou multiplicar ponteirosu


Adicionar dois ponteirosu
Adicionar ou subtrair floats ou doubles de ponteiros.
`   

1) xplique a diferença entre:
p++u (*p)++u *(p++)u

2) O que quer dizer *(p+10)u

3) Qual o resultado em cada printf


 = 2u
p = &u
printf ("\n\tconteudo p: %d\n",*p)u
x = *pu
(*p)++u
printf ("\n\tconteudo p: %d x: %d\n",*p,x)u
x--u
printf ("\n\n\tx: %d conteudo p: %d\n\n",x,*p)u
(*p) += xu
printf ("\n\n\t = %d conteudo p: %d\n\n\n", ,*p)u
`   

) Seja o seguinte trecho de programa:
int i=3, j=5, *p, *qu
p = &iu
q = &ju
Qual é o valor das seguintes expressões (variáveis inteiras) 
a) p == &iu b) *p - *q c) **&p d) 3* - *p/(*q)+7

5) Qual será a saída deste programa supondo que i ocupa o endereço 09 na memória
main() {
int i=5, *pu
p = &iu
printf(³%x %d %d %d %d \n´, p,*p+2,**&p,3**p,**&p+ )u

) Se i e j são variáveis inteiras e p e q ponteiros para int, quais das seguintes


expressões de atribuição são ilegais
a) p = &iu b) *q = &ju c) p = &*&iu d) i = (*&)ju
e) i = *&ju f) i = *&*&ju g) q = *pu h) i = (*p)++ + *q
`   

) Seja o seguinte trecho de programa:
int i=3, j=5, *p, *qu
p = &iu
q = &ju
Qual é o valor das seguintes expressões (variáveis inteiras) 
a) p == &iu b) *p - *q c) **&p d) 3* - *p/(*q)+7

5) Qual será a saída deste programa supondo que i ocupa o endereço 09 na memória
main() {
int i=5, *pu
p = &iu
printf(³%x %d %d %d %d \n´, p,*p+2,**&p,3**p,**&p+ )u

) Se i e j são variáveis inteiras e p e q ponteiros para int, quais das seguintes


expressões de atribuição são ilegais
a) p = &iu b) *q = &ju c) p = &*&iu d) i = (*&)ju
e) i = *&ju f) i = *&*&ju g) q = *pu h) i = (*p)++ + *q
`   

7) O que fazem os programas abaixo:

main() { int vet[] = { ,9,12u


int i,*ptru
ptr = vetu
for(i = 0 u i < 3 u i++) {
printf("%d ",*ptr++)u


main() { int vet[] = { ,9,12u


int i,*ptru
ptr = vetu
for(i = 0 u i < 3 u i++) {
printf("%d ",(*ptr)++)u 

V `  
xiste uma relação entre Vetores/Matrizes, pois quando um
vetor ou matriz é declarado apenas é indicado o endereço da primeira
posição. Logo as expressões abaixo são equivalentes:
nome_da_variável[índice] e
*(nome_da_variável+índice)

L MBR -S : p[t] é o mesmo que *(p+t)

matriz sem ponteiro matriz com ponteiro


float mat [20][20]u float mat [20][20], *pu
int i,ju int iu
for (i=0ui<20ui++) p=mat[0]u
for (j=0uj<20uj++) for (i=0ui< 00ui++) {
mat[i][j]=0.0u *p =0.0u
p++u 
`  
Ponteiros podem ser organizados em matrizes como qualquer outro
tipo de dado.
float *mat[5]u

Atribuir o endereço de uma variável ³x´ a qualquer elemento da matriz:


mat[3] = &xu

Para recuperar o valor de x:


*mat[3]u
 `
Um ponteiro que aponta para outro ponteiro que aponta para o valor
final.
ponteiro variável
endereço valor Indireção
Simples

ponteiro ponteiro variável


endereço valor Indireção
endereço
Múltipla
main()
{
int s, *p, **q;
s = 10;
p = &s;
q = &p;
printf (³%d %d´,*p,**q);
}
  ! 
A alocação dinâmica permite ao programador alocar memória
para variáveis quando o programa está sendo executado. Assim,
poderemos definir, por exemplo, um vetor ou uma matriz cujo tamanho
é solicitado em tempo de execução.

O padrão C ANSI define apenas funções para o sistema de


alocação dinâmica, disponíveis na biblioteca stdlib.h:

‡ malloc - memor allocation


‡ calloc
‡ realloc
‡ free
  !  " ##
Alocar memória:
void *malloc (unsigned int num)u

Aloca um bloco de btes consecutivos na memória e devolve o


endereço desse bloco. Se não houver memória suficiente para alocar a
memória requisitada a função malloc() retorna um ponteiro nulo.

int *pu
int au // em a será definido a quantidade de elementos a serem alocados

p=(int *)malloc(a*sizeof(int))u // o uso da função sizeof torna o programa portável

if (!p) { // if (p==NULL)
printf ("** rro: Memoria Insuficiente **")u
exit(0)u

  !   ##
Alocar memória, semelhante a malloc.

void *calloc (unsigned int num, unsigned int size)u

Aloca na memória e retorna um ponteiro void * para o primeiro


bte alocado. O ponteiro void * pode ser atribuído a qualquer tipo de
ponteiro. Se não houver memória suficiente para alocar a memória
requisitada a função malloc() retorna um ponteiro nulo.
int *pu
int au

p=(int *)calloc(a,sizeof(int))u // o uso da função sizeof torna o programa portável


if (!p) { // if (p==NULL)
printf ("** rro: Memoria Insuficiente **")u
exit(0)u

  ! 
##
Realoca a memória.
void *realloc (void *ptr, unsigned int num)u
A funçao modifica o tamanho da memória previamente alocada
apontada por *ptr para aquele especificado por num. O valor de num
pode ser maior ou menor que o original. Um ponteiro para o bloco é
devolvido porque realloc() pode precisar mover o bloco para aumentar
seu tamanho. Se isso ocorrer, o conteúdo do bloco antigo é copiado no
novo bloco, e nenhuma informação é perdida. Se ptr for nulo, aloca size
btes e devolve um ponteirou se size é zero, a memória apontada por
ptr é liberada. Se não houver memória suficiente para a alocação, um
ponteiro nulo é devolvido e o bloco original é deixado inalterado.
int *pu
int a=10u
p=(int *)malloc(a*sizeof(int))u
..

a = 50u
p = realloc (p, a*sizeof(int))u
  !  $

Libera a memória alocada dinamicamente.


void free (void *p)u

Passamos para free() o ponteiro que aponta para o início da


memória alocada.

int *pu
int au

p=(int *)malloc(a*sizeof(int))u
if (!p) { // if (p==NULL)
printf ("** rro: Memoria Insuficiente **")u
exit(0)u


free(p)u
  % &! 
  %  V 

‡ è necessário saber de antemão a dimensão máxima do vetoru

‡ Variável que representa o vetor armazena o endereço ocupado pelo


primeiro elemento do vetoru

‡ Se o vetor for declarado dentro do corpo de uma função não pode ser
usado fora do corpo da função

#define N 10
int v[N]u
  % &! 
  !  V 

‡ A dimensão do vetor pode ser definida em tempo de execuçãou

‡ Variável do tipo ponteiro recebe o valor do endereço do primeiro


elemento do vetoru

‡ A área de memória ocupada pelo vetor permanece válida até que


seja explicitamente liberada (através da função free). O vetor alocado
dentro do corpo de uma função pode ser usado fora do corpo da
função, enquanto estiver alocado.

int* v

v = (int*) malloc(n * sizeof(int))u
  !  V
'

Com a alocação dinâmica de vetores podemos referenciar o
nome do vetor como um ponteiro constante.

Com isso é possível indexar o nome de um vetor, e como


consequência podemos também indexar um ponteiro qualquer.

alocar_vetor.cpp

alocar_vetor.exe
  % &! 
  ! 

‡ A linguagem C só permite alocação dinâmica de conjuntos


unidimensionaisu

‡ è necessário criar abstrações conceituais com vetores para


representar matrizes (alocadas dinamicamente)u

‡ A matriz é representada por um vetor simples: o conjunto


bidimensional representado em vetor unidimensional. Logo, as
primeiras posições do vetor armazenam elementos da primeira linha
seguidos dos elementos da segunda linha, e assim por diante. isso
exige uma certa disciplina para acessar os elementos da matrizu
  % &! 
  ! 

Seja uma matriz mat com n colunas representada no vetor v:


mat[ i ][ j ] pode ser mapeado em v[ k ] onde k = i * n + j

mat[ i ][ j ] mapeado em v[ i * n + j ] //n é o número de colunas


float *matu /* matriz m x n representada por um vetor */
...
mat = (float*) malloc(m*n*sizeof(float))u
  % &! 
  ! 

A matriz pode ser representada por um vetor de ponteiros. Onde cada


elemento do vetor armazena o endereço do primeiro elemento de cada
linha da matriz.
  !   ' (

A alocação dinâmica de memória para matrizes é realizada da
mesma forma que para vetores, com a diferença que teremos um
ponteiro apontando para outro ponteiro que aponta para o valor final ±
Indireção Múltipla.

A estrutura de dados criada é composta por um vetor de


ponteiros (correspondendo ao primeiro índice da matriz), sendo que
cada ponteiro aponta para o início de uma linha da matriz. m cada
linha existe um vetor alocado dinamicamente (compondo o segundo
índice da matriz).

alocar_matriz.cpp

alocar_matriz.exe
  !  V
'
) # *+
' , -
#include <stdio.h>
#include <stdlib.h>

float *Alocar_vetor_real (int n)


{ float *vu /* ponteiro para o vetor */
if (n < 1) { /* verifica parametros recebidos */
printf ("** rro: Parametro invalido **\n")u return (NULL)u 
v = (float *) calloc (n, sizeof(float))u /* aloca o vetor */
if (v == NULL) {
printf ("** rro: Memoria Insuficiente **")u return (NULL)u 
return (v)u  /* retorna o ponteiro para o vetor */
float *Liberar_vetor_real (int n, float *v)
{ if (v == NULL) return (NULL)u
if (n < 1) { /* verifica parametros recebidos */
printf ("** rro: Parametro invalido **\n")u return (NULL)u 
free(v)u /* libera o vetor */
return (NULL)u /* retorna o ponteiro */
main ()
{ float *p,*auxu
int tam,i,u
printf("\nInforme o tamanho do vetor: ")u scanf("%d",&tam)u
p = Alocar_vetor_real (tam)u
aux=pu // guarda o endereço inicial de p
for (i=0ui<tamui++) { //carrega dados no vetor
printf("\nInforme o elemento %d do vetor: ",i+1)u
//scanf("%f",&p[i])u // leitura com notação de vetor
scanf("%f",p)u p++u  // leitura com notação de ponteiro
p=auxu //recupera o endereço inicial de p
for (i=0ui<tamui++) { //exibe dados do vetor
//printf("\n lemento %d eh: %f ",i+1,p[i])u //impressão com notação de vetor
printf("\n lemento %d eh: %.2f ",i+1,*p)u p++u  //impressão com notação de ponteiro
p = Liberar_vetor_real (tam, p)u
printf("\n\n")u sstem("pause")u  //fim do programa
  !   ' (
) # *" ' (, -
#include <stdio.h>
#include <stdlib.h>
float **Alocar_matriz_real (int m, int n)
{ float **vu /* ponteiro para a matriz */ int iu /* variavel auxiliar */
if (m < 1 || n < 1) { /* verifica parametros recebidos */
printf ("** rro: Parametro invalido **\n")u return (NULL)u 
v = (float **) calloc (m, sizeof(float *))u /* aloca as linhas da matriz */
if (v == NULL) {
printf ("** rro: Memoria Insuficiente **")u return (NULL)u 
for ( i = 0u i < mu i++ ) {
v[i] = (float*) calloc (n, sizeof(float))u /* aloca as colunas da matriz */
if (v[i] == NULL) {
printf ("** rro: Memoria Insuficiente **")u return (NULL)u  
return (v)u  /* retorna o ponteiro para a matriz */
float **Liberar_matriz_real (int m, int n, float **v)
{ int iu /* variavel auxiliar */
if (v == NULL) return (NULL)u
if (m < 1 || n < 1) { /* verifica parametros recebidos */
printf ("** rro: Parametro invalido **\n")u return (v)u 
for (i=0u i<mu i++) free (v[i])u /* libera as linhas da matriz */
free (v)u /* libera a matriz */ return (NULL)u  /* retorna um ponteiro nulo */
main ()
{ float **matu
int l,c,qtlin,qtcolu
printf("\nInforme a quantidade de linhas: ")u scanf("%d",&qtlin)u
printf("\nInforme a quantidade de colunas: ")u scanf("%d",&qtcol)u
mat = Alocar_matriz_real (qtlin, qtcol)u
for (l=0ul<qtlinul++) { //carrega dados da matriz
for (c=0uc<qtcoluc++) {
printf("\nInforme o elemento %d %d da matriz: ",l+1,c+1)u scanf("%f",&mat[l][c])u // leitura com notação de matriz 
for (l=0ul<qtlinul++) {printf("\n\n")u//exibe dados da matriz
for (c=0uc<qtcoluc++) { printf("\t%.2f",mat[l][c])u   //impressão com notação de matriz
mat = Liberar_matriz_real (qtlin, qtcol, mat)u
printf("\n\n")u sstem("pause")u  //fim do programa


labore uma função que forneça a transposta de uma matriz:

ntrada: mat matriz de dimensão m x n

Saída: trp transposta de mat, alocada dinamicamente

Definição de Matriz Transposta:


Q é a u u u de M se e somente se  

  
 u      u  
 u      uu 
 ' ( # "+
' " #


float* transposta (int m, int n, float* mat)


{
int i, ju
float* trpu

/* aloca matriz transposta com n linhas e m colunas */

trp = (float*) malloc(n*m*sizeof(float))u

/* preenche matriz */
for (i=0u i<mu i++)
for (j=0u j<nu j++)
trp[ j*m+i ] = mat[ i*n+j ]u
return trpu

 ' ( # "+
' 
 .'
 

float** transposta (int m, int n, float** mat)


{
int i, ju
float** trpu

/* aloca matriz transposta com n linhas e m colunas */


trp = (float**) malloc(n*sizeof(float*))u

for (i=0u i<nu i++)


trp[i] = (float*) malloc(m*sizeof(float))u

/* preenche matriz */
for (i=0u i<mu i++)
for (j=0u j<nu j++)
trp[ j ] [ i ] = mat[ i ][ j ]u
return trpu

 ' (
 .#/


Matriz representada por vetor bidimensional estático:


lementos acessados com indexação dupla m[ i ][ j ]

Matriz representada por um vetor simples:


Conjunto bidimensional representado em vetor unidimensional

Matriz representada por um vetor de ponteiros:


Cada elemento do vetor armazena o endereço do primeiro
elemento de cada linha da matriz

Вам также может понравиться