Ponteiros
Yuri Tavares dos Passos
Arquitetura de Von
Neumann
● Os computadores pessoais utilizam uma
arquitetura que é baseada na arquitetura de
Von Neumann...
Arquitetura de Von
Neumann
Busca e
executa
Lê e escreve
Arquitetura de Von
Neumann
Dados
Código
Código
Dados
Código
Dados
Memória Principal
Busca e
executa
Lê e escreve
Arquitetura de Von
Neumann
● Suponha uma memória RAM com
capacidade de 8 B. Ela pode ser
endereçada dos endereços 0 a 7, c...
Arquitetura de Von
Neumann
● Suponha uma memória RAM com
capacidade de 8 B. Ela pode ser
endereçada dos endereços 0 a 7, c...
Arquitetura de Von
Neumann
16
MOVE 16 0x19
SOME 0x21 0x19
3.89
MOVE 0x19 0x24
?
Memória PrincipalEndereços
0x19
0x21
0x20
...
Arquitetura de Von
Neumann
00010000
01010101
10100010
00100111
01010101
00010000
Memória PrincipalEndereços
0x19
0x21
0x20...
Arquitetura de Von
Neumann
16
MOVE 16 0x19
SOME 0x21 0x19
3.89
MOVE 0x19 0x24
?
Memória PrincipalEndereços
0x19
0x21
0x20
...
Ponteiro
● Como manipular endereços de memória no
código-fonte?
– Utilizando um tipo de variável para endereços.
● Um pont...
Ponteiros
● Aplicações de ponteiros:
– Estruturas de dados mais eficientes.
– Aplicações que envolvam a organização dos da...
Ponteiro
16
3.98
SOME 0x24 0x19
0x20
MOVE 0x19 0x24
0x22
0x19
0x21
0x20
0x22
0x23
0x24
São variáveis
que apontam
para outr...
Ponteiro
● Nos exemplos acima, os endereços
possuíam 1 B de tamanho.
● Quantos valores podem ser armazenados
com 1 B?
Ponteiro
● Nos exemplos acima, os endereços
possuíam 1 B de tamanho.
● Quantos valores podem ser armazenados
com 1 B?
– Re...
Ponteiro
● Suponha um computador de 1 GB.
● Ela pode possuir 1073741824 endereços de
1 B distintos. Para representar o mai...
Ponteiro
● Outro detalhe do exemplo de máquina
apresentado é o tamanho dos nossos
dados. Quantos bytes eles usam?
16
MOVE ...
Ponteiro
● Qual tipo de dado em C possui 1 B?
Ponteiro
● Qual tipo de dado em C possui 1 B?
● Resp.: char e unsigned char
Ponteiro
● Os tipos básicos de C possuem todos 1 B?
Tipos básicos Tamanho Precisão
char -> p/ caracteres 1 byte - 128 a + 127
int -> p/ inteiros 4 bytes* -2147483648 a
214748...
Ponteiro
● Considere o seguinte código:
Ponteiro
● Vamos pegar um número inteiro, como 0.
Em uma célula de 4 B (= 32 b), temos
como representação binária 32 zeros...
Ponteiro
● Um caractere como 'a', na tabela de
conversão ASCII é igual ao número 65.
Como binário temos 01000001.
– Em hex...
Ponteiro
0xbff43513
0xbff43514
0xbff43515
0xbff43516
0xbff43517
0xbff43518
0xbff43519
0xbff4351a
0xbff4351b
00000000
00000...
Ponteiro
● O endereço do inteiro a é 0xbff43513. Mas
o inteiro vai de 0xbff43513 a 0xbff43516
● O endereço do caractere c ...
Ponteiro
● Assim, um ponteiro além de armazenar o
endereço de uma variável também possui o
tamanho do dado daquela variáve...
Ponteiro
Ponteiro
● Para obter o endereço de memória de uma
variável utiliza-se o operador &.
● A sintaxe deste operador é:
& <vari...
Ponteiro
Ponteiro
● Para acessar o conteúdo do que um ponteiro
está apontando, usa-se *.
● A operação que realiza o acesso a algum ...
Ponteiro
Ponteiro
● Se fosse para escrever na tela os
endereços onde as variáveis ponteiros pa,
pb e pc estão o que deveria ser fei...
Ponteiro
Atribuições e tipos
● Em um compilador, o tipo de dado do lado
esquerdo de uma atribuição deve ser igual
ao tipo do result...
Atribuições e tipos
● Exemplo 2:
a = 0 - b;
● Exemplo 3:
float f = 3.14 * 4.0 / a ;
int int
float float
Atribuições e tipos
● Quando utilizamos o operador &, o
resultado é um endereço para a variável
aplicada a este operador.
...
Atribuições e tipos
● Para declaramos uma variável p1 ponteiro
para o tipo caractere fazemos:
char * p1;
● Para declaramos...
Atribuições e tipos
● A regra de igualdade entre tipos nos dois
lados de uma atribuição também funciona
para ponteiros.
● ...
Atribuições e tipos
● Exemplo 2:
float f = 3.14;
float *p;
p = &f;
● Exemplo 3:
int b = 13;
char * pi;
pi = &b;
float* = &...
Atribuições e tipos
● Quando utilizamos o operador *, o resultado
é um conteúdo para o mesmo tipo que o
ponteiro deve apon...
Atribuições e tipos
● Exemplo 1:
– char c = 'b';
char d;
char *p = &c;
d = *p;
char = * char*
Sabendo-se que * <ponteiro p...
Atribuições e tipos
● Exemplo 2:
int x = 9, y;
int *p = &x;
y = 2 + *p;
int = int + * int*
int = int + int
int = int
Qual ...
Atribuições e tipos
● Exemplo 3:
long l1 = 2E12;
long *p1 = &l1;
l1 = 2 * *p1;
long = long * * long*
long = long * long
lo...
Atribuições e tipos
● Exemplo 4:
long l1 = 2000, l2 = 0;
long *p1, *p2;
p1 = &l1;
p2 = &l2;
*p2 = 2 * *p1;
Existe algo de ...
Atribuições e tipos
● Exemplo 4:
long l1 = 2000, l2 = 0;
long *p1, *p2;
p1 = &l1;
p2 = &l2;
*p2 = 2 * *p1;
printf(“%in”,l2...
Observação sobre * e &
● Observação
– Os operadores & e * não podem ser apliados
a constantes.
● Exemplo:
int * p = &12;
–...
Observação sobre * e &
● Exemplo:
char c = * 0x5623;
– Interpretando este exemplo em linguagem
humana estaríamos dizendo q...
Ponteiro sem tipo
● Existe também um tipo de ponteiro que não está
associado a nenhum tipo de variável: void *.
● Este tip...
Conversão entre tipos
● Existem dois tipos de conversões
– Implícitas
– Explícitas
● As conversões ímplicitas são feitas
a...
Conversão implícita
● Exemplo:
int i = 1;
float f = i;
Isto está errado?
Conversão implícita
● Exemplo:
int i = 1;
float f = i;
printf(“%fn”,f);
Que valor será escrito na tela?
Conversão implícita
● Exemplo:
int i = 1;
float f = i;
float int
ℤ
ℝ
Conversão implícita
● Exemplo:
int i = 1;
float f = (float) i;
● Foi realizada uma conversão implícita de
inteiro para rea...
Conversão implícita
char
int
float
double
Conversão implícita
● O compilador gcc não acusa erro se for
esquecida a conversão de um tipo mais
abrangente para um tipo...
Conversão explícita
● A conversão explícita ocorre quando se
deseja forçar a conversão entre tipos.
● Utiliza-se o nome do...
Conversão explícita
● É útil quando se sabe que tipo de dado está armazenado
em uma certa variável, evitando os avisos dos...
Incremento e decremento
● Ao se utilizar adição e subtração com
ponteiros o comportamento destas
operações serão diferente...
Incremento e decremento
● Exemplo 1:
Incremento e decremento
● No Exemplo 1, o valor do ponteiro pchar é
aumentado de 1 como é feito normalmente
com o ++.
● Ve...
Incremento e decremento
● Exemplo 2:
Incremento e decremento
● Exemplo 3:
Exercícios
1) Escreva um programa com sizeof e
verifique o tamanho dos seguintes tipos de
dados: unsigned int *, int *, lo...
Exercícios
2) Por que o tamanho dos ponteiros da
questão 1 são iguais apesar de serem
ponteiros para tipos diferentes?
Exercícios
● Lista!
Próximos SlideShares
Carregando em…5
×

Aula04 ponteiros e conversao

459 visualizações

Publicada em

Ponteiro e conversão de tipos em C

Publicada em: Ciências
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Aula04 ponteiros e conversao

  1. 1. Ponteiros Yuri Tavares dos Passos
  2. 2. Arquitetura de Von Neumann ● Os computadores pessoais utilizam uma arquitetura que é baseada na arquitetura de Von Neumann. ● Esta arquitetura se baseia na utilização de um mesmo bloco de memória para armazenar dados e código executável. ● O processador fica responsável por buscar código na mesma memória em que busca por um dado.
  3. 3. Arquitetura de Von Neumann Busca e executa Lê e escreve
  4. 4. Arquitetura de Von Neumann Dados Código Código Dados Código Dados Memória Principal Busca e executa Lê e escreve
  5. 5. Arquitetura de Von Neumann ● Suponha uma memória RAM com capacidade de 8 B. Ela pode ser endereçada dos endereços 0 a 7, cada um com a capacidade de 1 B. 1 B 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 E se ela tivesse 1GB, iria do Endereço 0 a qual número decimal? E hexadecimal?
  6. 6. Arquitetura de Von Neumann ● Suponha uma memória RAM com capacidade de 8 B. Ela pode ser endereçada dos endereços 0 a 7, cada um com a capacidade de 1 B. 1 B 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 E se ela tivesse 1GB, iria do Endereço 0 a qual número decimal? Resp.: 1073741823 E em hexadecimal? Resp.: 3FFFFFFF
  7. 7. Arquitetura de Von Neumann 16 MOVE 16 0x19 SOME 0x21 0x19 3.89 MOVE 0x19 0x24 ? Memória PrincipalEndereços 0x19 0x21 0x20 0x22 0x23 0x24
  8. 8. Arquitetura de Von Neumann 00010000 01010101 10100010 00100111 01010101 00010000 Memória PrincipalEndereços 0x19 0x21 0x20 0x22 0x23 0x24
  9. 9. Arquitetura de Von Neumann 16 MOVE 16 0x19 SOME 0x21 0x19 3.89 MOVE 0x19 0x24 ? Memória PrincipalEndereços 0x19 0x21 0x20 0x22 0x23 0x24 Esta instrução envolve o uso de um endereço e um valor. Esta instrução envolve apenas endereços.
  10. 10. Ponteiro ● Como manipular endereços de memória no código-fonte? – Utilizando um tipo de variável para endereços. ● Um ponteiro ou apontador é uma variável que guarda endereços de memória. ● Endereços de memória são valores inteiros que podem ser armazenados e utilizados no código.
  11. 11. Ponteiros ● Aplicações de ponteiros: – Estruturas de dados mais eficientes. – Aplicações que envolvam a organização dos dados. – Aplicações que devem ser rápidas. – Alocação dinâmica de memória. – Acessar variáveis que não são visíveis em uma função. – Retornar mais de um valor para uma função. ● A tentativa de evitar o uso de ponteiros implicará quase sempre códigos maiores e de execução mais lenta.
  12. 12. Ponteiro 16 3.98 SOME 0x24 0x19 0x20 MOVE 0x19 0x24 0x22 0x19 0x21 0x20 0x22 0x23 0x24 São variáveis que apontam para outras
  13. 13. Ponteiro ● Nos exemplos acima, os endereços possuíam 1 B de tamanho. ● Quantos valores podem ser armazenados com 1 B?
  14. 14. Ponteiro ● Nos exemplos acima, os endereços possuíam 1 B de tamanho. ● Quantos valores podem ser armazenados com 1 B? – Resp.: 1 B = 8 b 28 = 256 ● Quantos Bytes as memórias vendidas no comércio possuem?
  15. 15. Ponteiro ● Suponha um computador de 1 GB. ● Ela pode possuir 1073741824 endereços de 1 B distintos. Para representar o maior endereço (3FFFFFFF), precisamos de 4 B. ● Portanto, para armarzenarmos um endereço numa máquina atual, precisaremos de 4 B ou mais!
  16. 16. Ponteiro ● Outro detalhe do exemplo de máquina apresentado é o tamanho dos nossos dados. Quantos bytes eles usam? 16 MOVE 16 0x19 SOME 0x21 0x19 3.89 MOVE 0x19 0x24 0 0x19 0x21 0x20 0x22 0x23 0x24
  17. 17. Ponteiro ● Qual tipo de dado em C possui 1 B?
  18. 18. Ponteiro ● Qual tipo de dado em C possui 1 B? ● Resp.: char e unsigned char
  19. 19. Ponteiro ● Os tipos básicos de C possuem todos 1 B?
  20. 20. Tipos básicos Tamanho Precisão char -> p/ caracteres 1 byte - 128 a + 127 int -> p/ inteiros 4 bytes* -2147483648 a 2147483647 float -> p/ reais 4 bytes* -3.4E-38 a +3.4E+38 double -> p/ reais 8 bytes* -1.7E-308 a +1.7E+308 * Variam a depender do processador Tipos de dados básicos
  21. 21. Ponteiro ● Considere o seguinte código:
  22. 22. Ponteiro ● Vamos pegar um número inteiro, como 0. Em uma célula de 4 B (= 32 b), temos como representação binária 32 zeros consecutivos. ● Um número inteiro como 1465232370 temos como representação binária 01010111010101011010101111110010 – Em hexadecimal: 5755ABF2
  23. 23. Ponteiro ● Um caractere como 'a', na tabela de conversão ASCII é igual ao número 65. Como binário temos 01000001. – Em hexadecimal: 41 ● O bloco de memória do código apresentado seria como apresentado a seguir.
  24. 24. Ponteiro 0xbff43513 0xbff43514 0xbff43515 0xbff43516 0xbff43517 0xbff43518 0xbff43519 0xbff4351a 0xbff4351b 00000000 00000000 00000000 00000000 01010111 01010101 10101011 11110010 01000001 } a = 0 } b = 1465232370 } c = 'a'
  25. 25. Ponteiro ● O endereço do inteiro a é 0xbff43513. Mas o inteiro vai de 0xbff43513 a 0xbff43516 ● O endereço do caractere c é 0xbff4351b. Apenas este endereço é suficiente para guardá-lo. ● Além do endereço, o programa precisa saber o tamanho do dado que aquele endereço armazena.
  26. 26. Ponteiro ● Assim, um ponteiro além de armazenar o endereço de uma variável também possui o tamanho do dado daquela variável. ● Para se declarar uma variável do tipo ponteiro utiliza-se o símbolo * após o tipo de dado que este ponteiro deve apontar. ● A sintaxe de declaração é: <tipo de dado> * <nome do ponteiro>;
  27. 27. Ponteiro
  28. 28. Ponteiro ● Para obter o endereço de memória de uma variável utiliza-se o operador &. ● A sintaxe deste operador é: & <variável>
  29. 29. Ponteiro
  30. 30. Ponteiro ● Para acessar o conteúdo do que um ponteiro está apontando, usa-se *. ● A operação que realiza o acesso a algum dado apontado por um ponteiro é conhecida como desreferenciamento. – Um endereço de memória é uma referência a um dado. ● Dentro de expressões, a sintaxe é: * <variável ponteiro>
  31. 31. Ponteiro
  32. 32. Ponteiro ● Se fosse para escrever na tela os endereços onde as variáveis ponteiros pa, pb e pc estão o que deveria ser feito?
  33. 33. Ponteiro
  34. 34. Atribuições e tipos ● Em um compilador, o tipo de dado do lado esquerdo de uma atribuição deve ser igual ao tipo do resultado do lado direito. ● Exemplo 1: c = 'b'; char char
  35. 35. Atribuições e tipos ● Exemplo 2: a = 0 - b; ● Exemplo 3: float f = 3.14 * 4.0 / a ; int int float float
  36. 36. Atribuições e tipos ● Quando utilizamos o operador &, o resultado é um endereço para a variável aplicada a este operador. ● Se temos: &<variável>; ● O operador & retorna um tipo igual a “ponteiro do tipo da” <variável>.
  37. 37. Atribuições e tipos ● Para declaramos uma variável p1 ponteiro para o tipo caractere fazemos: char * p1; ● Para declaramos uma variável p2 ponteiro para o tipo inteiro fazemos: int * p2; ● Assim, podemos usar o * para denotar o tipo ponteiro de algum tipo.
  38. 38. Atribuições e tipos ● A regra de igualdade entre tipos nos dois lados de uma atribuição também funciona para ponteiros. ● Exemplo 1: char c = 'a'; char *p; p = &c; char* = & char Sabendo-se que & <tipo> = <tipo>*, temos: char* = char*
  39. 39. Atribuições e tipos ● Exemplo 2: float f = 3.14; float *p; p = &f; ● Exemplo 3: int b = 13; char * pi; pi = &b; float* = & float float* = float* char* = & int char* = int* ERRADO!
  40. 40. Atribuições e tipos ● Quando utilizamos o operador *, o resultado é um conteúdo para o mesmo tipo que o ponteiro deve apontar. ● Se temos: * <variável ponteiro>; ● O operador * retorna um tipo igual ao tipo do ponteiro, sem um asterisco. Ou seja, ele remove o termo “ponteiro” para aquele tipo.
  41. 41. Atribuições e tipos ● Exemplo 1: – char c = 'b'; char d; char *p = &c; d = *p; char = * char* Sabendo-se que * <ponteiro para tipo> = <tipo>, temos: char = char O * em preto representa o operador desreferenciamento. O * em vermelho representa o tipo “ponteiro de”.
  42. 42. Atribuições e tipos ● Exemplo 2: int x = 9, y; int *p = &x; y = 2 + *p; int = int + * int* int = int + int int = int Qual o valor de y?
  43. 43. Atribuições e tipos ● Exemplo 3: long l1 = 2E12; long *p1 = &l1; l1 = 2 * *p1; long = long * * long* long = long * long long = long Qual o valor de l1?
  44. 44. Atribuições e tipos ● Exemplo 4: long l1 = 2000, l2 = 0; long *p1, *p2; p1 = &l1; p2 = &l2; *p2 = 2 * *p1; Existe algo de errado na última expressão?
  45. 45. Atribuições e tipos ● Exemplo 4: long l1 = 2000, l2 = 0; long *p1, *p2; p1 = &l1; p2 = &l2; *p2 = 2 * *p1; printf(“%in”,l2); Qual o valor aparecerá na tela?
  46. 46. Observação sobre * e & ● Observação – Os operadores & e * não podem ser apliados a constantes. ● Exemplo: int * p = &12; – Isto não é possível pois a constante 12 não está armazenada em nenhum endereço.
  47. 47. Observação sobre * e & ● Exemplo: char c = * 0x5623; – Interpretando este exemplo em linguagem humana estaríamos dizendo que o valor de c será igual ao valor do byte que estiver no endereço 0x5623. – Mas o S.O. protege este endereço, pois ele pode estar sendo utilizado por outro programa, evitando falha de segurança.
  48. 48. Ponteiro sem tipo ● Existe também um tipo de ponteiro que não está associado a nenhum tipo de variável: void *. ● Este tipo é utilizado quando se deseja acessar um endereço de memória ignorando o tipo de dado que existe neste endereço. ● Exemplo de declaração: void * p; void * bloco_de_memória; ● Contudo, atribuições para este tipo de variável necessitam de conversões explícitas para void*.
  49. 49. Conversão entre tipos ● Existem dois tipos de conversões – Implícitas – Explícitas ● As conversões ímplicitas são feitas automaticamente pelo compilador, quando o tipo convertido é um subconjunto do tipo a ser atribuído.
  50. 50. Conversão implícita ● Exemplo: int i = 1; float f = i; Isto está errado?
  51. 51. Conversão implícita ● Exemplo: int i = 1; float f = i; printf(“%fn”,f); Que valor será escrito na tela?
  52. 52. Conversão implícita ● Exemplo: int i = 1; float f = i; float int ℤ ℝ
  53. 53. Conversão implícita ● Exemplo: int i = 1; float f = (float) i; ● Foi realizada uma conversão implícita de inteiro para real.
  54. 54. Conversão implícita char int float double
  55. 55. Conversão implícita ● O compilador gcc não acusa erro se for esquecida a conversão de um tipo mais abrangente para um tipo menos abrangente. Mas você será avisado caso esteja fazendo. ● Exemplo: float f = 1.2; int i = f;
  56. 56. Conversão explícita ● A conversão explícita ocorre quando se deseja forçar a conversão entre tipos. ● Utiliza-se o nome do tipo a ser convertido entre parentêses. ● Exemplo: float f = 1.2; int i = (int) f;
  57. 57. Conversão explícita ● É útil quando se sabe que tipo de dado está armazenado em uma certa variável, evitando os avisos dos compiladores. ● Deve ser usado com extrema sabedoria, pois dados podem ser perdidos! – 0.0000122323 ≠ 0. ● Para se utilizar o ponteiro sem tipo, deve ser utilizada esta conversão. – Exemplo: char c = 'a'; void* p = (void*) &c;
  58. 58. Incremento e decremento ● Ao se utilizar adição e subtração com ponteiros o comportamento destas operações serão diferentes do apresentado anteriormente. ● A soma e a subtração são realizadas em unidades que correspondem ao tamanho em bytes do tipo de dado que aquele ponteiro faz referência.
  59. 59. Incremento e decremento ● Exemplo 1:
  60. 60. Incremento e decremento ● No Exemplo 1, o valor do ponteiro pchar é aumentado de 1 como é feito normalmente com o ++. ● Veja que o valor de pchar foi aumentado de apenas mais uma unidade.
  61. 61. Incremento e decremento ● Exemplo 2:
  62. 62. Incremento e decremento ● Exemplo 3:
  63. 63. Exercícios 1) Escreva um programa com sizeof e verifique o tamanho dos seguintes tipos de dados: unsigned int *, int *, long*, float*, void*. Responda: qual o tamanho de cada um?
  64. 64. Exercícios 2) Por que o tamanho dos ponteiros da questão 1 são iguais apesar de serem ponteiros para tipos diferentes?
  65. 65. Exercícios ● Lista!

×