48
Logo

Logo - rcosta62br.unifei.edu.brrcosta62br.unifei.edu.br/escola/EIP_06.pdf · 5 Ponteiros A532 VALOR 2897 P Aqui P “aponta” para a posição de memória denominada valor. A532

Embed Size (px)

Citation preview

Logo

2

Aula 06Aula 06

● Ponteiros

3

PonteirosPonteiros

• Embora o programador não tenha acesso ao endereço de uma variável, existem algumas situações onde é necessário a utilização deste endereço.

• Um exemplo clássico disto na linguagem C/C++ é quando se transporta informações para ou de uma função.

• É necessário muita habilidade para o uso correto de ponteirosponteiros em C/C++, caso contrário o resultado obtido poderá ser desastroso.

4

PonteirosPonteiros

• PonteiroPonteiro é uma variável que guarda em seu conteúdo o endereço físico de outra variável.

• Neste exemplo, a variável VALORVALOR está localizada na posição de memória A532A532 (valor dado em hexadecimal) e contém armazenado em seu conteúdo o valor 28972897.

A532

VALOR

2897

5

PonteirosPonteiros

A532

VALOR

2897

P

Aqui P “aponta” para

a posição de memória

denominada valor.

A532

6

PonteirosPonteiros

• Por apontar, entende-se que PP sabe onde encontrar a variável valorvalor.

● Neste caso, PP guarda (A532) o valor do endereço da variável valorvalor.

● Daí a denominação para este tipo de variável de ponteiroponteiro.

7

Declaração de um PonteiroDeclaração de um Ponteiro

• A declaração de ponteiros em linguagem C é feita da seguinte forma:

tipo *nome_variavel_ponteiro;tipo *nome_variavel_ponteiro;

8

Operadores de PonteirosOperadores de Ponteiros

• Dois operadores unitários são utilizados para se acessar um ponteiro: ** e &&

● O operador ** é utilizado para acessar o conteúdo da variável para a qual o ponteiro está apontando.

● O operador && é utilizado para acessar o endereço da variável para a qual o ponteiro está apontando.

9

Exemplo dos operadoresExemplo dos operadores#include <bits/stdc++.h>using namespace std;int main(){

int n, valor;int *pvalor;valor = 100;pvalor = &valor;n = *pvalor;printf("valor = %d\n", valor);printf("pvalor = %p\n", pvalor);printf("pvalor = %d\n", *pvalor);printf("n = %d\n", n);return 0;

}

10

Saída do programaSaída do programa

Saída:valor = 100pvalor = 0x7ffeb32dd5acpvalor = 100n = 100

11

Ponteiros apontados para Ponteiros apontados para vetoresvetores

• Dado um vetor V de 10 elementos e um ponteiro P. O comando P = &V irá colocar o ponteiro P “apontando” para a primeira posição do vetor V. Conforme a figura:

10 5 12 15 7 11 9 2 18 4

0

10

1 2 3 4 5 6 7 8 9

V

P

12

Ponteiros apontados para Ponteiros apontados para vetoresvetores

• Ao fazer o comando P++, você irá andar uma unidade de memória com o ponteiro P, neste caso ele vai apontar para a segunda casa do vetor V. Conforme a figura:

• E assim sucessivamente até chegar na ultima posição do vetor.

10 5 12 15 7 11 9 2 18 4

0

10

1 2 3 4 5 6 7 8 9

V

P

13

Exemplo dos ponteiro no Exemplo dos ponteiro no vetorvetor

#include <bits/stdc++.h>using namespace std;int main(){

freopen("entrada.txt", "r", stdin);int V[11], *P, i;for (i = 0; i < 10; i++){

scanf("%d", &V[i]);}

14

Exemplo dos ponteiro no Exemplo dos ponteiro no vetorvetor

P = V;printf("Valores do vetor V:\n");for (i = 0; i < 10; i++){

printf("%d ", V[i]);}printf("\n");

15

Exemplo dos ponteiro no Exemplo dos ponteiro no vetorvetor

printf("Valores Apontador por P:\n");for (i = 0; i < 10; i++){

printf("%d ", *P);P++;

} printf("\n");return 0;

}

16

Entrada e Saída do programaEntrada e Saída do programa

Entrada:10 5 12 15 7 11 9 2 18 4

Saída:Valores do vetor V:10 5 12 15 7 11 9 2 18 4 Valores Apontador por P:10 5 12 15 7 11 9 2 18 4

17

Dimensionamento DinâmicoDimensionamento Dinâmico

• O dimensionamento dinâmico é a solução para as restrições apresentadas pelo dimensionamento estático.

• Com o dimensionamento dinâmico, o usuário pode dimensionar a variável no meio do programa, e aí ele pode definir uma quantidade já conhecida de células e pode também liberar a área dimensionada caso não a precise mais no programa.

18

Dimensionamento DinâmicoDimensionamento Dinâmico

• Para alocar a memória em C você pode usar a função:

tipo *ponteiro;tipo *ponteiro;

ponteiro = (tipo *) malloc(sizeof(tipo));ponteiro = (tipo *) malloc(sizeof(tipo));

• Em em C++:

tipo *ponteiro;tipo *ponteiro;

ponteiro = new tipo;ponteiro = new tipo;

• Todos os dois alocam 1 espaço de memória para armazenar o valor da variável.

19

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

#include <bits/stdc++.h>using namespace std;int main(){

int *ptr_a;ptr_a = (int *) malloc(sizeof(int));printf("Endereço de ptr_a: %p\n", ptr_a);*ptr_a = 90;printf("Conteúdo de ptr_a: %d\n", *ptr_a);free(ptr_a);return 0;

}

20

Saída do programaSaída do programa

Saída:Endereço de ptr_a: 0xdc6c20Conteúdo de ptr_a: 90

21

Exemplo dimensionamento Exemplo dimensionamento dinâmico em C++dinâmico em C++

#include <bits/stdc++.h>using namespace std;int main(){

int *ptr_a;ptr_a = new int;cout << "Endereço de ptr_a: " << ptr_a << endl;*ptr_a = 90;cout << "Conteúdo de ptr_a: " << *ptr_a << endl;delete ptr_a;return 0;

}

22

Saída do programaSaída do programa

Saída:Endereço de ptr_a: 0xdc6c20Conteúdo de ptr_a: 90

23

Dimensionamento DinâmicoDimensionamento Dinâmico

• Para desalocar a memória em C você pode usar a função:

free(ponteiro);free(ponteiro);

• Em em C++:

delete ponteiro;delete ponteiro;

24

Dimensionamento DinâmicoDimensionamento Dinâmico

• Para alocar mais de uma memória em C e usar o ponteiro como vetor é só mudar a função malloc para:

tipo *ponteiro;tipo *ponteiro;

ponteiro = (tipo *) malloc( ponteiro = (tipo *) malloc( nn * sizeof(tipo)); * sizeof(tipo));

• Em em C++:

tipo *ponteiro;tipo *ponteiro;

ponteiro = new tipo[ponteiro = new tipo[nn];];

• Onde n é o tamanho de espaço do vetor que você deseja trabalhar.

25

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

#include <bits/stdc++.h>using namespace std;int main(){

int *v, i;freopen("entrada.txt", "r", stdin);v = (int *) malloc (10 * sizeof(int));for (i = 0; i < 10; i++){

scanf("%d", &v[i]);}

26

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

printf("O vetor eh:\n");for (i = 0; i < 10; i++){

printf("%d ", v[i]);}printf("\n");free(v);return 0;

}

27

Entrada e Saída do programaEntrada e Saída do programa

Entrada:10 5 12 15 7 11 9 2 18 4

Saída:O vetor eh: 10 5 12 15 7 11 9 2 18 4

28

Exemplo dimensionamento Exemplo dimensionamento dinâmico em C++dinâmico em C++

#include <bits/stdc++.h>using namespace std;int main(){

int *v, i;freopen("entrada.txt", "r", stdin);v = new int[11];for (i = 0; i < 10; i++){

cin >> v[i];}

29

Exemplo dimensionamento Exemplo dimensionamento dinâmico em C++dinâmico em C++

cout << "O vetor eh: " << endl;for (i = 0; i < 10; i++){

cout << v[i] << " ";}cout << endl;delete[] v;return 0;

}

30

Entrada e Saída do programaEntrada e Saída do programa

Entrada:10 5 12 15 7 11 9 2 18 4

Saída:O vetor eh: 10 5 12 15 7 11 9 2 18 4

31

Ponteiros como matrizesPonteiros como matrizes

• No caso de matriz, o conceito utilizado é o mesmo, ou seja, o dimensionamento dinâmico reserva uma área correspondente à matriz;

• Esta área é acessada pelo programa através dos índices de linha e coluna da matriz;

• No exemplo seguinte a matriz é definida dinamicamente mas é acessada via índices;

32

Ponteiros como matrizesPonteiros como matrizes

• linlin conjuntos de colcol células contendo cada uma um valor numérico do tipo inteiro totalizando colcol x linlin células

col

lin células contendo endereços de outros ponteiros

33

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

#include <bits/stdc++.h>using namespace std;int main(){

int **M, i, j, lin, col;freopen("entrada.txt", "r", stdin);scanf("%d %d", &lin, &col);M = (int **) malloc (lin * sizeof(int*));for (i = 0; i < lin; i++){

M[i] = (int *) malloc (col * sizeof(int));}

34

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

for (i = 0; i < lin; i++){

for (j = 0; j < col; j++){

scanf("%d", &M[i][j]);}

}

35

Exemplo dimensionamento Exemplo dimensionamento dinâmico em Cdinâmico em C

printf("A Matriz eh:\n");for (i = 0; i < lin; i++){

for (j = 0; j < col; j++){

printf("%d ", M[i][j]);}printf("\n");

}free(M);return 0;

}

36

Entrada e Saída do programaEntrada e Saída do programa

Entrada:3 31 2 34 5 67 8 9

Saída:A Matriz eh:1 2 3 4 5 6 7 8 9

37

Aritmética de PonteirosAritmética de Ponteiros

• Além de acessar os dados de uma área alocada dinamicamente como se fosse um vetor, é possível acessá-los através do próprio ponteiro, utilizando a técnica chamada aritmética de ponteiros.

38

Aritmética de PonteirosAritmética de Ponteiros

• Inicialmente o ponteiro pp aponta para o mesmo lugar que o ponteiro vv aponta. Enquanto pp se movimenta, vv mantém o endereço inicial para referencia.

v

05D3E

9E3AD

9E3AD

p

41FA9 9E3AD

39

Exemplo de Aritmética de Exemplo de Aritmética de PonteirosPonteiros

#include <bits/stdc++.h>using namespace std;int main(){

int *v, *p, i;freopen("entrada.txt", "r", stdin);v = (int *) malloc (10 * sizeof(int));p = v;for (i = 0; i < 10; i++){

scanf("%d", p);p++;

}

40

Exemplo de Aritmética de Exemplo de Aritmética de PonteirosPonteiros

printf("O vetor eh:\n");for (i = 0; i < 10; i++){

printf("%d ", v[i]);}printf("\n");free(v);return 0;

}

41

Entrada e Saída do programaEntrada e Saída do programa

Entrada:10 5 12 15 7 11 9 2 18 4

Saída:O vetor eh:10 5 12 15 7 11 9 2 18 4

42

Ponteiros de Estruturas Ponteiros de Estruturas HeterogêneosHeterogêneos

• Cada campo da estrutura tem seu endereço próprio e por isso deve ter um ponteiro particular apontando para ele;

• O incremento de um ponteiro do tipo estrutura acessa a próxima posição de memória cujo endereço corresponde ao deslocamento igual a soma dos bytes de todos os campos que compõem a estrutura.

43

ProgramaPrograma

#include <bits/stdc++.h>using namespace std;struct ALUNOS{

char nome[50];int mat;double nota[4], media;

};int main(){

int i, j, n;double soma;struct ALUNOS *v;freopen("entrada.txt", "r", stdin);scanf("%d", &n);v = (struct ALUNOS *) malloc (n * sizeof(struct ALUNOS);

44

ProgramaPrograma

for (i = 0; i < n; i++){

soma = 0.0;scanf(" %[^\n]", v[i].nome);scanf("%d", &v[i].mat);for (j = 0; j < 4; j++){

scanf("%lf", &v[i].nota[j]);soma += v[i].nota[j];

}v[i].media = soma / 4.0;

}

45

ProgramaProgramafor (i = 0; i < n; i++){

printf("%-20s - ", v[i].nome);printf("%10d - ", v[i].mat);for (j = 0; j < 4; j++){

printf("%4.1lf - ", v[i].nota[j]);}printf("%4.1lf - ", v[i].media);if (v[i].media >= 6.0){

printf("A\n");} else {

printf("R\n");}

}return 0;

}

46

EntradaEntradaEntrada:Entrada:5Antonio Carlos201801202110.0 5.0 4.0 8.3Pedro Miguel20180112122.0 3.5 4.3 7.2Ana Paula20180333236.0 2.0 9.0 1.3Fatima Santos20180000274.5 5.5 4.5 5.5Fujiro Nakombi20180125556.0 6.0 6.0 6.0

47

SaídaSaída

Saída:Saída:Antonio Carlos - 2018012021 - 10.0 - 5.0 - 4.0 - 8.3 - 6.8 - APedro Miguel - 2018011212 - 2.0 - 3.5 - 4.3 - 7.2 - 4.2 - RAna Paula - 2018033323 - 6.0 - 2.0 - 9.0 - 1.3 - 4.6 - RFatima Santos - 2018000027 - 4.5 - 5.5 - 4.5 - 5.5 - 5.0 - RFujiro Nakombi - 2018012555 - 6.0 - 6.0 - 6.0 - 6.0 - 6.0 - A

48

ExercíciosExercícios

• https://www.urionlinejudge.com.br/judge/en/login

– URI 1120, 1168, 1238, 1253, 1332, 1607, 1864, 1865, 1848, 1871, 1914, 1924, 1984, 2061, 2062, 2126, 2147, 2160, 2165, 2242, 2253, 2338, 2484, 2502, 2531, 2692, 2712, 2722, 2727, 2728.