Estrutura de dados 1

Propaganda
Estrutura de dados 1
Ponteiros
S
Ponteiros
S  Um ponteiro é um endereço de memória
S  O valor de um ponteiro indica onde uma variável está
armazenada
S  Um ponteiro proporciona um modo de acesso a uma
variável sem precisar referenciá-la.
Ponteiros
S  Os ponteiros são usados para:
S  Manipular elementos de matrizes;
S  Receber argumentos em funções que necessitem modificar o
argumento original;
S  Passar strings de uma função para outra;
S  Criar estruturas de dados complexas, como listas encadeadas e
árvores binárias, onde um item contém referências a outro;
S  Alocar e desalocar memória do sistema.
Ponteiros
S  Toda variável ocupa uma localização na memória
S  o seu endereço é o endereço do primeiro byte ocupado por ela.
S  O endereço de memória é a referência usada para localizar
as variáveis na memória.
S  Uma variável aponta para outra variável quando a primeira
contém o endereço da segunda.
&x = 0x7fff5a85eb58 x= 4
&y = 0x7fff5a85eb54 y= 7
px = 0x7fff5a85eb58
*px= 4
py = 0x7fff5a85eb54
*py= 7
Operador de endereço &
S  O operador de endereços (&)
S  é um operador unário e
S  seu operando deve ser o nome de uma variável, e
S  o resultado é seu endereço.
Ex:
#include <iostream.h>
using namespace std;
void main()
{
int x, y;
cout << "\n" << &i;
cout << "\n" << &j;
}
&x = 0x7fff5a85eb58 x= 4
&y = 0x7fff5a85eb54 y= 7
Operador de endereço & e o
operador indireto *
S  O operador << imprime & endereços em hexadecimal precedidos
pelo prefixo 0x.
S  O operador indireto (*) é
S  um operador unário
S  Seu operando é um endereço ou ponteiro e
S  resulta no conteúdo da variável localizada no endereço (ponteiro)
do operando.
S  Os ponteiros oferecem uma maneira alternativa de passagem de
parâmetros para uma função.
Ponteiros
&x = 0x7fff5a85eb58 x= 4
&y = 0x7fff5a85eb54 y= 7
#include <iostream.h>
using namespace std;
px = 0x7fff5a85eb58 *px= 4
void main( )
{
py = 0x7fff5a85eb54 *py= 7
int x=4, y=7;
cout << "\n&x = " << &x << "\t x= " << x;
cout << "\n&y = " << &y << "\t y= " << y;
int *px, *py;
px = & x;
py = & y;
cout << "\n\npx = " << px << "\t *px= " << *px;
cout << "\n\npy = " << py << "\t *py= << *py;
}
Ponteiros
S  A instrução “int *px, *py;”
S  declara ponteiros para variáveis int.
S  Quando um ponteiro não é inicializado na instrução de sua
declaração, o compilador inicializa-o com o endereço zero
(NULL) (não válido).
S  Um ponteiro pode ser inicializado no momento de sua
declaração. Ex:
int *px = &x;
Operações com ponteiros
S  As operações com ponteiros só podem ser realizadas entre
ponteiros de mesmo tipo.
S  Incrementar um ponteiro acarreta sua movimentação para o
próximo endereço da memória de uma variável do mesmo tipo.
S  A diferença entre dois ponteiros representa um número de tipo
apontado por eles.
S  Se py tem valor 4000 e px, 3998 a diferença entre eles é 1.
Considerando px e py como inteiros.
Operações com ponteiros
S  Ao declarar um ponteiro, o compilador deve conhecer o tipo de variável
apontada para executar corretamente as operações aritméticas.
S 
S 
S 
int *pi;
double *pd;
float *pf;
S  O tipo declarado é entendido como o tipo de variável apontada.
S  Ao somar 1 a pi, soma-se 4 bytes (1 int)
S  Ao somar 1 a pd, soma-se 8 bytes (1 double)
&i = 0x7fff5a2a9b58 i= 4
&d = 0x7fff5a2a9b50 d= 7
pi = 0x7fff5a2a9b58 *pi= 4
pd = 0x7fff5a2a9b50 *pd= 7
pi + 1 = 0x7fff5a2a9b5c
pd + 1 = 0x7fff5a2a9b58
Passando argumentos por
referências com ponteiros
S  Para usar ponteiros como argumentos há duas etapas:
S  A função chamadora passa endereços usando o operador de
endereços.
S  Estes endereços são de variáveis da função chamadora onde
deseja-se que a função coloque novos valores.
S  A função chamada deve criar variáveis para armazenar os
endereços enviados pela chamadora.
S  Estas variáveis são ponteiros.
Passando argumentos por
referências com ponteiros
#include <iostream>
using namespace std;
void reajusta20(float *p, float *r);
int main( )
{
float preco, reajuste;
do
{
cout << "\n\nInsira o preco atual:\n";
cin >> preco;
reajusta20(&preco, &reajuste);
cout << "\nPreco novo= "<< preco << "\nAumento= " << reajuste;
} while (preco != 0.0);
}
void reajusta20(float *p, float *r)
{
*r= *p * 0.2;
*p *= 1.2;
}
Atenção,
função altera direto variável
preco e reajuste
Ponteiros e Matrizes
S  O compilador transforma matrizes em ponteiros na
compilação.
S  O nome de uma matriz representa seu endereço de memória
que é o endereço do primeiro elemento da matriz
Ponteiros e Matrizes
#include <iostream>
#include <iostream>
using namespace std;
using namespace std;
void main( )
void main( )
{
{
int M[5]={92,81,70,69,58};
int M[5]={92,81,70,69,58};
for (int i=0; i<5; i++)
for (int i=0; i<5; i++)
cout << “\n” << M[i];
cout << “\n” << *(M+i);
}
}
•  M é um ponteiro int e aponta para M[0]
• 
Ao somar 1 a M obtém-se M[1]
• 
M + i é equivalente a &M[i]
• 
*(M+i) é equivalente a M[i]
Passando matrizes como
argumentos para funções
#include <iostream>
using namespace std;
int media (int *lista, int tamanho);
int main( )
{
int notas [20],i;
for (i=0; i<20; i++)
{
cout << "\nDigite a nota do aluno " << (i+1) << ": ";
cin >> *(notas+i);
if (*(notas+i) < 0) break;
}
int m = media (notas, i);
cout << "\n\nMedia das notas: " << m;
}
int media (int *lista, int tamanho)
{
int m=0;
for (int i=0; i < tamanho; i++) m += *lista++;
return (m/tamanho);
}
Alocação de memória
S  A alocação estática de memória ocorre em tempo de compilação,
ou seja, no momento em que se define uma variável ou estrutura
S  é necessário definir seu tipo e tamanho.
S  A alocação dinâmica de memória ocorre em tempo de execução,
no momento em que a variável ou estrutura precisar ser utilizada,
S  sua memória será reservada e será liberada se a memória não for
mais necessária.
S  Em C e C++ é possível criar matrizes e vetores dinâmicos através
de ponteiros.
Área de alocação dinâmica:
heap
S 
A área de alocação dinâmica (heap)
S 
toda a memória que ainda não está alocada.
S 
Em C++ há dois operadores para a alocação ou liberação da memória dinâmica: new e delete.
S 
Pode-se solicitar memória sempre que necessário.
S 
A operador new obtém memória do sistema operacional e retorna um ponteiro para o primeiro byte do bloco de memória alocado.
S 
S 
S 
S 
sintaxe: new tipo;
sintaxe: new tipo [numero_de_elementos];
Quando alocamos memória dinamicamente é recomendado que ao término da execução do programa essa memória seja liberada.
Para isto existe o operador delete.
S 
Sintaxe: delete ponteiro;
S 
Sintaxe: delete [ ] ponteiro;
Uma vez alocada, a memória só é liberada pela função free().
Área de alocação dinâmica
#include <iostream>
#include <new>
using namespace std;
int main ()
{
int i,n;
int * p;
cout << "Quantos numeros voce quer? ";
cin >> i;
p= new (nothrow) int[i];
if (p == nullptr)
cout << "** Erro: Memoria Insuficiente ";
else
{
for (n=0; n<i; n++)
{
cout << "Entre um numero: ";
cin >> p[n];
}
cout << "Voce digitou: ";
for (n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
}
return 0;
}
Área de alocação dinâmica:
heap
S  Em C há duas funções para a alocação ou liberação da memória
dinâmica: malloc() e free().
S  Pode-se solicitar memória sempre que necessário.
S  O operador new obtém memória do sistema operacional e retorna
um ponteiro para o primeiro byte do bloco de memória alocado.
S  Uma vez alocada, a memória só é liberada pelo operador delete.
Download