Escolar Documentos
Profissional Documentos
Cultura Documentos
Lê e escreve
Arquitetura de Von
Neumann
Dados Busca e
executa
Código
Dados
Código
Código
Dados
Lê e escreve
Memória Principal
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.
0x0
0x1 E se ela tivesse 1GB, iria do
0x2 Endereço 0 a qual número
0x3 decimal?
0x4
0x5
0x6 E hexadecimal?
0x7
1B
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.
0x0
0x1 E se ela tivesse 1GB, iria do
0x2 Endereço 0 a qual número
0x3 decimal?
0x4
0x5 Resp.: 1073741823
0x6 E em hexadecimal?
0x7 Resp.: 3FFFFFFF
1B
Arquitetura de Von
Neumann
0x19 16
0x21 3.89
0x24 ?
0x20 01010101
0x21 00100111
0x22 10100010
0x23 01010101
0x24 00010000
0x24 ?
0x20 3.98
0x24 0x22
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?
0x19 16
0x21 3.89
0x24 0
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 de dados básicos
}
0xbff43513 00000000
0xbff43514 00000000 a=0
0xbff43515 00000000
0xbff43516 00000000
}
0xbff43517 01010111
0xbff43518 01010101
b = 1465232370
0xbff43519 10101011
0xbff4351a 11110010
0xbff4351b 01000001 } 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;
int int
● Exemplo 3:
float f = 3.14 * 4.0 / a ;
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
char* = char*
Atribuições e tipos
● Exemplo 2:
float f = 3.14;
float *p;
p = &f; float* = & float
float* = float*
● Exemplo 3:
int b = 13;
char * pi;
pi = &b; 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:
O * em preto
– char c = 'b'; representa o
char d; operador
desreferenciamento.
char *p = &c;
d = *p; O * em vermelho
representa o tipo
“ponteiro de”.
char = * char*
Sabendo-se que * <ponteiro para tipo> = <tipo>, temos:
char = char
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
double
float
int
char
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!