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

Slides:



Advertisements
Apresentações semelhantes
Programação em Java Prof. Maurício Braga
Advertisements

Marco Antonio Montebello Júnior
Construção de Algoritmos AULA 07
Nivelamento de C: Vetores e Strings
Nivelamento de C: Tipos Estruturados de Dados
Capítulo 1 – Conceitos Básicos 1 Segunda-feira, 22 de Outubro de 2007 UNIBRATEC – Ensino Superior e Técnico em Informática Aula 15 – Tipos de Dados Avançados.
Listas Encadeadas CONTEÚDO (1) Motivação (2) Definição (3) Operações
Programação II Estruturas de Dados
Programação II Estruturas de Dados
Alocação Dinâmida de Memória
Algoritmos e Estrutura de Dados I
1 Tipos definidos O programador pode definir seus próprios tipos de dados tipos complexos usados da mesma forma que os simples declaram-se variáveis utilizando-se.
Alocação Dinâmica de Memória
LPG - I: Alocação Dinâmica de Memória - Ponteiros
LPG - I: Ponteiros e Vetores/Matrizes UDESC - SBS
LPG-I: Tipos Complexos - Estruturas
Estruturas de Dados I Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Estruturas de Dados I Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Estruturas de Dados II Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Estruturas de Dados II Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Universidade Federal do Espírito Santo Programação II Estruturas Professora: Norminda Luiza.
Universidade de Brasília
Linguagem C Strings.
Fundamentos de Programação 1
Ponteiros.
Escola Secundária c/ 3º CEB da Batalha
1MF. Vectores Tipo de dado usado para representar um CONJUNTO de dados do um mesmo tipo Estrutura de dados homogénea unidimensional Ex: Ler a nota de 3.
Listas Encadeadas.
Revisão da Linguagem C.
Apontadores ou Ponteiros
APRESENTAÇÃO: GIANCARLO DE GUSMÃO GONÇALVES CURSO DE C AULA 08: Tipos Estruturados.
Professor Reverton de Paula Faculdade Anhanguera de Indaiatuba
Aula prática 9 Alocação Dinâmica Monitoria de Introdução à Programação
Aula prática 8 Ponteiros Monitoria de Introdução à Programação
Aula prática 8 Ponteiros Monitoria de Introdução à Programação.
Aula prática 6 Vetores e Matrizes
Aula prática 9 Alocação Dinâmica Monitoria de Introdução à Programação
PROGRAMAÇÃO ESTRUTURADA II
PROGRAMAÇÃO ESTRUTURADA II
Linguagem de Programação II Parte IX
Definição de Tipos Estruturas e Ponteiros
CADEIA DE CARACTERES (Strings)
Construção de Algoritmos Professor: Aquiles Burlamaqui Construção de Algoritmos AULA 07 Aquiles Burlamaqui UERN
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
PROGRAMAÇÃO I PONTEIROS.
Estrutura de Dados Avançada
UNIDADE 5 ESTRUTURAS DE DADOS HOMOGÊNEAS
Prof. Ricardo Santos PONTEIROS
Computação Eletrônica
Linguagem C : Ponteiros
Estruturas de Dados Aula 5: Matrizes
Vetor Prof. Guilherme Baião S. Silva Adaptações:
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Aula P.02 – BCC202 Revisão sobre Ponteiros Túlio Toffolo
Algoritmos e Estruturas de Dados
Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
CES-10 INTRODUÇÃO À COMPUTAÇÃO
Algoritmos e Programação MC102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Ponteiros.
Programação de Computadores I – Ponteiros Profa. Mercedes Gonzales Márquez.
Ponteiros em C Prof. Kariston Pereira
Linguaguem de Programação II
PCI- Funções e Procedimentos Profa. Mercedes Gonzales Márquez.
Algoritmo e Estrutura de Dados I Aulas 15 – Linguagem C Alocação Dinâmica de Memória Márcia Marra
Linguagem de Programação
Aula Prática 6 Ponteiros Monitoria  Quando declaramos uma matriz:  tipo meuArray[tam];  O compilador aloca a matriz em uma região de memória.
FUNÇÕES Dilvan Moreira (baseado em material de Z. Liang)
DHD – Desenvolvimento em Hardware
Transcrição da apresentação:

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

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”

É 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

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

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 :-)

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?

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

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)

(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

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 :-)

(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.

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!

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

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)

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

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

"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

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

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.

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

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 email [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