Programação I:
Ponteiros
Rodrigo Paes
Instituto de Computação – UFAL
Exercício em sala
 Objetivo: ler 03 numeros nas variaveis x,y e z e
depois ordenar x,y e z de tal forma que x
armazene o menor valor, y o intermediário e z o
maior
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Código repetido
 O que queremos com
esses 03 trechos?
 Trocar os valores de duas
variáveis, correto?
 Ou seja, queriamos
isolar uma
funcionalidade
 Uma função de trocar
valores
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Não seria melhor assim?
 Ok … vamos tentar
rodrigo@ic.ufal.br
trocar(x,y)
trocar(x,z)
trocar(y,z)
Instituto de Computação – UFAL
Tentativa 01
 funcao_trocar_valores2.c
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Os valores foram trocados?
 Não, né?
 Passagem por valor
 A passagem de parâmetro foi feita por valor
 É feita uma cópia do valor da variável
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Passagem por valor
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Ponteiros
 Ao declarar uma variável sempre informamos o
tipo dela
 int a;
 float soma;
 …
 Lembra da 1a aula?
 As variáveis ficam na memória
 Endereço e Conteúdo
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Variáveis
 Já sabemos alterar o
conteúdo das
variáveis
 Comando de
atribuição
 resto = 25;
 soma =soma + i;
 …
 Mas como descobrir o
endereço de memória
das nossas variáveis?
rodrigo@ic.ufal.br
En
d.
Conteúdo
1 34
2 “O rato roeu a roupa do rei de
roma”
3 34.67
4 1
5 0
6 “aula de p1”
7 4677
… 123
n
Instituto de Computação – UFAL
Operador &
 Este operador nos fornece o endereço de
memória de uma variável
 Exemplo:
main()
{
int a = 1;
printf("O endereco de a eh: %pn",&a);
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Um novo tipo de variável: ponteiro
 O tipo da variável define os valores válidos para
uma variável
 Exemplo
 int: valores inteiros
 char: caracteres
 float: ponto flutuante
 …
 Um ponteiro é um tipo de variável cujos valores
válidos são endereços de memória
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Como funciona?
 Imagine uma caixa postal
 Caixa postal 22300
 A caixa postal é só um endereço
 Ela aponta para uma localização que contém
um imóvel (conteúdo)
 Os imóveis podem ser de vários tipos
 Residencial casa, residencial apartamento, comercial
…
 Ou seja, a caixa postal contém um endereço
para um conteúdo de um determinado tipo
 A caixa postal é um ponteiro
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
… voltando ao C
 Um ponteiro é um endereço para um
determinado tipo
 int
 float
 char
 outro ponteiro
 …
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Ponteiros
Endereço Identificador Conteúdo
0xFF4454 a 5
… … …
… … …
… … …
… … …
0xBBA031 b 12
rodrigo@ic.ufal.br
ponteiro_a
Instituto de Computação – UFAL
Declaração de ponteiros
main()
{
int a = 1;
int b = 2;
int *pt_a;
…
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Atribuição com ponteiro
main()
{
int a = 1;
int b = 2;
int *meu_ponteiro;
meu_ponteiro = &a; // atribui o endereço de a
…
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Acesso ao conteúdo do local apontado pelo
ponteiro: *, o operador de “dereference”
main()
{
int a = 1;
int b = 2;
int *pt_a;
pt_a = &a;
*pt_a = 50; // o que vai acontecer aqui?
…
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Brincando com ponteiros
 ponteiros.c
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Interessante né? mas e daí?
 Vamos voltar para a nossa função de troca
rodrigo@ic.ufal.br
E se …
•na nossa função recebessemos os
endereços das variáveis que desejamos
trocar
•Com o endereço, poderíamos trocar os
valores
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 5
0xFF1242 y 3
0xBBA031 z 2
0xABA005 aux ---
a
b
void trocar_valores(float *a, float *b)
{
float aux;
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 5
0xFF1242 y 3
0xBBA031 z 2
0xABA005 aux 5
a
b
void trocar_valores(float *a, float *b)
{
float aux;
aux = *a;
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 5
0xFF1242 y 3
0xBBA031 z 2
0xABA005 aux 5
a
b
void trocar_valores(float *a, float *b)
{
float aux;
aux = *a;
*a = *b;
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 3
0xFF1242 y 3
0xBBA031 z 2
0xABA005 aux 5
a
b
void trocar_valores(float *a, float *b)
{
float aux;
aux = *a;
*a = *b;
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 3
0xFF1242 y 3
0xBBA031 z 2
0xABA005 aux 5
a
b
void trocar_valores(float *a, float *b)
{
float aux;
aux = *a;
*a = *b;
*b = aux;
}
Instituto de Computação – UFAL
Ideia
 trocar_valores(&x,&y)
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 3
0xFF1242 y 5
0xBBA031 z 2
0xABA005 aux 5
a
b
void trocar_valores(float *a, float *b)
{
float aux;
aux = *a;
*a = *b;
*b = aux;
}
Instituto de Computação – UFAL
Ideia
 Ao sair … do escopo local as variáveis são
eliminadas
rodrigo@ic.ufal.br
Endereço Identificador Conteúdo
0xFF4454 x 3
0xFF1242 y 5
0xBBA031 z 2if (y < z) // neste caso y é o menor
{
// troca os conteúdos de x e de y
trocar_valores(&x,&y);
}
else // neste caso z é o menor
Instituto de Computação – UFAL
O programa completo
 funcao_trocar_valores3.c
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Passagem por referência
 O que acabamos de fazer foi passar os
parâmetros por referência ao invés de passar
por valor
 Passamos apenas uma referência para a variável
externa
 O seu valor não é copiado
 Mais eficiente
 Exige cuidados com efeitos colaterais
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Algumas reflexões
 Pra que ponteiros?
 C é de uma época em que os computadores eram
menos poderosos
 Necessidade de uso eficiente de processamento e
memória
 Logo, habilidade de trabalhar diretamente a memória
é muito útil
 E por que ainda usamos ponteiros?
 Necessidade de eficiência ainda é importante
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Exemplos
main()
{
int x = 7 ;
int *px ;
px = &x ;
*px = 8 ;
printf( "%dn" , x ) ;
printf( "%dn" , &x ) ;
printf( "%dn" , px ) ;
printf( "%dn" , *px ) ;
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Exemplos
void exemplo2()
{
int firstvalue, secondvalue;
int * mypointer;
mypointer = &firstvalue;
*mypointer = 10;
mypointer = &secondvalue;
*mypointer = 20;
printf("%dn",firstvalue);
printf("%dn",secondvalue);
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Exemplos
void exemplo3()
{
int firstvalue = 5, secondvalue = 15;
int * p1, * p2;
p1 = &firstvalue;
p2 = &secondvalue;
*p1 = 10;
*p2 = *p1;
p1 = p2;
*p1 = 20;
printf("%dn",firstvalue);
printf("%dn",secondvalue);
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Exemplos
 Assuma que os seguintes endereços:
 c é 1
 d é 2
 e é 3
 Qual a saída do programa abaixo:
char c = 'T', d = 'S';
char *p1 = &c;
char *p2 = &d;
char *p3;
p3 = &d;
printf("%cn",*p3);
p3 = p1;
printf("%c %pn", *p3, p3);
*p1 = *p2;
printf("%c %pn", *p1, p1 );
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Exemplos
int *p;
int i;
int k;
i = 42;
k = i;
p = &i;
 Qual dos seguintes comandos muda o valor de i para
75?
 k = 75;
 *k = 75;
 p = 75;
 *p = 75;
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Qual o valor de y?
int main()
{
int y, *p, x;
y = 0;
p = &y;
x = *p;
x = 4;
(*p)++;
x;
(*p) += x;
printf ("y = %dn", y);
return(0);
}
Rodrigo Paes – r0drigopaes@yahoo.com.br
Instituto de Computação – UFAL
Exercício: escreva a função ordenar
int main()
{
int a, b, c, d, e;
printf("Digite 05 numerosn");
scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
ordenar(&a,&b,&c,&d,&e);
printf("Os numeros ordenados em ordem decrescente sao:
%d, %d, %d, %d, %dn",a,b,c,d,e);
return 0;
}
Rodrigo Paes – r0drigopaes@yahoo.com.br
Instituto de Computação – UFAL
PONTEIROS E ARRAYS
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Lembra como você usa os arrays?
…
int array[9];
array[0] = 20;
printf(“%d”, array[0] );
…
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Por debaixo dos panos
 Uma variável array é um ponteiro constante
para uma área de memória onde os elementos
serão armazenados
int array[9];
*array = 20;
printf(“%d”, *array );
 Perceba que a variável array é um ponteiro para o
primeiro elemento
rodrigo@ic.ufal.br
20
array
Instituto de Computação – UFAL
E como acessar os outros elementos?
 Aritmética de ponteiros
int array[9];
*array = 20;
*(array +1) = 30;
*(array +2) = 40;
rodrigo@ic.ufal.br
20 30 40
array
32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits
Desloca 1 * sizeof(int) bytes
Desloca 2 * sizeof(int) bytes
Instituto de Computação – UFAL
Então …
 array[7]=96;
 É idêntico a fazer:
 *(array+7)=96;
 Podemos também:
int *p;
int array[5];
p = array;
p = &array[4];
p[-1] = 5;
printf("%dn",array[3]);
*(p-1) = 8;
printf("%dn",array[3]);
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Atenção
int *p;
p[3] = 8;
Certo ou errado?
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Quiz: pode ou não ? Qual a saída?
#include <stdio.h>
int main()
{
int a[10];
*a = 3;
a[1]= 4;
printf("%dn%dn",a[0],a[1]);
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Quiz: pode ou não? Qual a saída?
int main()
{
int a[10];
*a = 3;
a[1]= 4;
a++;
*a =5;
printf("%dn%dn",a[0],a[1]);
}
rodrigo@ic.ufal.br
Não podemos alterar o ponteiro
Instituto de Computação – UFAL
Passando arrays para funções
void funcao(int *a, int tamanho)
{
int i;
for (i=0; i< tamanho ; i++)
{
a[i] = i*i;
}
}
main()
{
int x[5];
funcao(x,5);
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Ponteiros para ponteiros
char a;
char * b;
char ** c;
a = 'z';
b = &a;
c = &b;
printf("%cn",a);
printf("%cn",*b);
printf("%cn",**c);
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Arrays bidimensionais :: estáticos
int array1[2][2] = {{0, 1}, {2, 3}};
…
Na memória:
0 1 2 3
O mesmo layout de:
int array2[4] = { 0, 1, 2, 3 };
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Arrays bidimensionais :: estáticos
 Um array 2D não é a mesma coisa que int**
 Array para ponteiros, só “funciona”
automaticamente no primeiro nível
 Logo:
 int array1[2][2] = {{0, 1}, {2, 3}};
 void function2(int a[][2]); ou:
 void function2(int a[2][2]);
 Diferente para alocação dinâmica
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Alocação dinâmica
 Muitas vezes só sabemos o tamanho do nosso
array durante a execução do programa
 Usar esta abordagem permite protelar a decisão
sobre o tamanho do bloco de memória
necessário para armazenar um array
 Quando aquela memória não é mais necessária,
ela pode ser liberada para outros usos
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Alocação dinâmica
 Exemplo. Alocação de um array com 10 inteiros
int *iptr;
iptr = (int *)malloc(10 * sizeof(int));
if (iptr == NULL)
{
... Rotina de erro vem aqui ...
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Alocação dinâmica e arrays
int *iptr;
iptr = (int *)malloc(10 * sizeof(int));
if (iptr == NULL)
{
... Rotina de erro vem aqui ...
}
int k;
for (k = 0; k < 10; k++)
iptr[k] = 2;
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Alocar uma matriz de inteiros
int **mi;
int row,col;
mi = malloc (ROWS * sizeof (int *));
for (row = 0; row < ROWS; row++)
{
mi[row] = malloc (COLS * sizeof (int));
}
for (row = 0; row < ROWS; row++)
{
for (col = 0; col < COLS; col++)
{
mi[row][col] = 17;
}
}
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Alocar uma matriz de inteiros ::
continuamente
 https://dl.dropbox.com/u/17364381/p1/alocacao
_continua_matriz.c
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Realocação
https://dl.dropbox.com/u/17364381/p1/realloc.c
rodrigo@ic.ufal.br
Instituto de Computação – UFAL
Liberar a memória
/* free example */
#include <stdlib.h> /* malloc, calloc, realloc, free */
int main ()
{
int * buffer1, * buffer2, * buffer3;
buffer1 = (int*) malloc (100*sizeof(int));
buffer2 = (int*) calloc (100,sizeof(int));
buffer3 = (int*) realloc (buffer2,500*sizeof(int));
free (buffer1);
free (buffer3);
return 0;
}
rodrigo@ic.ufal.br

Aula 13 ponteiros - Programação 1

  • 1.
  • 2.
    Instituto de Computação– UFAL Exercício em sala  Objetivo: ler 03 numeros nas variaveis x,y e z e depois ordenar x,y e z de tal forma que x armazene o menor valor, y o intermediário e z o maior rodrigo@ic.ufal.br
  • 3.
    Instituto de Computação– UFAL Código repetido  O que queremos com esses 03 trechos?  Trocar os valores de duas variáveis, correto?  Ou seja, queriamos isolar uma funcionalidade  Uma função de trocar valores rodrigo@ic.ufal.br
  • 4.
    Instituto de Computação– UFAL Não seria melhor assim?  Ok … vamos tentar rodrigo@ic.ufal.br trocar(x,y) trocar(x,z) trocar(y,z)
  • 5.
    Instituto de Computação– UFAL Tentativa 01  funcao_trocar_valores2.c rodrigo@ic.ufal.br
  • 6.
    Instituto de Computação– UFAL Os valores foram trocados?  Não, né?  Passagem por valor  A passagem de parâmetro foi feita por valor  É feita uma cópia do valor da variável rodrigo@ic.ufal.br
  • 7.
    Instituto de Computação– UFAL Passagem por valor rodrigo@ic.ufal.br
  • 8.
    Instituto de Computação– UFAL Ponteiros  Ao declarar uma variável sempre informamos o tipo dela  int a;  float soma;  …  Lembra da 1a aula?  As variáveis ficam na memória  Endereço e Conteúdo rodrigo@ic.ufal.br
  • 9.
    Instituto de Computação– UFAL Variáveis  Já sabemos alterar o conteúdo das variáveis  Comando de atribuição  resto = 25;  soma =soma + i;  …  Mas como descobrir o endereço de memória das nossas variáveis? rodrigo@ic.ufal.br En d. Conteúdo 1 34 2 “O rato roeu a roupa do rei de roma” 3 34.67 4 1 5 0 6 “aula de p1” 7 4677 … 123 n
  • 10.
    Instituto de Computação– UFAL Operador &  Este operador nos fornece o endereço de memória de uma variável  Exemplo: main() { int a = 1; printf("O endereco de a eh: %pn",&a); } rodrigo@ic.ufal.br
  • 11.
    Instituto de Computação– UFAL Um novo tipo de variável: ponteiro  O tipo da variável define os valores válidos para uma variável  Exemplo  int: valores inteiros  char: caracteres  float: ponto flutuante  …  Um ponteiro é um tipo de variável cujos valores válidos são endereços de memória rodrigo@ic.ufal.br
  • 12.
    Instituto de Computação– UFAL Como funciona?  Imagine uma caixa postal  Caixa postal 22300  A caixa postal é só um endereço  Ela aponta para uma localização que contém um imóvel (conteúdo)  Os imóveis podem ser de vários tipos  Residencial casa, residencial apartamento, comercial …  Ou seja, a caixa postal contém um endereço para um conteúdo de um determinado tipo  A caixa postal é um ponteiro rodrigo@ic.ufal.br
  • 13.
    Instituto de Computação– UFAL … voltando ao C  Um ponteiro é um endereço para um determinado tipo  int  float  char  outro ponteiro  … rodrigo@ic.ufal.br
  • 14.
    Instituto de Computação– UFAL Ponteiros Endereço Identificador Conteúdo 0xFF4454 a 5 … … … … … … … … … … … … 0xBBA031 b 12 rodrigo@ic.ufal.br ponteiro_a
  • 15.
    Instituto de Computação– UFAL Declaração de ponteiros main() { int a = 1; int b = 2; int *pt_a; … rodrigo@ic.ufal.br
  • 16.
    Instituto de Computação– UFAL Atribuição com ponteiro main() { int a = 1; int b = 2; int *meu_ponteiro; meu_ponteiro = &a; // atribui o endereço de a … rodrigo@ic.ufal.br
  • 17.
    Instituto de Computação– UFAL Acesso ao conteúdo do local apontado pelo ponteiro: *, o operador de “dereference” main() { int a = 1; int b = 2; int *pt_a; pt_a = &a; *pt_a = 50; // o que vai acontecer aqui? … rodrigo@ic.ufal.br
  • 18.
    Instituto de Computação– UFAL Brincando com ponteiros  ponteiros.c rodrigo@ic.ufal.br
  • 19.
    Instituto de Computação– UFAL Interessante né? mas e daí?  Vamos voltar para a nossa função de troca rodrigo@ic.ufal.br E se … •na nossa função recebessemos os endereços das variáveis que desejamos trocar •Com o endereço, poderíamos trocar os valores
  • 20.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux --- a b void trocar_valores(float *a, float *b) { float aux;
  • 21.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a;
  • 22.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b;
  • 23.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b;
  • 24.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b; *b = aux; }
  • 25.
    Instituto de Computação– UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 5 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b; *b = aux; }
  • 26.
    Instituto de Computação– UFAL Ideia  Ao sair … do escopo local as variáveis são eliminadas rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 5 0xBBA031 z 2if (y < z) // neste caso y é o menor { // troca os conteúdos de x e de y trocar_valores(&x,&y); } else // neste caso z é o menor
  • 27.
    Instituto de Computação– UFAL O programa completo  funcao_trocar_valores3.c rodrigo@ic.ufal.br
  • 28.
    Instituto de Computação– UFAL Passagem por referência  O que acabamos de fazer foi passar os parâmetros por referência ao invés de passar por valor  Passamos apenas uma referência para a variável externa  O seu valor não é copiado  Mais eficiente  Exige cuidados com efeitos colaterais rodrigo@ic.ufal.br
  • 29.
    Instituto de Computação– UFAL Algumas reflexões  Pra que ponteiros?  C é de uma época em que os computadores eram menos poderosos  Necessidade de uso eficiente de processamento e memória  Logo, habilidade de trabalhar diretamente a memória é muito útil  E por que ainda usamos ponteiros?  Necessidade de eficiência ainda é importante rodrigo@ic.ufal.br
  • 30.
    Instituto de Computação– UFAL Exemplos main() { int x = 7 ; int *px ; px = &x ; *px = 8 ; printf( "%dn" , x ) ; printf( "%dn" , &x ) ; printf( "%dn" , px ) ; printf( "%dn" , *px ) ; } rodrigo@ic.ufal.br
  • 31.
    Instituto de Computação– UFAL Exemplos void exemplo2() { int firstvalue, secondvalue; int * mypointer; mypointer = &firstvalue; *mypointer = 10; mypointer = &secondvalue; *mypointer = 20; printf("%dn",firstvalue); printf("%dn",secondvalue); } rodrigo@ic.ufal.br
  • 32.
    Instituto de Computação– UFAL Exemplos void exemplo3() { int firstvalue = 5, secondvalue = 15; int * p1, * p2; p1 = &firstvalue; p2 = &secondvalue; *p1 = 10; *p2 = *p1; p1 = p2; *p1 = 20; printf("%dn",firstvalue); printf("%dn",secondvalue); } rodrigo@ic.ufal.br
  • 33.
    Instituto de Computação– UFAL Exemplos  Assuma que os seguintes endereços:  c é 1  d é 2  e é 3  Qual a saída do programa abaixo: char c = 'T', d = 'S'; char *p1 = &c; char *p2 = &d; char *p3; p3 = &d; printf("%cn",*p3); p3 = p1; printf("%c %pn", *p3, p3); *p1 = *p2; printf("%c %pn", *p1, p1 ); rodrigo@ic.ufal.br
  • 34.
    Instituto de Computação– UFAL Exemplos int *p; int i; int k; i = 42; k = i; p = &i;  Qual dos seguintes comandos muda o valor de i para 75?  k = 75;  *k = 75;  p = 75;  *p = 75; rodrigo@ic.ufal.br
  • 35.
    Instituto de Computação– UFAL Qual o valor de y? int main() { int y, *p, x; y = 0; p = &y; x = *p; x = 4; (*p)++; x; (*p) += x; printf ("y = %dn", y); return(0); } Rodrigo Paes – r0drigopaes@yahoo.com.br
  • 36.
    Instituto de Computação– UFAL Exercício: escreva a função ordenar int main() { int a, b, c, d, e; printf("Digite 05 numerosn"); scanf("%d%d%d%d%d",&a,&b,&c,&d,&e); ordenar(&a,&b,&c,&d,&e); printf("Os numeros ordenados em ordem decrescente sao: %d, %d, %d, %d, %dn",a,b,c,d,e); return 0; } Rodrigo Paes – r0drigopaes@yahoo.com.br
  • 37.
    Instituto de Computação– UFAL PONTEIROS E ARRAYS rodrigo@ic.ufal.br
  • 38.
    Instituto de Computação– UFAL Lembra como você usa os arrays? … int array[9]; array[0] = 20; printf(“%d”, array[0] ); … rodrigo@ic.ufal.br
  • 39.
    Instituto de Computação– UFAL Por debaixo dos panos  Uma variável array é um ponteiro constante para uma área de memória onde os elementos serão armazenados int array[9]; *array = 20; printf(“%d”, *array );  Perceba que a variável array é um ponteiro para o primeiro elemento rodrigo@ic.ufal.br 20 array
  • 40.
    Instituto de Computação– UFAL E como acessar os outros elementos?  Aritmética de ponteiros int array[9]; *array = 20; *(array +1) = 30; *(array +2) = 40; rodrigo@ic.ufal.br 20 30 40 array 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits Desloca 1 * sizeof(int) bytes Desloca 2 * sizeof(int) bytes
  • 41.
    Instituto de Computação– UFAL Então …  array[7]=96;  É idêntico a fazer:  *(array+7)=96;  Podemos também: int *p; int array[5]; p = array; p = &array[4]; p[-1] = 5; printf("%dn",array[3]); *(p-1) = 8; printf("%dn",array[3]); rodrigo@ic.ufal.br
  • 42.
    Instituto de Computação– UFAL Atenção int *p; p[3] = 8; Certo ou errado? rodrigo@ic.ufal.br
  • 43.
    Instituto de Computação– UFAL Quiz: pode ou não ? Qual a saída? #include <stdio.h> int main() { int a[10]; *a = 3; a[1]= 4; printf("%dn%dn",a[0],a[1]); } rodrigo@ic.ufal.br
  • 44.
    Instituto de Computação– UFAL Quiz: pode ou não? Qual a saída? int main() { int a[10]; *a = 3; a[1]= 4; a++; *a =5; printf("%dn%dn",a[0],a[1]); } rodrigo@ic.ufal.br Não podemos alterar o ponteiro
  • 45.
    Instituto de Computação– UFAL Passando arrays para funções void funcao(int *a, int tamanho) { int i; for (i=0; i< tamanho ; i++) { a[i] = i*i; } } main() { int x[5]; funcao(x,5); } rodrigo@ic.ufal.br
  • 46.
    Instituto de Computação– UFAL Ponteiros para ponteiros char a; char * b; char ** c; a = 'z'; b = &a; c = &b; printf("%cn",a); printf("%cn",*b); printf("%cn",**c); rodrigo@ic.ufal.br
  • 47.
    Instituto de Computação– UFAL Arrays bidimensionais :: estáticos int array1[2][2] = {{0, 1}, {2, 3}}; … Na memória: 0 1 2 3 O mesmo layout de: int array2[4] = { 0, 1, 2, 3 }; rodrigo@ic.ufal.br
  • 48.
    Instituto de Computação– UFAL Arrays bidimensionais :: estáticos  Um array 2D não é a mesma coisa que int**  Array para ponteiros, só “funciona” automaticamente no primeiro nível  Logo:  int array1[2][2] = {{0, 1}, {2, 3}};  void function2(int a[][2]); ou:  void function2(int a[2][2]);  Diferente para alocação dinâmica rodrigo@ic.ufal.br
  • 49.
    Instituto de Computação– UFAL Alocação dinâmica  Muitas vezes só sabemos o tamanho do nosso array durante a execução do programa  Usar esta abordagem permite protelar a decisão sobre o tamanho do bloco de memória necessário para armazenar um array  Quando aquela memória não é mais necessária, ela pode ser liberada para outros usos rodrigo@ic.ufal.br
  • 50.
    Instituto de Computação– UFAL Alocação dinâmica  Exemplo. Alocação de um array com 10 inteiros int *iptr; iptr = (int *)malloc(10 * sizeof(int)); if (iptr == NULL) { ... Rotina de erro vem aqui ... } rodrigo@ic.ufal.br
  • 51.
    Instituto de Computação– UFAL Alocação dinâmica e arrays int *iptr; iptr = (int *)malloc(10 * sizeof(int)); if (iptr == NULL) { ... Rotina de erro vem aqui ... } int k; for (k = 0; k < 10; k++) iptr[k] = 2; rodrigo@ic.ufal.br
  • 52.
    Instituto de Computação– UFAL Alocar uma matriz de inteiros int **mi; int row,col; mi = malloc (ROWS * sizeof (int *)); for (row = 0; row < ROWS; row++) { mi[row] = malloc (COLS * sizeof (int)); } for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) { mi[row][col] = 17; } } rodrigo@ic.ufal.br
  • 53.
    Instituto de Computação– UFAL Alocar uma matriz de inteiros :: continuamente  https://dl.dropbox.com/u/17364381/p1/alocacao _continua_matriz.c rodrigo@ic.ufal.br
  • 54.
    Instituto de Computação– UFAL Realocação https://dl.dropbox.com/u/17364381/p1/realloc.c rodrigo@ic.ufal.br
  • 55.
    Instituto de Computação– UFAL Liberar a memória /* free example */ #include <stdlib.h> /* malloc, calloc, realloc, free */ int main () { int * buffer1, * buffer2, * buffer3; buffer1 = (int*) malloc (100*sizeof(int)); buffer2 = (int*) calloc (100,sizeof(int)); buffer3 = (int*) realloc (buffer2,500*sizeof(int)); free (buffer1); free (buffer3); return 0; } rodrigo@ic.ufal.br