Ponteiros
Yuri Tavares dos Passos
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.
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, 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?
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
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
Arquitetura de Von
Neumann
00010000
01010101
10100010
00100111
01010101
00010000
Memória PrincipalEndereços
0x19
0x21
0x20
0x22
0x23
0x24
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.
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.
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.
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
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?
– Resp.: 1 B = 8 b
28 = 256
● Quantos Bytes as memórias vendidas no
comércio possuem?
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!
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
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
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
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
consecutivos.
● Um número inteiro como 1465232370
temos como representação binária
01010111010101011010101111110010
– Em hexadecimal: 5755ABF2
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.
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'
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.
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>;
Ponteiro
Ponteiro
● Para obter o endereço de memória de uma
variável utiliza-se o operador &.
● A sintaxe deste operador é:
& <variável>
Ponteiro
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>
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 feito?
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 resultado do lado direito.
● Exemplo 1:
c = 'b';
char char
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.
● Se temos:
&<variável>;
● O operador & retorna um tipo igual a
“ponteiro do tipo da” <variável>.
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.
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*
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!
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.
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”.
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?
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?
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?
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?
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.
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.
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*.
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.
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 real.
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 menos
abrangente. Mas você será avisado caso
esteja fazendo.
● Exemplo:
float f = 1.2;
int i = f;
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;
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;
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.
Incremento e decremento
● Exemplo 1:
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.
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 *, long*, float*,
void*. Responda: qual o tamanho de cada
um?
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!

Aula04 ponteiros e conversao

  • 1.
  • 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.
    Arquitetura de Von Neumann Buscae executa Lê e escreve
  • 4.
  • 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.
    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.
    Arquitetura de Von Neumann 16 MOVE16 0x19 SOME 0x21 0x19 3.89 MOVE 0x19 0x24 ? Memória PrincipalEndereços 0x19 0x21 0x20 0x22 0x23 0x24
  • 8.
  • 9.
    Arquitetura de Von Neumann 16 MOVE16 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.
    Ponteiro ● Como manipularendereç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.
    Ponteiros ● Aplicações deponteiros: – 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.
    Ponteiro 16 3.98 SOME 0x24 0x19 0x20 MOVE0x19 0x24 0x22 0x19 0x21 0x20 0x22 0x23 0x24 São variáveis que apontam para outras
  • 13.
    Ponteiro ● Nos exemplosacima, os endereços possuíam 1 B de tamanho. ● Quantos valores podem ser armazenados com 1 B?
  • 14.
    Ponteiro ● Nos exemplosacima, 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.
    Ponteiro ● Suponha umcomputador 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.
    Ponteiro ● Outro detalhedo 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.
    Ponteiro ● Qual tipode dado em C possui 1 B?
  • 18.
    Ponteiro ● Qual tipode dado em C possui 1 B? ● Resp.: char e unsigned char
  • 19.
    Ponteiro ● Os tiposbásicos de C possuem todos 1 B?
  • 20.
    Tipos básicos TamanhoPrecisã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.
    Ponteiro ● Considere oseguinte código:
  • 22.
    Ponteiro ● Vamos pegarum 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.
    Ponteiro ● Um caracterecomo '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.
  • 25.
    Ponteiro ● O endereçodo 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.
    Ponteiro ● Assim, umponteiro 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.
  • 28.
    Ponteiro ● Para obtero endereço de memória de uma variável utiliza-se o operador &. ● A sintaxe deste operador é: & <variável>
  • 29.
  • 30.
    Ponteiro ● Para acessaro 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.
  • 32.
    Ponteiro ● Se fossepara escrever na tela os endereços onde as variáveis ponteiros pa, pb e pc estão o que deveria ser feito?
  • 33.
  • 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.
    Atribuições e tipos ●Exemplo 2: a = 0 - b; ● Exemplo 3: float f = 3.14 * 4.0 / a ; int int float float
  • 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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    Conversão implícita ● Exemplo: inti = 1; float f = i; Isto está errado?
  • 51.
    Conversão implícita ● Exemplo: inti = 1; float f = i; printf(“%fn”,f); Que valor será escrito na tela?
  • 52.
    Conversão implícita ● Exemplo: inti = 1; float f = i; float int ℤ ℝ
  • 53.
    Conversão implícita ● Exemplo: inti = 1; float f = (float) i; ● Foi realizada uma conversão implícita de inteiro para real.
  • 54.
  • 55.
    Conversão implícita ● Ocompilador 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.
    Conversão explícita ● Aconversã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.
    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.
    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.
  • 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.
  • 62.
  • 63.
    Exercícios 1) Escreva umprograma 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.
    Exercícios 2) Por queo tamanho dos ponteiros da questão 1 são iguais apesar de serem ponteiros para tipos diferentes?
  • 65.