Buscar

Ponteiros_Apostila

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Universidade Federal de Itajubá
BAC004 - Informática
Profa. Claudia Akemi Izeki
Prof. Walter Aoiama Nagai
Tópico Complementar: Ponteiros
1. Definição, Declaração e Operadores
Um ponteiro é uma variável cujo valor é um endereço de memória. Na Figura 1, xPtr é um ponteiro para
um valor do tipo float.
 
Figura 1. xPtr referencia indiretamente a variável x cujo valor é 10.0
 
O valor do ponteiro xPtré o endereço da variável xque, por sua vez, contém o valor 10.0. Assim, o nome 
de variável x referencia diretamente um valor, sendo que o ponteiro xPtr referencia indiretamente um 
valor. 
 
No exemplo da Figura 2 é apresentado um programa que declara um ponteiro de nome xPtre utiliza os 
seguintes operadores:
● & - operador de endereço: obtém o endereço na memória de uma variável;
● * - operador de indireção, também chamado de derreferência: obtém o valor da variável apontada.
 
Na linha 4 é declarada uma variável chamada xPtrcomo sendo do tipo float*,ou seja, um ponteiro para   
um valor do tipo float. Lê-se "xPtré um ponteiro para float" ou "xPtraponta para uma varíavel do tipo 
float".
 
1 int main()
2 {
3    float x;     // x é uma variável do tipo float
4    float *xPtr; // xPtr é um ponteiro para um float
5 
6    x = 10.0;
7    xPtr = &x;   // xPtr recebe o endereço de x
8 
9    cout << "O valor de x é: " << x << endl;
10   cout << "O endereço de x é: " << &x << endl;
11   cout << "O valor de xPtr é: " << xPtr << " que é o mesmo endereço de x" << endl;
12    cout << "O valor de *Ptr é " << *xPtr << " que é o mesmo valor de x" << endl;
13    cout << "O endereço de xPtr é: " << &xPtr;
14    return 0;
15}
Figura 2. Primeiro exemplo com ponteiros e operadores de endereço e de indireção.
 
1
Na Figura 3 são apresentadas as impressões na tela do código da Figura 2.
O valor de x é: 10.0
O endereço de x é: 0x22ff0c
O valor de xPtr é: 0x22ff0c que é o mesmo endereço de x
O valor de *Ptr é: 10.0 que é o mesmo valor de x
O endereço de xPtr é: 0x22ff08
Figura 3. Saída do programa da Figura 2.
2. Inicialização de variáveis ponteiros 
Existem 3 formas de inicializar um ponteiro:
● Com o valor 0 ou a constante NULL: não aponta para nada. Em C++ é preferível usar a constante 0.
Exemplos:
int *x = 0;
int *y = NULL;
● Com algum endereço de memória de uma variável já existente. Exemplo:
int a = 10;
int *x = &a;
● Com a atribuição de um endereço de memória retornado pelo comando new() de alocação dinâmica
de memória. Exemplo:
int *y = new int(); // Este comando será explicado posteriormente
3. Argumentos ponteiros na passagem de parâmetro por referência
Ponteiros na chamada por referência podem ser usados para modificar uma ou mais variáveis da função 
chamadora, ou para evitar sobrecarga através da passagem por valor de dados grandes.
 
Quando se chama uma função com parâmetros que devem ser modificados, os endereços dos parâmetros 
devem ser passados. Existem duas fomas de passar os endereços dos parâmetros:
● empregando-se o operador de endereços & ao nome da variável cujo valor será modificado; ou
● escrevendo-se o nome do próprio vetor ou matriz, pois seu nome é sua posição inicial na memória.
 
Na Figura 4 é apresentada a execução passo a passo de uma chamada à função que troca dois valores 
utilizando ponteiros.
 Antes da chamada à função troca()... 
 
2
 Função troca() sendo chamada...
 
 Após realizar a troca de valores...
Figura 4. Passo a passo de uma chamada por referência típica usando ponteiro como parâmetro.
 4. Aritmética de ponteiros
Com a finalidade de apresentar aritmética de ponteiros, é apresentado o exemplo da Figura 6, no qual o 
ponteiro vPtr aponta para o vetor v (ilustração na Figura 5). 
 
 Figura 5. Um vetor v e uma variável ponteiro vPtr apontando para v. 
 
1 int main()
2 {
3    int v[]={10, 20, 30, 40, 50};  // v é um vetor de inteiros
4    int *vPtr; // vPtr é um ponteiro para inteiro
5 
6    vPtr = &v[0]; // ou vPtr = v, pois o nome do vetor é o endereço do primeiro
elemento
7    cout << "O valor de *vPtr é o mesmo que v[0], que é: " << *vPtr << "\n\n";
8    cout << "Operação vPtr++..." << endl;
9    vPtr++; // incrementa o ponteiro de 1 unidade (tamanho de um inteiro)
10   cout << "O valor de *vPtr é o mesmo que v[1], que é: " << *vPtr << "\n\n";
3
11   cout << "Operação vPtr = vPtr + 2..." << endl;
12   vPtr = vPtr + 2; // incrementa o ponteiro de 2 unidades (tamanho de 2 inteiros)
13   cout << "O valor de *vPtr é o mesmo que v[3], que é: " << *vPtr << "\n\n";
14   cout << "Operação vPtr­­" << endl;
15   vPtr­­; // decrementa em uma unidade o valor do ponteiro (tamanho de um inteiro)
16   cout << "O valor de *vPtr é o mesmo que v[2], que é: " << *vPtr << "\n\n"; 
17   
18   int *v2Ptr = &v[3];
19   int q;
20   q = v2Ptr ­ vPtr;
21   cout << "Subtração entre dois ponteiros: v2Ptr ­ vPtr = " << q;
22   return 0;
23 }
Figura 6. Um programa com várias operações aritméticas de ponteiros.
 
A saída do programa é apresentada na Figura 7. Inicialmente, vPtrestá com o valor 2000 (endereço do 
primeiro elemento do vetor). Note que a instrução vPtr++resulta em 2004 e não em 2001, já que somar 
uma unidade de um ponteiro significa somar uma unidade do tipo ao qual ele aponta (um inteiro, no caso, 
possui 4 bytes). Sendo o endereço 2004 o do segundo elemento do vetor, então v[1] corresponde ao valor 
20. A instrução da linha 20 (subtração entre dois ponteiros) segue o mesmo raciocínio, no qual v2Ptr 
possui o endereço do quarto elemento, no caso 2012 e vPtr o do terceiro elemento, a subtração 
v2Ptr­vPtr resulta em 1 e não em 4 (2012-2008).
 
O valor de *vPtr é o mesmo que v[0], que é: 10
 
Operação vPtr++...
O valor de *vPtr é o mesmo que v[1], que é: 20
 
Operação vPtr = vPtr + 2...
O valor de *vPtr é o mesmo que v[3], que é: 40
 
Operação vPtr­­
O valor de *vPtr é o mesmo que v[2], que é: 30
 
Subtração entre dois ponteiros: v2Ptr ­ vPtr = 1
Figura 7. Saída do programa da Figura 6.
 
5. Relação entre ponteiros e vetores (arrays)
Ponteiros e vetores estão intimamente relacionados: o nome de um vetor é um ponteiro constante ; e os 1
ponteiros podem ser usados para fazer qualquer operação envolvendo indexação de vetores. 
No exemplo da Figura 8 são apresentados quatro tipos de notação de acesso aos elementos de um vetor:
1. Uso de subscritos com array;
2. Ponteiro/deslocamento com o nome do array como ponteiro;
3. Uso de subscritos com ponteiros;
4. Ponteiro/deslocamento com um ponteiro;
Seja vPtr o mesmo ponteiro dos exemplos das Figuras 5 e 6:
int v[]={10, 20, 30, 40, 50};
1Um ponteiro constante é aquele cujo valor não pode ser modificado. 
4
int *vPtr = v;
Verifique na Tabela 1 um exemplo de como referenciar o quarto elemento de um array com os 4 tipos de 
notação descritos acima.
1 - Uso de subscritos com array v[3]
2 - Ponteiro/deslocamento com o nome do
array como ponteiro
*(v+3)
3 - Uso de subscritos com ponteiros vPtr[3]
4 - Ponteiro/deslocamento com um ponteiro *(vPtr+3)
Note que a expressão v = v+3é incorreta porque vé um ponteiro constante, seu valor não deverá ser     
modificado, sempre deverá apontar para o primeiro elemento do array.
6. Arrays de ponteiros
Arrays de ponteiros são arrays cujos elementos são ponteiros. Um uso muito comum de arrays de ponteiros 
são os arrays de strings.
No programa da Figura 8 é apresentado um array de strings que armazena os dias da semana. Na 
declaração da variável diaSemana, a parte diaSemana[7]indica que é um vetor de 7 elementos. A partechar * indica que cada elemento do vetor é do tipo "ponteiro para caracter".
1 int main()
2 {
3    char *diaSemana[7] = {"Domingo", "Segunda­feira", "Terca­feira",
4                   "Quarta­feira", "Quinta­feira", "Sexta­feira",
5                                   "Sabado"}
6 int i;
7
8 for(i=0; i<7; i++)
9    cout << diaSemana[i] << endl;
10   
11   return 0;
12 }
Figura 8. Um programa com várias operações aritméticas de ponteiros.
Figura 9. Representação gráfica do array diaSemana.
7. Operadores new e delete
O comando newé utilizado para obter memória do sistema operacional em tempo de execução. Ele retorna 
um ponteiro para o início do novo bloco de memória que foi alocado. Uma vez alocada, esta memória 
continua ocupada até que seja desalocada explicitamente pelo operador delete.
5
Exemplo 1: alocando memória para um inteiro
int main()
{
int *intPtr;
intPtr = new int(); // aloca memória para 1 inteiro e retorna o
                    // endereço inicial da memória alocada
*intPtr = 10;
cout << *intPtr;
delete intPtr; // liberando a memória alocada
return 0;
}
 
Figura 10. Esquema correpondente ao Exemplo1
 
Exemplo 2: alocando memória para um vetor de inteiros de n posições
int main()
{
int *arrayPtr, i, n;
cin >> n;
arrayPtr = new int[n];
for(i=0; i<n; i++)
cin >> arrayPtr[i];
delete []  arrayPtr;
return 0;
}
 
Figura 11. Esquema correpondente ao Exemplo2
6
Exemplo 3: alocando memória para um vetor de caracteres 
#include <iostream>
#include <cctype> // islower() e toupper()
#include <cstring> // strlen()
#include <cstdio> // gets()
using namespace std;
int main()
{
char *stringPtr, str[40];
int i;
gets(str);
stringPtr = new char[strlen(str)+1];
for(i=0; i<strlen(str); i++)
{
    if(islower(str[i]))
        stringPtr[i] = toupper(str[i]);
    else
        stringPtr[i] = str[i];
}
stringPtr[i] = '\0';
cout << "String: " << stringPtr;
delete []  stringPtr;
return 0;
}
Exemplo 4: alocando memória para um registro simples (tipo Aluno)
#include<iostream>
#include<cstdio>
using namespace std;
struct Aluno {
   int matricula;
   char nome[40];
};
int main()
{
   Aluno *student = new Aluno();
   cout << "Matricula: "; cin >> (*student).matricula; cin.ignore();
   cout << "Nome.....: "; gets((*student).nome);
7
   cout << "Matricula digitada: " << student­>matricula << endl;
   cout << "Nome digitado.....: " << student­>nome << endl;
   delete student;
   return 0;
}
 
Figura 12. Esquema correpondente ao Exemplo4
Exemplo 5: alocando memória para um registro simples (tipo Aluno) com funções
#include<cstdio>
#include<iostream>
using namespace std;
struct Aluno {
   int matricula;
   char nome[40];
};
void leia_aluno (Aluno *a) {
   cout << "Matricula: "; cin >> a­>matricula; cin.ignore();
   cout << "Nome.....: "; gets(a­>nome);
}
void imprime_aluno (Aluno *a) {
   cout << "Matricula digitada: " << a­>matricula << endl;
   cout << "Nome digitado.....: " << a­>nome << endl;
}
int main()
{
   Aluno *student = new Aluno();
   leia_aluno (student);
   imprime_aluno (student);
   delete student;
   return 0;
}
8
Exemplo 6: alocando memória para um vetor de registro (tipo Aluno) 
#include<iostream>
using namespace std;
const int MAX = 5;
struct Aluno {
   int matricula;
   char nome[40];
};
int main()
{
 Aluno *students = new Aluno[MAX];
   for (int i = 0; i < MAX; i++)
   {
   cout << "Matricula: "; cin >> students[i].matricula; cin.ignore();
   cout << "Nome.....: "; cin.getline (students[i].nome, 40);
   }
   for (int i = 0; i < MAX; i++)
   {
   cout << "\nMatricula digitada: " << students[i].matricula << endl;
   cout << "Nome digitado.....: " << students[i].nome << endl;
   }
   delete [] students;
   return 0;
}
 Figura 13. Esquema correpondente ao Exemplo6
Exemplo 7: alocando memória para um vetor de registro (tipo Aluno) com funções - versão 1
#include<iostream>
using namespace std;
const int MAX = 5;
9
struct Aluno {
   int matricula;
   char nome[40];
};
void leia_aluno (Aluno *a) {
   cout << "Matricula: "; cin >> a­>matricula; cin.ignore();
   cout << "Nome.....: "; cin.getline (a­>nome, 40);
   cout << endl;
}
void imprime_aluno (Aluno a) {
   cout << "\nMatricula digitada: " << a.matricula << endl;
   cout << "Nome digitado.....: " << a.nome << endl;
}
int main()
{
   Aluno *students = new Aluno[MAX];
   for (int i = 0; i < MAX; i++)
   leia_aluno(&students[i]);
   for (int i = 0; i < MAX; i++)
    imprime_aluno(students[i]);
   delete [] students;
   return 0;
}
Exemplo 8: alocando memória para um vetor de registro (tipo Aluno) com funções - versão 2
#include<iostream>
using namespace std;
const int MAX = 5;
struct Aluno {
   int matricula;
   char nome[40];
};
10
void leia_alunos (Aluno *alunos) {
   for(int i=0; i<MAX; i++)
   {
    cout << "Matricula: "; cin >> alunos[i].matricula; cin.ignore();
    cout << "Nome.....: "; cin.getline (alunos[i].nome, 40);
    cout << endl;
   }
}
void imprime_alunos (Aluno *alunos) {
   for(int i=0; i<MAX; i++)
   {
    cout << "\nMatricula digitada: " << alunos[i].matricula << endl;
    cout << "Nome digitado.....: " << alunos[i].nome << endl;
   }
}
int main()
{
   Aluno *students = new Aluno[MAX];
   leia_alunos(students);
   imprime_alunos(students);
   delete [] students;
   return 0;
}
Exemplo 9: alocando memória para um vetor de registro (tipo Aluno) com funções - versão 3
#include<iostream>
using namespace std;
const int MAX = 5;
struct Aluno {
   int matricula;
   char nome[40];
};
 
11
void aloca_leAlunos(Aluno **alunos){ 
   *alunos = new Aluno[MAX];
   for(int i=0; i<MAX; i++)
   {
    cout << "Matricula: "; cin >> (*alunos)[i].matricula; cin.ignore();
    cout << "Nome.....: "; cin.getline ((*alunos)[i].nome, 40);
    cout << endl;
   }
}
 
void imprime_alunos (Aluno *a) {
   for(int i=0; i<MAX; i++)
   {
    cout << "\nMatricula digitada: " << a[i].matricula << endl;
    cout << "Nome digitado.....: " << a[i].nome << endl;
   }
}
int main()
{
   Aluno *students;
   aloca_leAlunos(&students);
   imprime_alunos(students);
   delete [] students;
   return 0;
}
 
Figura 14. Esquema correpondente ao Exemplo9
12

Outros materiais