21
Prof. Frederico Brito Fernandes [email protected] Nivelamento de C: Nivelamento de C: Ponteiros e Alocação Dinâmica Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3) Alocação Dinâmica

Prof. Frederico Brito Fernandes [email protected] Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Embed Size (px)

Citation preview

Page 1: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Prof. Frederico Brito [email protected]

Nivelamento de C:Nivelamento de C:Ponteiros e Alocação Ponteiros e Alocação

Dinâmica Dinâmica

Nivelamento de C:Nivelamento de C:Ponteiros e Alocação Ponteiros e Alocação

Dinâmica Dinâmica

CONTEÚDO

(1) Exercícios de revisão(2) Ponteiros(3) Alocação Dinâmica

Page 2: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 2Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Antes de prosseguir, exercite um pouco...Antes de prosseguir, exercite um pouco...

a) Crie um tipo tCasamento contendo os campos (nomeDoConjuge, idadeDoConjuge, NFilhos, tempoDeCasado)

b) Crie um tipo tEmpregado, que ira conter os campos (nome, salario, idade, estadoCivil, casamento do tipo tCasamento)

c) Crie e inicialize um vetor “empregados” com N_EMP elementos do tipo tEmpregado. Defina N_EMP como uma constante valendo 2 (#define N_EMP 2). Crie dois empregados hipotéticos.Ex: int vet[2] = {2,45}; // cria e inicializa (2 e 45) um vetor de dois inteiros

d) Faça uma função que recebe um empregado e resulta no número de filhos desse empregado multiplicado pelo tempo de casado

e) Faça uma função que recebe dois tEmpregado, e retorna a idade do empregado mais velho

f) Faça uma função que receba um vetor de tEmpregado e um número inteiro (que representa a quantidade de elementos desse vetor), e que resulte na quantidade de empregados solteiros

g) Faça uma função que receba um vetor de tEmpregado, e que imprima o nome dos casais que trabalham na empresa. – Ex: Se “João” é um empregado, e sua esposa é “Maria”, e se existe uma

empregada chamada “Maria” que é casada com “João”, então sua função deve imprimir “João e Maria”

(1) Exerícios de Revisão

Page 3: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 3Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

O que é um ponteiro?O que é um ponteiro?

• É um tipo de dado que guarda um endereço– Ex:

• O tipo int armazena um inteiro – Ex: int i=4; //2 bytes

• O tipo char armazena um caractere – Ex: char c=65; //1 byte

• O tipo float armazena um número de ponto flutuante – Ex: float f=0; //4 bytes

• O tipo ponteiro armazena um endereço (Ex: 4 bytes)– Ex: int *p=&i; //4 bytes

4 A 0.0 100

i c f p

[100] [102]

[103] [107]

(2) Ponteiros

Page 4: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 4Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Analogia do Controle RemotoAnalogia do Controle Remoto

• Analogia prática: – O Ar-condicionado (variável)

– O Controle Remoto (ponteiro)

• Afirmações:– Possuir o Controle Remoto significa poder manipular o Ar-Condicionado

– Você liga/muda temperatura do Ar-Condicionado com o ponteiro• Mas se você quisesse, poderia fazer essas coisas diretamente no Ar-Condicionado

– Controle pode existir sem que exista um Ar-Condicionado

– Ar-Condicionado pode existir sem que exista um Controle Remoto

– Um Ar-Condicionado pode ter vários controles

– Um Controle só pode manipular um Ar-Condicionado ao mesmo tempo, porém...• Ele pode ser usado em seguida para manipular outro Ar-Condicionado

• Um Controle pode manipular Ar-Condicionado do mesmo fabricante

(2) Ponteiros

Page 5: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 5Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Declarando e inicializandoDeclarando e inicializando

• Declarando um ponteiro:float *p;

• Como o ponteiro não foi inicializado, ele pode estar apontando para qualquer endereço de memória– Ex:

? ? ? ?

p

[100] [104]

[105] [113]

105 ? ? ?

p

[100] [104]

[105] [113]

O Ministério da Saúde adverte: o uso descuidado de ponteiros pode levar a sérios bugs e a dores de cabeça terríveis :-)

O Ministério da Saúde adverte: o uso descuidado de ponteiros pode levar a sérios bugs e a dores de cabeça terríveis :-)

(2) Ponteiros

Page 6: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 6Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Declarando e inicializandoDeclarando e inicializando

• Declarando e inicializando um ponteiro. Ex1:

int i=4;

char c=‘B’;

float f=3;

float *p=&f;

• Seria muito difícil pro programador lidar diretamente com o endereço físico. Ex2:

float *p=103;

– Mesmo porque, esse endereço iria mudar de computador pra computador, ou mesmo entre duas execuções na mesma máquina

4 66 3.0 ?

i c f p

[100] [102]

[103] [107]

Qual valor será atribuído a p nessa instrução?Qual valor será atribuído a p nessa instrução?

(2) Ponteiros

Page 7: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 7Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Mudando o endereçoMudando o endereço

• Dada as declarações e inicializações abaixo:Ex1:

int i=4;int k=‘C’;float f=3;int *p=&i;

• É possível fazer o ponteiro apontar para outro endereço:Ex1: (continuação)

p = &k;

• O que acontece abaixo?(a) p = k; (b) p = &f;

4 67 200

[200] [202] [204] [208]

i k f pinicialmenteinicialmente

4 67 202

[200] [202] [204] [208]

i k f pnovo endereçonovo endereço

(2) Ponteiros

Page 8: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 8Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Acessando o conteúdoAcessando o conteúdo

• Dada as declarações e inicializações abaixo:

Ex1:int i=4;

int k=‘C’;

float f=3;

int *p=&i;

• É possível acessar o conteúdo de quem o ponteiro aponta:Ex1.2:

printf(“%d”, *p); // imprime 4 na tela*p = 7; // altera indiretamente o valor de i

p = &k; // faz p apontar para k

i = *p + 2; // qual o valor de i agora? (admita o p apontando para k)

• O que aconteceria na instrução abaixo? (admita p apontando pra k)Ex1.3:

printf(“%d”, p);

4 67 3.0 200

[200] [202] [204] [208]

i k f pinicialmenteinicialmente

printf(“%p”,p)printf(“%p”,p)

Impressão do Impressão do endereço do endereço do

ponteiro ponteiro pp, em , em hexadecimalhexadecimal

CACA1616

(2) Ponteiros

Page 9: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 9Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Acessando o conteúdoAcessando o conteúdo

• Diferença entre inicialização e acesso ao conteúdo de um ponteiro:– O caractere * (asterisco) é usado tanto para :

• acessar o conteúdo de quem o ponteiro aponta

• declarar e inicializar ponteiros

Ex:int i=4;

int k=‘A’;

float f=3;

int *p=&i; // inicialização de p, indicando que ele deve apontar para o endereço de i

*p = 1; // acesso ao conteúdo de quem p aponta, ou seja, modifica i indiretamente

4 65 3.0 200

[200] [202] [204] [208]

i k f p

(2) Ponteiros

Page 10: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 10Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Auto-avaliaçãoAuto-avaliação

a) O que será impresso no programa abaixo?#include <stdio.h>int main () {

int num,*p;num=55;p=&num;printf ("\nValor inicial: %d\n",num);*p=100; printf ("\nValor final: %d\n",num);

}Obs: quando souber o que será impresso, copie e execute no compilador!

b) Qual o erro do programa abaixo:int main () /* Errado - Nao Execute */{

int x,*p;x=13;*p=x;return(0);

}

O Ministério da Saúde adverte: o uso descuidado de ponteiros pode levar a sérios bugs e a dores de cabeça terríveis :-)

O Ministério da Saúde adverte: o uso descuidado de ponteiros pode levar a sérios bugs e a dores de cabeça terríveis :-)

(2) Ponteiros

Page 11: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 11Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Auto-avaliaçãoAuto-avaliação

c) Escreva uma função que receba dois ponteiros de inteiros, e que inverta o conteúdo desses parâmetros.

void troca(int *a, int *b); //prototipo da funcao

d) Em seguida, execute o programa abaixo:#include <stdio.h>

void troca(int *a, int *b){

// implemente sua funcao aqui

}

int main () {int k=4,m=7;

printf ("\nValor inicial de k= %d e valor inicial de m= %d\n",k,m);

troca(&k,&m);

printf ("\nValor final de k= %d e valor final de m= %d\n",k,m);

}

Como sabemos, a passagem de parâmetros em C é feita por valor. Porém, esse é um exemplo de como podemos simular uma passagem de

parâmetros por referência.

Como sabemos, a passagem de parâmetros em C é feita por valor. Porém, esse é um exemplo de como podemos simular uma passagem de

parâmetros por referência.

(2) Ponteiros

Page 12: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 12Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Ponteiros e VetoresPonteiros e Vetores

• O vetor é um ponteiro...– Ponteiro esse que aponta para a primeira posição do vetor

– Vejamos como o compilador interpreta o exemplo abaixo: (suponha que um inteiro seja armazenado em 2 bytes)Ex:

int vetor[10] = {2,3,0}; // O compilador reserva 20 bytes seqüenciais

2 3 0 ? ? ? ? ? ? ?0 1 2 3 4 5 6 7 8 9

[100] [102] [104] [106] [108] [110] [112] [114] [116] [118]

vetorvetor

• A variável vetor é na verdade, o endereço da primeira posição do vetor– Ex:

• vetor[0] = 4 é equivalente a *vetor = 4; //veja se vc entende bem isso!

(2) Ponteiros

Page 13: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 13Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Ponteiros e VetoresPonteiros e Vetores

2 3 0 ? ? ? ? ? ? ?0 1 2 3 4 5 6 7 8 9

[100] [102] [104] [106] [108] [110] [112] [114] [116] [118]

vetorvetorouou&vetor[0]&vetor[0]

– Ex:int vetor[10] = {2,3,0}; // o vetor é o endereço do primeiro elemento

int *p = vetor; // apesar de não ter ‘&’, o vetor já representa um endereço

p = &vetor[2];

printf(“%d”, *p); // que valor é impresso aqui?

printf(“%d”, p); // qual valor é impresso aqui agora?

p = &vetor[0]; // novamente aponta para o início do vetor

p = &vetor; // redundante, mas válido

printf(“%d”, *vetor); // qual valor é impresso aqui agora?

vetor = &vetor[1]; // Inválido, pois não se altera o endereço de variáveis

• O endereço da primeira posição do vetor é dado por:– vetor ou &vetor[0]

(2) Ponteiros

Page 14: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 14Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Auto-avaliaçãoAuto-avaliação

1. Por que o compilador C é incapaz de checar os limites de um vetor?

2. Olhe o código abaixo:#include <stdio.h>

typedef struct{

char nome[50];

int idade;

} tPessoa;

void zeraIdade1(tPessoa pessoa){

pessoa.idade=0;

}

void zeraIdade2(tPessoa pessoas[]){

pessoas[0].idade=0;

}

main(){

tPessoa pessoas[10] = { {"Fred", 31} };

zeraIdade1(pessoas[0]);

printf("A idade da primeira pessoa eh %d\n",pessoas[0].idade);

zeraIdade2(pessoas); // equivalente a zeraIdade2(&pessoas[0]);

printf("A idade da primeira pessoa eh %d\n",pessoas[0].idade);

getchar();

}

(1)(1)

(2)(2)

O que será impresso em O que será impresso em (1)(1) e e (2)(2)? Explique o porquê!? Explique o porquê!

(2) Ponteiros

Page 15: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 15Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Ponteiros para estruturasPonteiros para estruturas

• É possível fazer um ponteiro apontar para um tipo de dado estruturado– Para acessar o campos desse ponteiro, basta usar o “->”, em vez de “.”

Ex:#include <stdio.h>

typedef struct{

char nome[50];

int idade;

} tPessoa, *tPtrPessoa;

main(){

tPessoa pessoa = {"Fred",31};

tPessoa *p1 = &pessoa;

tPtrPessoa p2 = &pessoa;

printf("%s\n",pessoa.nome);

printf("Nome: %s\n",p1->nome);

printf("Idade: %d\n",p1->idade);

p1->idade = 20;

printf("Idade: %d\n",p2->idade);

getchar();

}

100 100F r e d \0 31

pessoa p1 p2

[100] [154] [158]

nome idade

Ponteiros Ponteiros para tPessoapara tPessoa

Acessando Acessando os campos os campos do ponteirodo ponteiro

(2) Ponteiros

Page 16: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 16Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Auto-avaliaçãoAuto-avaliação

1. O que será impresso no programa abaixo?#include <stdio.h>

#include <string.h>

typedef struct{

char nome[50];

int idade;

} tPessoa;

main(){

tPessoa pessoa = {"Fred",27};

tPessoa *p1 = &pessoa;

int *p2 = &pessoa.idade;

printf("Nome: %s\n",pessoa.nome);

printf("Idade: %d\n",pessoa.idade);

strcpy(p1->nome,"Zezim");

*p2 = 4;

printf("\nNome: %s\n",p1->nome);

printf("Idade: %d\n",p1->idade);

getchar();

}

(2) Ponteiros

100 100F r e d \0 31

pessoa p1 p2

[100] [154] [158]

nome idade

Page 17: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 17Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

Auto-avaliaçãoAuto-avaliação

2. Modifique a função zeraIdade() abaixo, para que ela simule uma passagem por referência. Em outras palavras, ela deveria imprimir:

"A idade da primeira pessoa eh 0”

#include <stdio.h>

typedef struct{

char nome[50];

int idade;

} tPessoa;

void zeraIdade(tPessoa pessoa){

pessoa.idade=0;

}

main(){

tPessoa pessoa = {"Fred", 27};

zeraIdade(pessoa);

printf("A idade da primeira pessoa eh %d\n",pessoa.idade);

getchar();

}

DICA: Faça a função receber um ponteiro para tPessoa, e

modifique o que for necessário

(2) Ponteiros

Page 18: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 18Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

• C permite a criação de memória para variáveis em tempo de execução

• Isso quer dizer que é possível criar vetores dinâmicos

• Funções da stdlib.h:– malloc(tamanho) permite a alocação de memória capaz de armazenar tamanho bytes.

– free(pont) libera a memória alocada associada com o ponteiro pont.– calloc(tamanho, qtde) permite a alocação de memória capaz de

armazenar (tamanho * qtde) bytes.– realloc(pont, tamanho) redimensiona o bloco apontado pelo pont, para ter o novo tamanho

(2) Alocação dinâmica

Alocação dinâmica de memóriaAlocação dinâmica de memória

Page 19: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 19Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

• Protótipo: void *malloc(tamanho);

• Detalhes : – Devolve um ponteiro do tipo void (sem tipo) para o início (1º byte) da

área de memória alocada.

– Isto significa que o valor deste ponteiro pode ser atribuído a qualquer variável do tipo ponteiro.

• Para isto deve ser utilizado sempre um typecasting. Ex.: se x é ponteiro para inteiro então explicitar isto comx = (int *) malloc( sizeof(int) );

– tamanho é a quantidade de bytes alocado.

(2) Alocação dinâmica

MallocMalloc

Page 20: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 20Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

• Ex:

int *vet;

vet = malloc(sizeof(int)*10);

vet[0] = 2;

vet[1] = 3;

vet[2] = 0;

???????032

9876543210

[118][116][114][112][110][108][106][104][102][100]

vetvet

Criação dinâmica de vetoresCriação dinâmica de vetores

Forma Não Dinâmica: int vet[10];Forma Dinâmica: int *vet;

(2) Alocação dinâmica

Criando vetores com mallocCriando vetores com malloc

Page 21: Prof. Frederico Brito Fernandes christus@fredbf.com Nivelamento de C: Ponteiros e Alocação Dinâmica CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3)

Frederico Brito FernandesFrederico Brito Fernandes 21Estrutura, Pesquisa e Ordenação de DadosEstrutura, Pesquisa e Ordenação de Dados

• Dadas as definições abaixo, implemente o que se pede:

typedef struct {

char email [50];

char nome [20];

char sobrenome [50];

char telefone [20];

}tUsuario;

a) Crie um programa que permita que o usuário digite um valor inteiro N, e em seguida crie um vetor de N tUsuario

b) Crie uma função que receba um número inteiro ‘n’, e retorne um vetor de n tUsuario

(2) Alocação dinâmica

Auto-avaliaçãoAuto-avaliação