cap. 8—endereçamento de memória …agomes/programacao/teoricas/08-enderec...utiliza-se o nomeda...

16
Endereçamento de Memória Programação 13205: Engenharia Informática 13901: Matemática e Aplicações Cap. 8— Endereçamento de Memória

Upload: others

Post on 24-Jun-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Programação13205: Engenharia Informática13901: Matemática e Aplicações

Cap. 8— Endereçamento de Memória

Page 2: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Sumário:

• O que nós já sabemos sobre endereçadores (ou apontadores ou ponteiros)

• Declaração de variáveis endereçadoras

• Inicialização de variáveis endereçadoras

• Acesso ao valor e ao endereço duma variável

• Apontadores e arrays

• Aritmética de endereçadores

• Acesso aos elementos dum array através de endereços

• Passagem de arrays para funções

Page 3: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Valor de uma variávelEndereço de uma variável

#include <stdio.h>int main(){

int j = 1;printf("O valor de j = %d\n",j);printf("O endereco de j = %p\n",&j);return 0;

}

1 248623

memória

j

valor de jendereço de j

Saída no ecrã:O valor de j = 1O endereco de j = 248623

REVISÃO

Page 4: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Acesso ao valor de uma variável

• Há duas formas de ler (aceder a) o valor duma variável em memória:

– Leitura directa (ou acesso directo). Utiliza-se o nome da variável.

– Leitura indirecta (ou acesso indirecto). Utiliza-se operador de valoração * seguido de nome de variável apontadora.

– Exemplo:

• O acesso ao valor 1.2 de j faz-se através do uso:

– da variável j– da variável p que aponta (ou endereça) para j

1.2

1342167

1342167

memória

j

valor de jendereço de j

p

REVISÃO

Page 5: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

O que é que nós já sabemos sobre variáveis endereçadoras?

1342167

memória

j

valor de jendereço de j

p

• Tal como qualquer variável, uma variável endereçadora tem:

– nome

– valor

– endereço

• Mas, o seu valor é um endereço de memória. 1342170

Page 6: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Declaração de variáveis endereçadoras

• Diagrama de sintaxe

em que

nome: é o identificador da variável apontadora

tipo : é o tipo do dado que será endereçado

* : indicador de que a variável declarada é do tipo apontador.

• Exemplosint *x;

float *y;

nometipo * ;

Page 7: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Inicialização de variáveis endereçadoras

• A inicialização de variáveis endereçadoras faz-se através do operador & (endereço de).

• Exemplofloat x = 5.0;

float *p;p = &x;

5.0

1342167

1342167x

p 1342173

ATENÇÃO:A constante simbólica NULL, quando atribuída a uma variável endereçadora, indica que esta não endereça nenhuma variável.

Page 8: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Acesso ao valor e ao endereço de uma variável

• Há duas formas de ler (aceder a) o valor duma variável em memória:

– Leitura directa (ou acesso directo). Utiliza-se o nome da variável.

– Leitura indirecta (ou acesso indirecto). Utiliza-se operador de valoração * seguido de nome de variável apontadora.

- O acesso ao endereço duma variável é feito através do operador &.

• Exemploint a = 5, b=10;int *p;

p = &a;

510

13456

13458b

p

a 13456

13461

Acesso a:a ® 5&a ® 13456b ® 10&b ® 13458p ® 13456&p ® 13461*p ® 5

Page 9: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Endereçadores e arrays

• Uma das principais aplicações de apontadores é na manipulação de arrays e strings (cadeias de caracteres).

• Normalmente a utilização do nome duma variável dá acesso ao seu valor.

• EXCEPÇÃO: no caso dum vector, a utilização do seu nome dá acesso ao seu endereço que é o endereço do seu primeiro elemento.

• Exemplo

int v[3] = {5,10,20};int *p, *q;p=v; q=&v[0];

p

v[0] 13456

13462

q 13465

1345813460

v

v[1]v[2]

13456

51020

13456

13456

Page 10: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Aritmética de endereçadores

• Dado que os endereçadores armazenam números (endereços) que representam posições de memória, podem ser sobre eles realizadas algumas operações aritméticas:

• Incrementação

– Um endereçador pode ser incrementado como qualquer variável.

– A incrementação de 1 unidade não significa que o endereço armazenado no endereçador é incrementado de 1 byte.

– O que acontece é que um endereçador para um dado tipo avança sempre sizeof(tipo)bytes por cada unidade de incremento.

• Decrementação

– Faz exactamente o contrário da incrementação.

– Um endereçador para um dado tipo retrocede sizeof(tipo) bytes por cada unidade de decremento.

Page 11: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Exemplo:

#include <stdio.h>int main(){

int x=5;int *p=&x;

printf(“%d %p\n",x,p);printf(“%d %p\n",x+1,p+1);

return 0;}

Saída no ecrã:5 2345686 234570

Page 12: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Aritmética de endereçadores (cont.)

• Diferença

– O resultado da diferença entre dois endereçadores é o número de elementos que existem entre os dois endereços.

– RESTRIÇÃO: Os dois endereçadores têm de ser do mesmo tipo.

• Comparação

– É possível comparar endereçadores através dos operadores relacionais (>, <, >=, <=, ==, !=).

– RESTRIÇÃO: Os dois endereçadores têm de ser do mesmo tipo.

Page 13: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Exemplo:

#include <stdio.h>int main(){

int v[5]={5,10,15,20,25};int *p=v;

int *q=&v[4];printf(“%p\n",q-p);

return 0;}

Saída no ecrã:4

Page 14: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Acesso aos elementos dum array através de endereçamento

• Exemplo

int v[5] = {5,10,15,20,25};int *p=v; // é o mesmo que p=&v[0]

Exemplificando o acesso ao elemento 15:

v[2] | Inteiro existente na posição índice 2.

*(p+2) | Como p contém o endereço do 1º elemento, se lhe adicionarmos 2

| obtemos o endereço do 3º elemento. O 3º elemento é então obtido através d operador *.

*(v+2) | Mesma estratégia que a anterior pois p=v=&v[0].

p[2] | O endereçamento através de parêntesis rectos pode ser feito também por apontadores,

| como se de um vector se tratasse.

Page 15: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Passagem de arrays para funções

• Sempre que na chamada duma função se passa um array como parâmetro, a função não recebe o array na totalidade, mas somente o endereço do 1º elemento, pois estamos a passar v=&v[0].

• Se se passa um endereço para a função, a variável que o recebe terá de ser um apontador para o tipo dos elementos do array.

• É por esta razão que no cabeçalho duma função, que recebe um array como argumento, aparece normalmente um apontador a receber o respectivo parâmetro.

Page 16: Cap. 8—Endereçamento de Memória …agomes/programacao/teoricas/08-enderec...Utiliza-se o nomeda variável. – Leituraindirecta(ouacessoindirecto). Utiliza-se operadorde valoração*seguidode

Endereçamento de Memória

Exemplo#include <stdio.h>int soma( int*, int);

int main(void){int v[5] = {5,34,56,1,6};float media;

media = soma(v,5) / 5.0;

printf(“media= %f\n”, media);return 0;

}

int soma( int *a, int N){

int i, sum=0;

for ( i=0; i<N; i++)sum = sum + a[i];

return sum;}

NOTA:

O argumento a da função soma é um endereçador para um inteiro que receberá o endereço do array vaquando da chamada da referida função.

102

main somaN

sum

&v[0]a

5

media

5 34 56

i ® 0 1 2 3 4

1 6v

FIM