Ponteiros - Aquiles Burlamaqui

Propaganda
Professor Aquiles Burlamaqui
UERN
PONTEIROS
Endereço
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
Célula
A memória
• Para um melhor entendimento do
uso de ponteiros na linguagem de
programação C é imprescindível
compreender o seu relacionamento
com a memória do computador em
que o programa esta executando.
• A memória é formada por várias
células. Cada celular contém um
endereço e um valor.
• O Tamanho do endereço e o
tamanho do valor depende da
arquitetura do computador (ex: 32
bits ou 64 bits).
Endereço
0000000D
Valor
??
Célula
Endereço
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
Variáveis Caracteres
int main() {
char i;
}
• Declaro um caractere chamado i. Os caracteres
ocupam 1 bytes na memória(para uma
arquitetura de 32 bits).
Endereço
Variáveis Inteiras
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
int main() {
int i;
}
• Declaro um inteiro chamado i. Os inteiros
ocupam 4 bytes na memória(para uma
arquitetura de 32 bits)
Endereço
Variáveis Flutuantes
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
int main() {
float i;
}
• Declaro um número ponto flutuante chamado
i. Os flutuantes ocupam 4 bytes na
memória(para uma arquitetura de 32 bits)
Endereço
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
Variáveis Flutuante Longo
i
int main() {
double i;
}
• Declaro um número ponto flutuante grande
chamado i. Os flutuantes ocupam 8 bytes na
memória(para uma arquitetura de 32 bits)
Endereço
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
Declaração de ponteiros
c
i
f
d
int main() {
char* c;
int* i;
float* f;
double d;
}
• Declaração
de
quatro
ponteiros(c,i,f e d).
• Cada ponteiro de um tipo
diferente(char, int, float, double).
• Todos eles ocupam o mesmo
espaço na memória, 4 bytes.
• Isso acontece porque todos eles
armazenam
endereços
de
memória, e o tamanho de um
endereço de memória é o mesmo
para todos os tipos.
Endereço
Exemplo 1
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
int main() {
int i;
i = 15;
char c = ‘s’;
int * p = &i;
*p = 25;
}
• Declaro um inteiro chamado i. Os inteiros
ocupam 4 bytes na memória(para uma
arquitetura de 32 bits)
Endereço
Exemplo 1
Valor
00000000
00
00000001
00
00000002
00
00000003
15
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
int main() {
int i;
i = 15;
char c = ‘s’;
int * p = &i;
*p = 25;
}
• Faço uma atribuição. A variável i recebe o
valor 15. Esse valor 15 é colocado no campo
valor da memória alocada previamente para a
variável i.
• Lembrem que essa notação com o 15 na
ultima casa é apenas didática na verdade esse
valor é armazenado utilizando a notação
complemento de 2(tudo em binário).
Endereço
Exemplo 1
Valor
00000000
00
00000001
00
00000002
00
00000003
15
00000004
s
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
c
int main() {
int i;
i = 15;
char c = ‘s’;
int * p = &i;
*p = 25;
}
• Variável c do tipo char criada e inicializada
com o valor ‘s’. Uma variável do tipo char ocupa
1 byte na memória em nossa arquitetura 32
bits.
Endereço
Exemplo 1
Valor
00000000
00
00000001
00
00000002
00
00000003
15
00000004
s
00000005
00
00000006
00
00000007
00
00000008
00
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
c
p
int main() {
int i;
i = 15;
char c = ‘s’;
int * p = &i;
*p = 25;
}
• Ponteiro de inteiro declarado.
• O nome desse ponteiro é p e ele é inicializada no
momento de sua criação.
• O valor que esse ponteiro recebe ao ser
inicializado é o endereço da variável i(&i) que
nesse caso é o endereço 000000.
• Dizemos que p aponta para i.
Endereço
Exemplo 1
Valor
00000000
00
00000001
00
00000002
00
00000003
25
00000004
s
00000005
00
00000006
00
00000007
00
00000008
00
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
i
c
p
int main() {
int i;
i = 15;
char c = ‘s’;
int * p = &i;
*p = 25;
}
• Finalizando,
fazemos
uma
atribuição.
Colocamos 25 no valor apontado por p. Como
visto no slide anterior p aponta para i. Desse
modo, colocamos 25 no valor da variável i.
Endereço
Exemplo 2
Valor
00000000
??
00000001
??
00000002
??
00000003
??
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
p1
int main() {
char * p1;
p1 = malloc(sizeof(char));
int * p2 = malloc(sizeof(int)*2);
*p2 = 55;
*(p2+1) = 11;
}
• Declaração de um ponteiro para char.
Endereço
Exemplo 2
Valor
00000000
00
00000001
00
00000002
00
00000003
04
00000004
??
00000005
??
00000006
??
00000007
??
00000008
??
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
p1
int main() {
char * p1;
p1 = malloc(sizeof(char));
int * p2 = malloc(sizeof(int)*2);
*p2 = 55;
*(p2+1) = 11;
}
• O ponteiro p1 recebe o endereço da primeira
posição do espaço reservado pela instrução
malloc(...). Nesse caso o malloc aloca 1 byte:
sizeof(char) é igual a 1.
• Dizemos que p1 aponta para o byte
reservado pelo malloc.
Endereço
Exemplo 2
Valor
00000000
00
00000001
00
00000002
00
00000003
04
00000004
??
00000005
00
00000006
00
00000007
00
00000008
09
00000009
??
0000000A
??
0000000B
??
0000000C
??
0000000D
??
0000000E
??
0000000F
??
00000010
??
p1
p2
int main() {
char * p1;
p1 = malloc(sizeof(char));
int * p2 = malloc(sizeof(int)*2);
*p2 = 55;
*(p2+1) = 11;
}
• Declaração de um ponteiro para
inteiro
(p2).
Esse
ponteiro
é
inicializado com o valor da primeira
posição do espaço alocado pelo
malloc.
• malloc(sizeof(int)*2)
aloca
4*2
bytes,ou seja 8 bytes. O espaço
equivalente a dois inteiros.
Endereço
Exemplo 2
Valor
00000000
00
00000001
00
00000002
00
00000003
04
00000004
??
00000005
00
00000006
00
00000007
00
00000008
09
00000009
00
0000000A
00
0000000B
00
0000000C
55
0000000D
??
0000000E
??
0000000F
??
00000010
??
p1
p2
int main() {
char * p1;
p1 = malloc(sizeof(char));
int * p2 = malloc(sizeof(int)*2);
*p2 = 55;
*(p2+1) = 11;
}
• O valor apontado por p2 recebe 55.
Endereço
Exemplo 2
Valor
00000000
00
00000001
00
00000002
00
00000003
04
00000004
??
00000005
00
00000006
00
00000007
00
00000008
09
00000009
00
0000000A
00
0000000B
00
0000000C
55
0000000D
00
0000000E
00
0000000F
00
00000010
11
p1
p2
*p2
*(p2+1)
int main() {
char * p1;
p1 = malloc(sizeof(char));
int * p2 = malloc(sizeof(int)*2);
*p2 = 55;
*(p2+1) = 11;
}
• A valor apontado por p2+1 recebe 11.
• Podemos
somar
ou
subtrair
do
ponteiro. Com isso podemos fazer com o
ponteiro aponte não somente para a
primeira posição que lhe foi reservado.
p2
=> 00000009
+ 1 (1 int => 4 bytes)
p2+1 0000000D
Endereço
Exemplo 3
Valor
00000000
00
00000001
00
00000002
00
00000003
04
00000004
B
00000005
O
00000006
L
00000007
A
• ----
00000008
S
Endereço
00000009
00
00000011
00
00000019
F
0000000A
00
00000012
00
0000001A
00
0000000B
00
00000013
00
0000001B
00
0000000C
0D
00000014
19
0000001C
04
0000000D
F
00000015
B
0000001D
B
0000000E
??
00000016
O
0000001E
O
0000000F
??
00000017
L
0000001F
L
00000010
??
00000018
A
00000020
A
p1
int main() {
char * p1 = malloc(sizeof(char)*5);
char * p2 = malloc(sizeof(char));
*p2 = ‘F’;
p1 = “BOLAS”;
char * p3 = malloc(sizeof(char)*6);
*p3 = *p2;
*(p3+1) = *p1;
*(p3+2) = *(p1+1);
}
p2
Valor
Endereço
p3
Valor
Download