A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Nivelamento de C: Ponteiros e Alocação Dinâmica

Apresentações semelhantes


Apresentação em tema: "Nivelamento de C: Ponteiros e Alocação Dinâmica"— Transcrição da apresentação:

1 Nivelamento de C: Ponteiros e Alocação Dinâmica
CONTEÚDO (1) Exercícios de revisão (2) Ponteiros (3) Alocação Dinâmica

2 Antes de prosseguir, exercite um pouco...
(1) Exerícios de Revisão Antes de prosseguir, exercite um pouco... Crie um tipo tCasamento contendo os campos (nomeDoConjuge, idadeDoConjuge, NFilhos, tempoDeCasado) Crie um tipo tEmpregado, que ira conter os campos (nome, salario, idade, estadoCivil, casamento do tipo tCasamento) 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 Faça uma função que recebe um empregado e resulta no número de filhos desse empregado multiplicado pelo tempo de casado Faça uma função que recebe dois tEmpregado, e retorna a idade do empregado mais velho 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 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”

3 É um tipo de dado que guarda um endereço
(2) Ponteiros 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 [100] [102] [103] [107] 4 A 0.0 100 i c f p

4 Analogia do Controle Remoto
(2) Ponteiros Analogia 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

5 Declarando e inicializando
(2) Ponteiros Declarando 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: [100] [104] [105] [113] ? p [100] [104] [105] [113] 105 ? p 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 :-)

6 Declarando e inicializando
(2) Ponteiros Declarando 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 [100] [102] [103] [107] 4 66 3.0 ? i c f p Qual valor será atribuído a p nessa instrução?

7 Dada as declarações e inicializações abaixo:
(2) Ponteiros Mudando 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; [200] [202] [204] [208] 4 67 200 i k f p inicialmente [200] [202] [204] [208] 4 67 202 i k f p novo endereço

8 Impressão do endereço do ponteiro p, em hexadecimal
(2) Ponteiros Acessando 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); [200] [202] [204] [208] 4 67 3.0 200 i k f p inicialmente Impressão do endereço do ponteiro p, em hexadecimal CA16 printf(“%p”,p)

9 (2) Ponteiros Acessando 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 [200] [202] [204] [208] 4 65 3.0 200 i k f p

10 Auto-avaliação a) O que será impresso no programa abaixo?
(2) Ponteiros Auto-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 :-)

11 (2) Ponteiros Auto-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.

12 A variável vetor é na verdade, o endereço da primeira posição do vetor
(2) Ponteiros Ponteiros 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 vetor [100] [102] [104] [106] [108] [110] [112] [114] [116] [118] 2 3 ? 1 2 3 4 5 6 7 8 9 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!

13 O endereço da primeira posição do vetor é dado por:
(2) Ponteiros Ponteiros e Vetores O endereço da primeira posição do vetor é dado por: vetor ou &vetor[0] vetor ou &vetor[0] [100] [102] [104] [106] [108] [110] [112] [114] [116] [118] 2 3 ? 1 2 3 4 5 6 7 8 9 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

14 O que será impresso em (1) e (2)? Explique o porquê!
(2) Ponteiros Auto-avaliação Por que o compilador C é incapaz de checar os limites de um vetor? 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]); getchar(); O que será impresso em (1) e (2)? Explique o porquê! (1) (2)

15 Ponteiros 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] [154] [158] 100 F r e d \0 31 Ponteiros para tPessoa nome idade pessoa p1 p2 Acessando os campos do ponteiro

16 O que será impresso no programa abaixo?
(2) Ponteiros Auto-avaliação 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(); } [100] [154] [158] 100 F r e d \0 31 nome idade pessoa p1 p2

17 "A idade da primeira pessoa eh 0”
(2) Ponteiros Auto-avaliação 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

18 Alocação dinâmica de memória
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

19 Protótipo: void *malloc(tamanho); Detalhes :
(2) Alocação dinâmica Malloc 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 com x = (int *) malloc( sizeof(int) ); tamanho é a quantidade de bytes alocado.

20 Criando vetores com malloc
(2) Alocação dinâmica Criando vetores com malloc Ex: int *vet; vet = malloc(sizeof(int)*10); vet[0] = 2; vet[1] = 3; vet[2] = 0; Criação dinâmica de vetores Forma Não Dinâmica: int vet[10]; Forma Dinâmica: int *vet; vet [118] [116] [114] [112] [110] [108] [106] [104] [102] [100] ? 3 2 9 8 7 6 5 4 3 2 1

21 Dadas as definições abaixo, implemente o que se pede:
(2) Alocação dinâmica Auto-avaliação Dadas as definições abaixo, implemente o que se pede: typedef struct { char [50]; char nome [20]; char sobrenome [50]; char telefone [20]; }tUsuario; Crie um programa que permita que o usuário digite um valor inteiro N, e em seguida crie um vetor de N tUsuario Crie uma função que receba um número inteiro ‘n’, e retorne um vetor de n tUsuario


Carregar ppt "Nivelamento de C: Ponteiros e Alocação Dinâmica"

Apresentações semelhantes


Anúncios Google