• No se han encontrado resultados

Anhanguera ED 03 4 Ponteiro

N/A
N/A
Protected

Academic year: 2020

Share "Anhanguera ED 03 4 Ponteiro"

Copied!
39
0
0

Texto completo

(1)

Disciplina:

Estrutura de Dados

Tema da aula:

Ponteiro

Função: Passagem de argumentos por Valor

Função : Passagem de argumentos através de Ponteiros Alocação Estática de Memória

Alocação Dinâmica de Memória: malloc e free

(2)

Ponteiro

PLT: 706

(3)

Como funcionam os Ponteiros

• O

int

guardam inteiros.

• O

float

guardam números

de ponto flutuante.

23

45,89

de ponto flutuante.

• O

char

guardam caracteres.

O ponteiro guardam

endereços de memória

.

ABC

(4)

Um Ponteiro é uma variável que contém o endereço de

Não entendi!

que contém o endereço de memória de outra variável.

Podemos ter um ponteiro para qualquer tipo de

(5)

Como funcionam os Ponteiros

Quando você anota o endereço de um colega

você está criando um ponteiro

. O ponteiro é

este seu pedaço de papel. Ele tem anotado

um endereço. Qual é o sentido disto? Quando

um endereço. Qual é o sentido disto? Quando

você anota o endereço de um colega, depois

você vai usar este endereço para achá-lo. Da

mesma maneira, uma agenda, onde são

guardados endereços de vários amigos, poderia

ser vista como sendo uma

(6)

Declarando e Utilizando Ponteiros

• Para declarar um ponteiro temos a seguinte forma:

tipo_do_ponteiro *nome_da_variável;

• É o asterisco (*) que faz o compilador saber que

aquela variável não vai guardar um valor mas sim um endereço para aquele tipo especificado. Exemplos:

endereço para aquele tipo especificado. Exemplos:

int ct;

declara um inteiro

int *pt1;

declara um ponteiro para um inteiro

(7)

Inicializando Ponteiros

O ponteiro deve ser inicializado, ou

seja, apontado para algum lugar

conhecido, antes de ser usado.

conhecido, antes de ser usado.

(8)

Inicializando Ponteiros

• Podemos então deixar que o compilador faça este trabalho por nós. Para saber o endereço de uma variável basta usar o operador &.

Veja o exemplo:

int contador=20; 20

int contador=20;

Criamos um inteiro “contador” com valor 20.

int *pt;

Declaramos o ponteiro inteiro “pt”

pt=&contador;

Temos agora o endereço da variável

(9)

Inicializando Ponteiros

• Como nós colocamos um endereço em pt, ele está agora "liberado" para ser usado.

Podemos, por exemplo, alterar o valor de

contador usando pt.

• Vamos usar o operador "inverso" do

• Vamos usar o operador "inverso" do

operador &. É o operador *. No exemplo, uma vez que fizemos pt=&contador a expressão

(10)

Inicializando Ponteiros

Observação importante

:

apesar do símbolo ser o mesmo, o

operador

* (multiplicação)

não é o

operador

* (multiplicação)

não é o

mesmo operador que o

(11)

Para declararmos variáveis do tipo Ponteiro

int *px, *py;

Isso cria duas variáveis do tipo ponteiro (px e py). Essas variáveis podem conter

Por favor,

explica ai novamente...

(px e py). Essas variáveis podem conter

endereços de variáveis do tipo int.

Operadores

& operador direto que retorna o endereço da variável operando

(12)

Exemplo de Ponteiros - 01

#include <stdio.h> int main ()

{ int num,valor;

int *pt;

num=55;

pt=&num; // Pega o endereco de num */

valor=*pt; // Valor e igual ao valor armazenado em num

printf ("Valor: %d\n",valor);

printf ("Endereco para onde o ponteiro aponta: %p\n",pt); printf ("Valor da variavel apontada: %d\n",*pt);

(13)

Exemplo de Ponteiros - 02

Muda o valor de uma variável de forma indireta

#include <stdio.h> int main ()

{ int numero,*pz; numero=55;

pz=&numero; // Pega o endereço de num

pz=&numero; // Pega o endereço de num

printf ("\nValor inicial: %d\n",numero);

// Muda o valor de numero de uma maneira indireta

*pz=100;

printf ("\nValor final: %d\n",numero); return(0);

(14)

Adição e Subtração com Ponteiros

Vamos imaginar que p é um ponteiro.

p++ ou p--

ele anda 8 bytes na

memória, ou seja, muda o valor do

memória, ou seja, muda o valor do

endereço de memória.

(15)

Qual o resultado de y?

4

0 0

2293476

y x

p

4

4 44

(16)

Por favor, faz uma

revisão sobre ponteiros!

int bb = 10; int cc = 0;

int *zz; declara um ponteiro do tipo inteiro de nome zz zz = &bb coloca o endereço de bb em zz

zz = &bb coloca o endereço de bb em zz

cc = *zz coloca o valor que esta no endereço zz em cc

10 0 229346

int cc

ponteiro zz

int bb

(17)

• Em C todos os parâmetros de funções são passados por valor

• Assim uma cópia dos valores dos argumentos é

Função

Passagem de argumentos

por Valor

• Assim uma cópia dos valores dos argumentos é dada à função que é chamada e ela cria outras variáveis temporárias para armazenar esses valores

• Em C uma função chamada não pode alterar o valor de uma variável da função que a

(18)

int main(){ int valorX; intvalorY; valorX = 5; valorY = 5;

printf("\nNo main...");

printf("\n\tO Valor de a: %d e o seu endereco e: %d\n", valorX, &valorX); printf("\tO Valor de b: %d e o seu endereco e: %d", valorY, &valorY);

somaDois(valorX,valorY); Isso a gente

somaDois(valorX,valorY);

printf("No main novamente...");

printf("\n\tO Valor de a: %d e o seu endereco e: %d\n", valorX, &valorX); printf("\tO Valor de b: %d e o seu endereco e: %d\n", valorY, &valorY); return(0); } Função: Passagem de argumentos através de Ponteiso

(19)

• Agora vamos passar como parâmetros da função os ponteiros de variáveis do

Função

Passagem de argumentos através de Ponteiros

função os ponteiros de variáveis do

main, desta forma conseguimos alterar o valor de uma variável do main dentro da função que foi chamada.

Hã???

(20)

int main(){ int valorW; valorW = 5;

printf("\nNo main...");

printf("\n\tO Valor de valorW: %d e o seu endereco e: %d\n", valorW, &valorW);

somaTres(&valorW);

printf("No main novamente...");

printf("\n\tO Valor de valorW: %d e o seu endereco e: %d\n", valorW, &valorW); return(0);

} Função: Passagem

Passei o endereço da variável

como parâmetro

Mostra outra ai...!

} Função: Passagem

de argumentos através de ponteiros

Recebe um ponteiro

(21)

int main(){

int valorA = 10; int valorB = 200;

troca(&valorA, &valorB); printf("Valor A = %d\n",valorA); printf("Valor B = %d\n",valorB); return(0); } Função Passagem de argumentos através de Ponteiros Passa o endereço

das variáveis como parâmetros

Na função os parâmetros são declarados como ponteiros: p1 e p2

}

O valor do ponteiro p1

O endereço do ponteiro &p1

O valor variável apontada pelo ponteiro *p1

(22)

int main(){

int valorQ; int valorE;

atualiza(&valorQ, &valorE); printf("Valor Q = %d\n",valorQ); printf("Valor E = %d\n",valorE); return(0); } Função Passagem de argumentos através de Ponteiros Passa o endereço

das variáveis como parâmetros

Na função os parâmetros são declarados como ponteiros: pQ e pE

}

No main eu criei as variáveis, mas não coloquei dados nas vari[aveis, a atualização das variáveis foram

realizadas pela função “atualiza”.

(23)

Para fazer que

pn

aponte para o mesmo lugar que

pm

int hh=100; int *pm, *pn;

pm = &hh; // Pega o endereco de hh e coloca em pm

Atenção para alguns detalhes

muito importantes... 1

pm = &hh; // Pega o endereco de hh e coloca em pm

pn=pm; // Pega o endereco de pm e coloca em pn

Para fazer que o conteúdo apontado por pn tenha o mesmo conteúdo da variável apontada por pm

*pn=*pm; // Pega o valor apontador por pm e coloca pn

100 2293400 2293400

pn

bb pm

100 *pm

(24)

Os ponteiros devem

ser inicializados!!!

Outro detalhe muito

importante... 2

Se não inicializarmos um ponteiro pode fazer com que ele esteja

alocando um espaço de memória utilizado,

main (){

int x int *pt; x =13;

*pt =x; //posição de memória de pt é indefinida!

}

de memória utilizado, por exemplo, pelo

sistema operacional

Vai dar erro!

(25)

main (){

int x int *pt; x =13;

E como eu resolvo isso de inicializar ponteiro?

Inicializando o ponteiro

com algum endereço!

x =13;

pt = &x;

//inicializei pt com o endereço de x

*pt =x; //posição de memória de pt é definida!

(26)

main (){

float salario = 2500; float novoSalario = 0; int *pt;

//inicialize pt com o //endereço de salario

pt = &salario;

Memória RAM

Identificação Endereço da

Memória Conteúdo

Windows 0100100 até

0300100

Sistema operacional Windows

Dev C++ 0300101 até Programa

pt = &salario;

} Dev C++ 0300101 até0400100 Programa Dec C++

salario 2293400 2500

novoSalario 2293412 0

pt 2293424 2293400

(27)

O ponteiro deve ser inicializado, antes de ser usado. int contador=20; Criamos um inteiro “contador”.

int *pt; Declaramos o ponteiro inteiro “pt”

pt=&contador; Endereço do “contador” armazenado em pt

Revisão

Ponteiros

pt=&contador; Endereço do “contador” armazenado em pt

*pt=12. Muda o valor do “contador” para 12.

(28)

Alocação

Estática e

Dinâmica de

Memória

PLT: 706

(29)

Alocação Estática de Memória

Alocação estática de memória ocorre

antes que o programa comece a ser

executado

,

por exemplo:

29

por exemplo:

(30)

Alocação Dinâmica de Memória

• Em determinados sistemas a quantidade de memória que deve ser alocada só se torna conhecida durante a execução do programa, assim é necessário recorrer ao processo de

alocação dinâmica de memória.

30

alocação dinâmica de memória.

• O processo de alocação retorna um endereço físico de memória para o tipo de variável que se pretende guardar. O endereço é guardado num apontador.

(31)

Alocação Dinâmica de Memória

• A alocação dinâmica é gerenciada pelas

funções

malloc e free, que estão na

biblioteca

stdlib

. Para usar esta

biblioteca, é preciso incluir no programa:

31

biblioteca, é preciso incluir no programa:

(32)

Função malloc

• malloc , abreviatura de memory allocation,

aloca um bloco de bytes consecutivos na memória do computador e devolve

o endereço desse bloco em um apontador, por exemplo: Tipo char ocupa 1 byte

32

por exemplo:

char *ponteiro;

ponteiro =

(char*)

malloc

(1);

Aloca 1 byte de memória e

coloca o endereço em um ponteiro

(33)

Função malloc

O retorno de malloc é um ponteiro void*

então temos que converter o ponteiro void* no ponteiro do tipo correto que no exemplo abaixo é o char.

33

abaixo é o char.

char *ponteiro;

ponteiro = (char*)

malloc

(1);

(34)

Operador

sizeof

Em determinados casos podemos não saber a quantidade de bytes devemos alocar,

então utilizamos o operador

sizeof

.

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

int iNumero = 0;

34

int iNumero = 0; char cLetra = 'A';

struct data {int dia,mes,ano;};

printf ("sizeof (int) = %d\n", sizeof(iNumero)); printf ("sizeof (char) = %d\n", sizeof(cLetra)); printf ("sizeof (data) = %d\n", sizeof(data)); return (0);

}

(35)

Função free

• As

variáveis alocadas estaticamente dentro de

uma função desaparecem quando a execução

da função termina

.

• As variáveis alocadas dinamicamente

• As variáveis alocadas dinamicamente

continuam a existir mesmo depois que a

execução da função termina.

(36)

Operador sizeof

#include <stdio.h> #include <stdlib.h>

struct data {int dia,mes,ano;};

int main()

{ data *p;

p =(data*) malloc (sizeof(data));

p.dia=10; p.mes=3; 36 utilizado no malloc p.mes=3; p.ano=2012; printf("Dia:%d\nMes:%d\nAno:%d\n", p.dia, p.mes, p.ano);

free(p);

(37)

Operador sizeof

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

{ int *p;

p = (int*)malloc(sizeof(int));

if (p == null)

“Há memória suficiente disponível para alocar um bloco de memória do tamanho solicitado?“

37

utilizado no malloc

{ printf("ERRO: Sem memória\n"); return 1;

}

*p = 5;

printf("%d\n", *p);

free(p);

(38)

Referências

• Feofiloff, Paulo. Alocação dinâmica de memória; Disponível em:

<http://www.ime.usp.br/~pf/algoritmos/aulas/ aloca.html>. Acesso em: 14/04/2014.

(39)

MUITO OBRIGADO!

[email protected]

Referencias

Documento similar

Sin negar que las Cajas tengan un cierto carácter fundacional o puedan calificarse dogmáticamente de fundaciones a los efectos de encajarlas en una de las figuras jurídicas

Para facilitar el visionado se puede utilizar un proyector o la pizarra digital.. En grupos de cuatro alumnos y alumnas elegir un personaje como favorito, entre todos los

La campaña ha consistido en la revisión del etiquetado e instrucciones de uso de todos los ter- mómetros digitales comunicados, así como de la documentación técnica adicional de

ccLa vigente Ley de Procedimiento administrativo de 17 de julio de 1958, mediante sus artículos 129 a 132, instituye un procedimiento para la elaboración de las disposiciones

16 de octubre de 1981, sobre una carta comunitaria de las lenguas y culturas regionales y sobre una carta de los derechos de las minorías étnicas (14); 11 de febrero de 1983, sobre

Desde 1990 es profesora de Historia del Arte en la Facultad de Bellas Artes de la Universidad Complutense de Madrid; y desde 2004 colabora con el Departamento de Educación del

Debido al riesgo de producir malformaciones congénitas graves, en la Unión Europea se han establecido una serie de requisitos para su prescripción y dispensación con un Plan

Como medida de precaución, puesto que talidomida se encuentra en el semen, todos los pacientes varones deben usar preservativos durante el tratamiento, durante la interrupción